hobokai 님의 블로그

Poetry 완전 가이드: 파이썬 프로젝트 관리의 혁신 본문

Language

Poetry 완전 가이드: 파이썬 프로젝트 관리의 혁신

hobokai 2025. 8. 14. 09:18

목차

  1. Poetry란 무엇인가?
  2. 설치 및 기본 설정
  3. 프로젝트 생성과 구조
  4. 의존성 관리
  5. 가상환경 관리
  6. 빌드와 배포
  7. 고급 기능
  8. 실무 활용 예제
  9. 모범 사례

Poetry란 무엇인가?

Poetry는 Python의 의존성 관리와 패키징을 위한 현대적인 도구입니다. pip + virtualenv + setup.py의 복잡한 조합을 하나의 일관된 도구로 대체하여 Python 프로젝트 관리를 획기적으로 개선합니다.

기존 도구들의 문제점

# 기존 방식의 복잡함
pip install virtualenv
virtualenv venv
source venv/bin/activate  # Windows: venv\Scripts\activate
pip install -r requirements.txt
pip freeze > requirements.txt
python setup.py sdist bdist_wheel

Poetry의 해결책

# Poetry로 간단하게
poetry install
poetry add requests
poetry build
poetry publish

설치 및 기본 설정

설치 방법

공식 인스톨러 사용 (권장)

# Unix/macOS
curl -sSL https://install.python-poetry.org | python3 -

# Windows (PowerShell)
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python -

pip를 통한 설치

pip install poetry

conda를 통한 설치

conda install -c conda-forge poetry

기본 설정

# 가상환경을 프로젝트 폴더 내에 생성
poetry config virtualenvs.in-project true

# 설정 확인
poetry config --list

# 설정 변경
poetry config repositories.test-pypi https://test.pypi.org/simple/

프로젝트 생성과 구조

새 프로젝트 생성

# 새 프로젝트 생성
poetry new my-project

# 기존 디렉토리에 초기화
cd existing-project
poetry init

프로젝트 구조

my-project/
├── pyproject.toml          # 프로젝트 설정 파일
├── README.md
├── my_project/
│   └── __init__.py
└── tests/
    └── __init__.py

pyproject.toml 파일

[tool.poetry]
name = "my-project"
version = "0.1.0"
description = "내 프로젝트 설명"
authors = ["Your Name <your.email@example.com>"]
readme = "README.md"
homepage = "https://github.com/username/my-project"
repository = "https://github.com/username/my-project"
documentation = "https://my-project.readthedocs.io"
keywords = ["python", "poetry", "example"]
classifiers = [
    "Development Status :: 4 - Beta",
    "Intended Audience :: Developers",
    "License :: OSI Approved :: MIT License",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.8",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
]

[tool.poetry.dependencies]
python = "^3.8"
requests = "^2.28.0"
click = "^8.0.0"

[tool.poetry.group.dev.dependencies]
pytest = "^7.0.0"
black = "^22.0.0"
flake8 = "^5.0.0"
mypy = "^0.991"

[tool.poetry.group.docs.dependencies]
sphinx = "^5.0.0"
sphinx-rtd-theme = "^1.0.0"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.poetry.scripts]
my-cli = "my_project.cli:main"

의존성 관리

의존성 추가

# 기본 의존성 추가
poetry add requests
poetry add "django>=4.0,<5.0"

# 개발 의존성 추가
poetry add --group dev pytest black flake8

# 선택적 의존성 추가
poetry add --optional redis
poetry add --optional[cache] redis

# Git 저장소에서 설치
poetry add git+https://github.com/user/repo.git

# 로컬 패키지 설치
poetry add ./path/to/local/package
poetry add ../relative/path/to/package

의존성 제거

# 의존성 제거
poetry remove requests

# 개발 의존성 제거
poetry remove --group dev pytest

의존성 업데이트

# 모든 의존성 업데이트
poetry update

# 특정 패키지만 업데이트
poetry update requests

# 의존성 트리 확인
poetry show --tree

# 설치된 패키지 목록
poetry show
poetry show --latest  # 최신 버전과 비교

의존성 그룹 관리

# 특정 그룹만 설치
poetry install --only dev
poetry install --only docs

# 특정 그룹 제외하고 설치
poetry install --without dev
poetry install --without dev,docs

# 모든 그룹 설치
poetry install --with dev,docs

가상환경 관리

가상환경 조작

# 가상환경 정보 확인
poetry env info

