2025년 8월 24일 일요일

[2025-08-24] vscode로 프로젝트 초기 설정 가이드

vscode로 프로젝트 초기 설정 가이드

안녕하세요. 클스 입니다.

우리가 서비스를 개발할때, front-end, back-end, batch 등 여러 하위 시스템들로 구성하는 경우가 많습니다.
이때 project 폴더를 만들고 하위에 폴더를 구성합니다.

full-stack을 혼자 다해야 하는 개발자는 vscode를 3개를 실행해서 편집하는 경우가 대부분입니다.

테미널도 3개를 띄워서 쓰는 경우가 있습니다. 이를 간단하게 해결하는 방법입니다.


1. 개요

솔루션, 서비스를 개발할때 project folder를 생성하고, 하위에 여러 기능들을 추가한다.
api, batch, user web, admin web, monitoring web...

이때 vscode의 workspace를 열면 자동으로 터미널까지 셋팅하게 할 수 있다.

2. 환경 설정(workspace)

  • project folder 생성
    $ mkdir myproject
    $ cd myproject
    $ mkdir .vscode
    $ code .
    
  • .vscode 폴더에서 tasks.json 작성
    {
      "version": "1.0.0",
      "tasks": [
        {
          "label": "admin-web",
          "type": "shell",
          "command": "${env:SHELL}",                   // macOS/Linux
          "windows": { "command": "powershell.exe" },  // Windows
          "options": {
            "cwd": "${workspaceFolder}/nginx-proxy" 
          },
          "presentation": {
            "panel": "dedicated",
            "group": "MyService",          //     group  
            "reveal": "always",
            "showReuseMessage": false
          },
          "problemMatcher": [],
          "runOptions": { "runOn": "folderOpen" }
        },
        {
          "label": "web-user",
          "type": "shell",
          "command": "${env:SHELL}",
          "windows": { "command": "powershell.exe" },
          "options": {
            "cwd": "${workspaceFolder}/web-user/trunk" 
          },
          "presentation": {
            "panel": "dedicated",
            "group": "MyService",
            "reveal": "always",
            "showReuseMessage": false
          },
          "problemMatcher": [],
          "runOptions": { "runOn": "folderOpen" }
        },
        {
          "label": "user-web-api",
          "type": "shell",
          "command": "${env:SHELL}",
          "windows": { "command": "powershell.exe" },
          "options": {
            "cwd": "${workspaceFolder}/web-user-api/trunk" 
          },
          "presentation": {
            "panel": "dedicated",
            "group": "MyService",
            "reveal": "always",
            "showReuseMessage": false
          },
          "problemMatcher": [],
          "runOptions": { "runOn": "folderOpen" }
        }
      ]
    }
    
  • 하위 프로젝트 폴더를 생성하고 workspace로 저장한다.
    {
      "folders": [
        {
          "path": ".",
          "name": "MyService",
          "editor.tabSize": 2,
        }
      ],
      "settings": {
        "files.exclude": {
          "**/.git": true,
          "**/.venv": true,
          "**/.nvmrc": true,
          "**/.quasar": true,
          "**/.files": true,
          "**/node_modules": true,
          "**/.DS_Store": true,
          "**/__pycache__": true
        }
      }
    }
    
  • tasks.json 파일 변경시 적용
1. 편집기 재실행 (간단하지만 확실한 방법)
   창 전체 Reload : 단축키: Ctrl+Shift+P → “Developer: Reload Window” 실행
   VS Code 창이 재시작되며 모든 설정(tasks.json 포함)이 새로 로드됩니다.

2. 워크스페이스 재열기
   메뉴: File > Close Folder 한 뒤 다시 Open Folder
   폴더 열기 시 runOn: "folderOpen" 옵션이 있는 태스크가 자동으로 실행됩니다.
  • svn ignore 설정하기
    # .svnignore 파일 생성
    .git
    .venv
    .nvmrc
    .quasar
    .files
    node_modules
    .DS_Store
    __pycache__
    
  • 커밋하기
    # 1) .svnignore 파일을 svn:ignore 속성으로 설정
    svn propset svn:ignore -F .svnignore .
    
    # 2) 변경 사항 커밋
    svn commit -m "Add svn:ignore based on VSCode files.exclude" 
  • code로 workspace 열기
    • workspace를 프로젝트 폴더에 생성했다면 myservice.code-workspace 파일이 있다.
    • $ code myservice.code-workspace 로 열면 필요한 Terminal이 한번에 열리게 된다.

3. 친절한 README.md 파일

  • project 폴더에 README.md : 개발자가 빠르게 개발, 빌드환경을 설정할 수 있도록 상세하게 적는다.
    하위 여러개의 프로젝트가 있으므로 전체를 기술한다. 그리고 각 프로젝트 폴더별 README.md를 생성하고 자세하게 필요한 내용을 가이드 한다. 전체 실행 방법, 테스트 계정등을 포함하면 좋다.
  • 신입 팀원이 들어와도 개발 환경 구축 부터 빠르게 할 수 있게 된다.
# web-user

## quasar 초기 설정
```bash
pnpm setup --global ===> .zshrc에 pnpm path 를 추가
pnpm add -g @quasar/cli
pnpm add -D vite@^6.0.0 => 프로젝트는 이 버전을 쓰네
```

## 모듈 설치
```bash
pnpm install --frozen-lockfile
```

## 로컬 구동
```bash
./start.sh
# or
nvm use
pnpm start:local-pwa
```

## 빌드
```bash
# 개발
pnpm build:dev-pwa

# 운영
pnpm build:prd-pwa
```

## Tips
```bash
# config 임시파일 삭제
pnpm quasar clean --qconf
```

라벨: , , , ,

2025년 7월 28일 월요일

[2025-07-28] python 에서 html to pdf 변환 비교

[2025-07-28] python 에서 html to pdf 변환 비교

안녕하세요. 클스 입니다.


html로 작성된 문서를 RAG를 하기위해서 html을 그대로 사용해도 되지만, 불필요한 테그가 있어 비효율 적입니다. 그렇다고 테그를 제거하면 표 등 레이아웃이 깨지게 됩니다.

일반적으로  pdf가 많이 사용됩니다. 그래서 macos에서 많이 사용하는 2개의 라이브러리를 비교해보고자 합니다.

1. html 을 바로 변환하는 방법 : weasyprint    [장점] 가볍다.

2. html 을 브라우저로 열어서 변환하는 방법 : playwright  
   [장점] 풍부하게 css를 처리한다.

코드

###### html to pdf #########
'''
외부망에서 해야 함
brew install pango
uv pip install weasyprint
'''
from weasyprint import HTML

html_file = '~/doc/test.html'
# 1. 문자열 경로를 Path 객체로 만듭니다.
path_obj = Path(html_file)
# 2. .with_suffix() 메서드로 확장자를 변경합니다.
pdf_file = path_obj.with_suffix('.pdf')
HTML(filename=html_file).write_pdf(pdf_file)


'''
외부망에서 해야함.
# 1. Playwright 라이브러리 설치
uv pip install playwright

# 2. Playwright가 제어할 브라우저(Chromium 등) 설치 (라이브러리 엄청 크네)
python -m playwright install
'''


import asyncio
from pathlib import Path
from playwright.async_api import async_playwright

async def convert_local_html_to_pdf_async(html_file_path: str, output_pdf_path: str):
"""
(비동기) 로컬 HTML 파일을 Playwright를 사용하여 PDF 파일로 변환합니다.
IPython/Jupyter 환경에 최적화되었습니다.

:param html_file_path: 변환할 원본 HTML 파일의 전체 경로
:param output_pdf_path: 저장할 PDF 파일의 전체 경로
"""
# pathlib.Path를 사용하여 파일 경로를 브라우저가 인식하는 file:// URI 형식으로 변환합니다.
# 이렇게 하면 공백이나 한글 등 특수문자가 포함된 경로도 안전하게 처리됩니다.
html_file_uri = Path(html_file_path).as_uri()
print("Playwright를 시작합니다...")
# 'async with'를 사용하여 비동기 컨텍스트 매니저를 실행합니다.
async with async_playwright() as p:
# 모든 I/O 작업(네트워크, 파일 시스템 등) 앞에 'await' 키워드를 붙여줍니다.
browser = await p.chromium.launch()
page = await browser.new_page()
try:
print(f"HTML 파일 로딩 중: {html_file_uri}")
# 페이지로 이동하고 로딩이 끝날 때까지 기다립니다.
await page.goto(html_file_uri)