# 가상환경 목록
poetry env list

# 특정 Python 버전으로 가상환경 생성
poetry env use python3.9
poetry env use /full/path/to/python

# 가상환경 제거
poetry env remove python3.9

# 가상환경에서 명령 실행
poetry run python script.py
poetry run pytest
poetry run black .

# 가상환경 활성화
poetry shell

의존성 설치와 동기화

# pyproject.toml과 poetry.lock 기반으로 설치
poetry install

# poetry.lock 파일 업데이트
poetry lock

# 프로덕션 의존성만 설치
poetry install --only main

빌드와 배포

패키지 빌드

# wheel과 source distribution 빌드
poetry build

# 특정 형식만 빌드
poetry build --format wheel
poetry build --format sdist

PyPI 배포

# PyPI에 배포 (API 토큰 필요)
poetry publish

# 테스트 PyPI에 배포
poetry publish --repository test-pypi

# 빌드와 배포를 한 번에
poetry publish --build

# 저장소 설정
poetry config repositories.test-pypi https://test.pypi.org/simple/
poetry config pypi-token.test-pypi your-test-pypi-token

버전 관리

# 버전 확인
poetry version

# 버전 업데이트
poetry version patch     # 0.1.0 -> 0.1.1
poetry version minor     # 0.1.1 -> 0.2.0
poetry version major     # 0.2.0 -> 1.0.0
poetry version prerelease # 1.0.0 -> 1.0.1-alpha.0

# 직접 버전 지정
poetry version 2.0.0

고급 기능

플러그인 시스템

[tool.poetry.plugins."poetry.plugins"]
my-plugin = "my_package.plugins:MyPlugin"

[tool.poetry.plugins."console_scripts"]
my-cli = "my_package.cli:main"

소스 저장소 설정

[[tool.poetry.source]]
name = "private-pypi"
url = "https://private-pypi.example.com/simple/"
priority = "primary"