print(f"PDF 파일 생성 중: {output_pdf_path}")
# PDF 생성이 완료될 때까지 기다립니다.
await page.pdf(
path=output_pdf_path,
print_background=True, # 배경 그래픽(색상, 이미지 등) 인쇄
format='A4' # 용지 형식 지정
)
print(f"✅ 성공: '{output_pdf_path}' 파일이 생성되었습니다.")

except Exception as e:
print(f"❌ 오류 발생: {e}")
finally:
print("브라우저를 닫습니다.")
# 브라우저 종료가 완료될 때까지 기다립니다.
await browser.close()

async def main():
"""
비동기 작업을 실행하기 위한 메인 함수
"""
# 1. 변환할 원본 HTML 파일 경로를 설정하세요.
'~/doc/test.html'

# 2. 저장할 PDF 파일 이름을 자동으로 설정합니다 (확장자만 .pdf로 변경).
output_file = Path(html_file).with_suffix('.pdf')

# 3. 위에서 정의한 비동기 변환 함수를 호출합니다.
await convert_local_html_to_pdf_async(html_file, str(output_file))


# IPython/Jupyter 환경에서는 'await'를 직접 사용하여 비동기 함수를 실행할 수 있습니다.
await main()


결론

둘다 레이아웃의 깨짐 없이 잘 변환해준다. 내가 선택하려면 자동화를 위해서 1번을 선택하는것이 맞다.

또 하나는 결과 파일의 크기 이다.

1) 51KB

2) 520KB


이상 클스 였습니다.


라벨: , , , ,

2024년 9월 21일 토요일

[2024-09-21] MacOS Sequoia 15.0 업그레이드

[2024-09-21] MacOS Sequoia 15.0 업그레이드

맥이 세콰이어(Sequoia)를 발표했다. 1984년 System 1을 출시한 후 40주년 버전이라 의미가 깊을듯 합니다.

내 사양은 인텔맥입니다. 2019년에 생산된 모델이에요

애플 홈에 가보면 아래와 같이 소개 되어 있습니다.

macOS Sequoia는 매끄러운 윈도우 타일과 더욱 집중하기 좋은 웹 브라우징, 새로운 iPhone
미러링 기능과 더불어 Apple Intelligence에 대한 지원까지 선사합니다.

이름은 미국 캘리포니아주 시에라네바다 산맥의 서쪽 사면에 위치한 세쿼이아 국립공원에서 따왔다. 지구상에서 부피 기준으로 가장 큰 나무인 거삼나무 제너럴 셔먼 트리가 있는 곳으로 유명한 곳이라고 하네요

버전 번호
15
코드명
Glow
정식 출시일
2024년 9월 17일
정식 최신 버전
15.0 (24A335)
최신 베타 버전
15.1 Developer Beta 2 (24B5024e)
15.0 Developer Beta 7 (24A5327a)
아키텍처
지원 여부
현재 지원 중
[출처:나무위키]

다운로드 및 설치에 약 30분 정도 걸린것 같고, 해두고 무리없이 설치하면 됩니다.
그리고 sdk 도 한번 업데이트 하라고 나오길래. 해두고 밥먹고 오니 다 되긴했습니다.

뭔가 모서리가 더 둥글어진 기분이다. 기분  탓인가? 설정에서 윈도우의 라운딩 옵션이 있으면 좋겠습니다.


아직 특별한 문제는 없다. 개발툴 설치 잘되고 있습니다.
vscode, dbevear, docker
brew upgrade 해줬습니다.

MacOS Sequoia (15) 업데이트 후 내부망 접속이 안될 때 (회사 분리망 사용시, 보안장비 있을때)
  • 설정 > Wi-FI
  • 알고 있는 네트워크의 CNCITY5G 우측 점3개 선택  > 네트워크 설정... 선택
  • 비공개 Wi-FI 주소 : 고정 => 끔 (끄지 않을 경우 Wi-Fi Mac주소가 접속시마다 변경이 됨)
  • 사내 방화벽에서 등록된 Wi-Fi Mac 주소만 허용이 되어서 Mac주소가 변경이 되지 않도록 설정 해야 함

자세한 내용 보기 »

라벨: , , , ,

2023년 10월 14일 토요일

[2023-10-13] mac intel, M1, M2에 tensorflow GPU 사용하도록 설치

[2023-10-13] mac intel, M1, M2에 tensorflow GPU 사용하도록 설치 (feat. 셔틀콕 D3)


안녕하세요. 클스 입니다.

2023년 10월 초에 구글에서 tensorflow 2.14 버전을 출시했습니다.

apple mac intel 칩이 장착된 2020년 이전 생산된 맥북들이 많습니다.
저도 2019년 맥 프로를 사용하고 있습니다.
워낙 nvidia가 cuda를 기반으로 머신러닝을 잘하는데, 안타깝게도 맥은 radeon 을 사용합니다.
2012년까지는 애플도 nvidia를 사용했다가, 발열로 인한 리콜을 한다음 radeon으로 변경한듯 싶습니다.

그 후로 머신러닝이 중요해지면서 GPU를 사용해야 하는 장비에는 nvidia 를 필수로 장착합니다.

아쉽게도 맥은 사용이 불가했었고, 일부 사람들이 맥에 장착된 radeon의 gpu를 사용할 수 있게 하려고
노력했습니다.

그 결과 지금은 metal 플러그인을 통해 지원이 가능해졌습니다.

그런데 버전 호환에 조합이 잘 필요하더군요~

그리고 nvidia의 독주를 막기위해 여러 회사의 gpu에서 동일하게 코딩이 가능하도록 언어를 개발하는
회사도 있습니다. 언어는 mojo 라고 합니다. 아래 유투브 링크 걸어 두었어요~

환경

- mac intel, mac m1, m2
- python 3.11.5 

호환성


1. Intel MacOS 에 tensorflow gpu 사용하기


   - tensorflow 2.12 버전만 tensorflow-macos가 지원한다.

   $ pip install tensorflow-macos 
     tensorflow 2.12 버전이 설치된다.
   $ pip install tensorflow-metal  

(py311) [~/projects/tf]$ pip install tensorflow-metal
Collecting tensorflow-metal
  Obtaining dependency information for tensorflow-metal from https://files.pythonhosted.org/packages/52/56/8373f5751011304a346f07e5423e69f809b626989d2541ae9e816ae7ced2/tensorflow_metal-1.1.0-cp311-cp311-macosx_12_0_arm64.whl.metadata
  Downloading tensorflow_metal-1.1.0-cp311-cp311-macosx_12_0_arm64.whl.metadata (1.2 kB)
Requirement already satisfied: wheel~=0.35 in /Users/keulstar/.pyenv/versions/3.11.5/envs/py311/lib/python3.11/site-packages (from tensorflow-metal) (0.41.2)
Requirement already satisfied: six>=1.15.0 in /Users/keulstar/.pyenv/versions/3.11.5/envs/py311/lib/python3.11/site-packages (from tensorflow-metal) (1.16.0)
Downloading tensorflow_metal-1.1.0-cp311-cp311-macosx_12_0_arm64.whl (1.4 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 18.3 MB/s eta 0:00:00
Installing collected packages: tensorflow-metal
Successfully installed tensorflow-metal-1.1.0

   $ pip freeze | grep tensorflow
   
      tensorflow==2.12.0
      tensorflow-estimator==2.12.0
      tensorflow-io-gcs-filesystem==0.34.0
      tensorflow-macos==2.12.0
      tensorflow-metal==1.1.0

2. M1,M2 MacOs에 tensorflow gpu 사용하기

  
   - tensorflow 2.12 이후 버전에서 tensorflow-macos가 지원한다.
      tensorflow 2.14 버전이 기본으로 된다. intel 에서는 tensorflow-macos==2.14.0 을 설치하면
      지원하지 않는다고 설치가 안된다.

   $ pip freeze | grep tensorflow
      tensorflow==2.14.0
      tensorflow-estimator==2.14.0
      tensorflow-io-gcs-filesystem==0.34.0
      tensorflow-macos==2.14.0
      tensorflow-metal==1.1.0


소스 및 실행 결과

tf1.py 소스를 작성한다.

import tensorflow as tf

cifar = tf.keras.datasets.cifar100
(x_train, y_train), (x_test, y_test) = cifar.load_data()
model = tf.keras.applications.ResNet50(
include_top=True,
weights=None,
input_shape=(32, 32, 3),
classes=100,)

loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False)
model.compile(optimizer="adam", loss=loss_fn, metrics=["accuracy"])
model.fit(x_train, y_train, epochs=5, batch_size=64)