[[tool.poetry.source]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
priority = "explicit"
# 특정 소스에서 패키지 설치
poetry add torch --source pytorch

사용자 정의 명령어

[tool.poetry.scripts]
my-cli = "my_package.cli:main"
deploy = "my_package.deploy:run"

환경 변수 설정

# .env 파일 지원 (python-dotenv 설치 필요)
poetry add python-dotenv
# my_package/__init__.py
from dotenv import load_dotenv
load_dotenv()

실무 활용 예제

FastAPI 프로젝트 예제

# 프로젝트 생성
poetry new fastapi-project
cd fastapi-project

# 의존성 추가
poetry add fastapi uvicorn
poetry add --group dev pytest httpx black

# pyproject.toml 설정
[tool.poetry]
name = "fastapi-project"
version = "0.1.0"
description = "FastAPI 프로젝트 예제"
authors = ["Developer <dev@example.com>"]

[tool.poetry.dependencies]
python = "^3.8"
fastapi = "^0.104.0"
uvicorn = {extras = ["standard"], version = "^0.23.0"}
pydantic = "^2.0.0"
sqlalchemy = "^2.0.0"
alembic = "^1.12.0"

[tool.poetry.group.dev.dependencies]
pytest = "^7.4.0"
httpx = "^0.25.0"
black = "^23.9.0"
flake8 = "^6.1.0"
mypy = "^1.6.0"

[tool.poetry.scripts]
start = "fastapi_project.main:start_server"
migrate = "alembic:main"

[tool.black]
line-length = 88
target-version = ['py38']

[tool.mypy]
python_version = "3.8"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true

Django 프로젝트 예제

# Django 프로젝트 초기화
poetry new django-project
cd django-project

# Django 관련 의존성 추가
poetry add django djangorestframework
poetry add --group dev django-debug-toolbar pytest-django

# 환경별 의존성 분리
poetry add --group prod gunicorn psycopg2-binary
poetry add --group dev sqlite3

데이터 사이언스 프로젝트

# 데이터 사이언스 프로젝트
poetry new data-analysis
cd data-analysis

# 데이터 사이언스 스택
poetry add pandas numpy matplotlib seaborn scikit-learn
poetry add jupyter notebook
poetry add --group dev pytest

# Jupyter 확장 설정
[tool.poetry.group.jupyter.dependencies]
jupyter = "^1.0.0"
jupyterlab = "^4.0.0"
ipykernel = "^6.25.0"

모범 사례

1. 프로젝트 구조 최적화

my-project/
├── pyproject.toml
├── poetry.lock
├── README.md
├── .gitignore
├── src/
│   └── my_project/
│       ├── __init__.py
│       ├── core/
│       ├── api/
│       └── utils/
├── tests/
│   ├── __init__.py
│   ├── unit/
│   └── integration/
├── docs/
└── scripts/

2. 의존성 관리 전략

# 정확한 버전 제약 사용
[tool.poetry.dependencies]
python = "^3.8"
django = "~4.2.0"  # 4.2.x 버전만
requests = "^2.31.0"  # 2.31.0 이상, 3.0.0 미만

# 그룹별 의존성 분리
[tool.poetry.group.dev.dependencies]
pytest = "^7.4.0"
black = "^23.9.0"
mypy = "^1.6.0"

[tool.poetry.group.docs.dependencies]
sphinx = "^7.1.0"
sphinx-rtd-theme = "^1.3.0"

[tool.poetry.group.test.dependencies]
pytest-cov = "^4.1.0"
pytest-mock = "^3.11.0"

3. CI/CD 통합

.github/workflows/ci.yml

name: CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: [3.8, 3.9, "3.10", "3.11"]

    steps:
    - uses: actions/checkout@v4
    
    - name: Install Poetry
      uses: snok/install-poetry@v1
      with:
        version: latest
        virtualenvs-create: true
        virtualenvs-in-project: true
    
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v4
      with:
        python-version: ${{ matrix.python-version }}
    
    - name: Load cached venv
      id: cached-poetry-dependencies
      uses: actions/cache@v3
      with:
        path: .venv
        key: venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/poetry.lock') }}
    
    - name: Install dependencies
      if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
      run: poetry install --no-interaction --no-root
    
    - name: Install project
      run: poetry install --no-interaction
    
    - name: Run tests
      run: |
        poetry run pytest --cov=src --cov-report=xml
    
    - name: Upload coverage
      uses: codecov/codecov-action@v3

4. Docker 통합

Dockerfile

FROM python:3.11-slim

# Poetry 설치
RUN pip install poetry

# Poetry 설정
ENV POETRY_NO_INTERACTION=1 \
    POETRY_VENV_IN_PROJECT=1 \
    POETRY_CACHE_DIR=/tmp/poetry_cache

WORKDIR /app

# 의존성 파일 복사
COPY pyproject.toml poetry.lock ./

# 의존성 설치
RUN poetry install --only=main --no-root && rm -rf $POETRY_CACHE_DIR

# 소스 코드 복사
COPY src/ src/

# 프로젝트 설치
RUN poetry install --only=main

EXPOSE 8000

CMD ["poetry", "run", "uvicorn", "src.my_project.main:app", "--host", "0.0.0.0", "--port", "8000"]

5. 개발 환경 설정

Makefile

.PHONY: install update test lint format clean

install:
	poetry install

update:
	poetry update

test:
	poetry run pytest

lint:
	poetry run flake8 src tests
	poetry run mypy src

format:
	poetry run black src tests
	poetry run isort src tests

clean:
	find . -type d -name __pycache__ -delete
	find . -type f -name "*.pyc" -delete
	poetry env remove python

pre-commit 설정

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/psf/black
    rev: 23.9.1
    hooks:
      - id: black

  - repo: https://github.com/pycqa/isort
    rev: 5.12.0
    hooks:
      - id: isort

  - repo: https://github.com/pycqa/flake8
    rev: 6.1.0
    hooks:
      - id: flake8

  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.6.0
    hooks:
      - id: mypy

6. 성능 최적화

# 캐시 관리
poetry cache clear --all pypi
poetry cache list

# 병렬 설치 활성화
poetry config installer.parallel true

# 의존성 해결 최적화
poetry config solver.lazy-wheel true

7. 보안 고려사항

# 취약점 검사
poetry add --group dev safety
poetry run safety check

# 의존성 라이선스 확인
poetry add --group dev pip-licenses
poetry run pip-licenses
# pyproject.toml에 보안 설정
[tool.poetry.dependencies]
# 알려진 취약점이 있는 버전 제외
urllib3 = "^1.26.12"  # CVE-2022-37454 이후 버전

 

Poetry는 Python 프로젝트 관리의 새로운 표준으로 자리잡고 있습니다. 의존성 관리부터 배포까지 모든 과정을 일관되고 효율적으로 처리할 수 있어, 개발 생산성을 크게 향상시킬 수 있습니다. 이 가이드를 참고하여 Poetry를 프로젝트에 도입해보세요.