$ python tf1.py

리소스 모니터로 GPU 사용률을 확인한다. 처음에는 CPU가 많이 사용되다가, 데이터 로딩을 마치고
학습에 들어가면 GPU를 사용한다. 대략 CPU를 사용하는 것보다는 최소 20배 빠른듯 하다






참고로 제 경우는 맥 스투디오 울트라 최고 사양에서 3090과 비슷하다고는 하는데,
실제 돌려보니 80% 정도 성능 처럼 보입니다.

이만 클스 였습니다.




셔틀콕 추천드려요. 대한민국 배드민턴 동호회 공식 셔틀콕 입니다.

배드민턴 셔틀콕 에이스 D3 콕 ACE 1박스 25타 300개입 거위 깃털 2단 코르크 동호인용 경기용 대회용 배드민턴공 공인구 배린이 방과후, 1개  

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다


즐턴 하세요~

감사합니다.

라벨: , , , , , , , ,

2023년 8월 8일 화요일

[FastAPI] uvicorn, hypercorn에서 worker 여러개 띄우기 (feat. 배드민턴 셔틀콕 추천)

안녕하세요. 클스 입니다.

오늘은 FastAPI에 여러개 worker를 실행하는 것을 해보려고 합니다.

많은 요청을 처리하기 위해서 worker를 해주면 좋습니다.

worker의 계산은  2 x number_of_cores +1 이 적절하다고 합니다.


좀더 정확하게 산출해보려면 아래와 같이 계산하면 됩니다.

number_of_workers = number_of_cores x num_of_threads_per_core + 1
MacOS의 터미널에서 
$ sysctl -n hw.packages   ==> MacOS에 장착된 cpu socket 수
$ sysctl hw.physicalcpu hw.logicalcpu ==> cpu의 core 수, 총 thread 수
   num_of_threads_per_core(core당 thread 수) = hw.logicalcpu / hw.physicalcpu

$ sysctl -n hw.ncpu  혹은  ==> core 수
$ sysctl -n machdep.cpu.thread_count ==> core 수

uvicorn과 hypercorn으로 실행하는데 --reload 옵션이 있으면 --workers는 무시되고 1개만 뜹니다.

그리고 reload process가 1개 실행 됩니다.


참고로 FastAPI 공식 문서에서는 worker를 띄울때는 uvicorn 보다는 gunicorn을 사용하는게 좋다고 합니다.

그래서 저는 hypercorn을 많이 사용합니다.


# uvicorn

```sh
$ APP_ENV=dev uvicorn app:app --host "0.0.0.0" --port "8001" --reload
$ APP_ENV=dev uvicorn app:app --host "0.0.0.0" --port "8001" --workers 4
```

# hypercorn

```sh
$ APP_ENV=dev hypercorn app:app --bind 0.0.0.0:8001 --reload
$ APP_ENV=dev hypercorn app:app --bind 0.0.0.0:8001 --workers 4
```

* 4개를 실행한 결과 입니다.

INFO:     Started server process [91202]

INFO:     Waiting for application startup.

INFO:     Started server process [91203]

INFO:     Waiting for application startup.

INFO:     Started server process [91204]

INFO:     Waiting for application startup.

INFO:     Started server process [91201]

INFO:     Waiting for application startup.

INFO:     Application startup complete.

INFO:     Application startup complete.

INFO:     Application startup complete.

INFO:     Application startup complete.


======== 저는 배드민턴을 좋아하는 클스 입니다. =========

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."


아래를 눌러서 구매 부탁드립니다.


강산연 501 배드민턴 셔틀콕, 화이트, 12개입, 1개 샌디스크 울트라 듀얼 C타입 Type c OTG겸용, 128GB

라벨: , , , , , , , , ,

2023년 2월 15일 수요일

ChatGPT Python 으로 해보기 MacOS

 ChatGPT Python 으로 해보기<OpenAI>


1. pyenv + virtualenv + poetry 가 설치되어 있어야 한다.

2. 디렉토리 만들기

$ mkdir chatgpt
$ cd chatgpt


3. 패키지 설치하기

$ poetry init  

   ... 계속 엔터 ...

$ poetry add openai

$ code . 

4. main.py 짜기

import openai import argparse YOUR_API_KEY = '여기에 API KEY 입력' def chatGPT(prompt, API_KEY=YOUR_API_KEY): # set api key openai.api_key = API_KEY # Call the chat GPT API completion = openai.Completion.create( engine = 'text-davinci-003' # 'text-curie-001' # 'text-babbage-001' #'text-ada-001' , prompt = prompt , temperature = 0.5 , max_tokens = 1024 , top_p = 1 , frequency_penalty = 0 , presence_penalty = 0) return completion['choices'][0]['text'] def main(): # 지문 입력 란 prompt = input("Insert a prompt: ") print(chatGPT(prompt).strip()) if __name__ == '__main__': main()


5. 실행 하기

$ python main.py



아직 한글이 지원이 잘 안되기 때문에 영어로 하면 잘나온다.

그리고 무료의 경우 한도가 있어서 아래와 같이 오류가 나온다.





라벨: , , ,

2023년 2월 7일 화요일

맥북에 AWS 개발 환경 설정하기

 

1. 개요

2. 설치하기

  1. VPN에 상관없이 인터넷 연결만 되면 가능함
  2. Run iTerm on Mac
  3. mkdir ~/aws
  4. cd aws
  5. Install awscli : $ pip install awscli
  6. $ aws configure -> 자격 증명 넣어라고 나옴 (발급 권한 필요)

AWS Access Key ID [None]: AK당신이 AIM에서 발급 받은 키ROZ7A
AWS Secret Access Key [None]: KEY [ 잘 생각 해보세요 ]
Default region name [None]: ap-northeast-2
Default output format [None]: json

Aws cli와 anaconda 충돌 해결
  • 문제
Traceback (most recent call last):
  File "/Users/mksong.cncity/opt/anaconda3/bin/aws", line 19, in <module>
    import awscli.clidriver
  File "/Users/mksong.cncity/opt/anaconda3/lib/python3.7/site-packages/awscli/clidriver.py", line 24, in <module>
    from botocore.history import get_global_history_recorder
ModuleNotFoundError: No module named 'botocore.history'

  • 해결법
$ pip uninstall awscli
$ pip install awscli --force-reinstall --upgrade --user
$ aws configure

  • Test : $ aws s3 ls
  • Key 생성은 루트 관리자가 생성해줘야 함. 다운은 AWS Console > 내계정 > 내 보안 자격 증명에서 받을 수 있음
  • 절대로 노출하면 안됨

3. AWS SDK 로 프로그램 개발

3.1 AWS SDK 설치

3.1 AWS SDK Sample for python

import boto3

# Create an S3 client
s3 = boto3.client('s3')

# Call S3 to list current buckets
response = s3.list_buckets()

# Get a list of all bucket names from the response
buckets = [bucket['Name'] for bucket in response['Buckets']]

# Print out the bucket list
print("Bucket List: %s" % buckets)

4. AWS EC2에 접속하기

4.1 with SSH on Mac

ssh youraccount@IPaddr

라벨: , , , , ,