본문으로 건너뛰기
Advertisement

써드파티 패키지 관리 — pip, requirements.txt, pyproject.toml, uv

Python 생태계의 강점은 수십만 개의 써드파티 패키지입니다. 패키지를 올바르게 설치, 관리, 배포하는 방법을 마스터합니다.


pip 기본 명령어

pip은 Python Package Installer로, PyPI(Python Package Index)에서 패키지를 설치합니다.

# 설치
pip install requests
pip install "requests==2.31.0" # 정확한 버전
pip install "requests>=2.28,<3.0" # 버전 범위
pip install requests[security] # 선택적 의존성(extras)

# 업그레이드
pip install --upgrade requests
pip install -U pip # pip 자체 업그레이드

# 제거
pip uninstall requests
pip uninstall -y requests # 확인 없이 제거

# 목록 조회
pip list # 설치된 패키지 목록
pip list --outdated # 업데이트 가능한 패키지
pip show requests # 특정 패키지 상세 정보

# 의존성 출력
pip freeze # 설치된 패키지를 requirements.txt 형식으로
pip freeze > requirements.txt

# 오프라인 설치
pip download requests -d ./packages # 다운로드만
pip install --no-index -f ./packages requests # 다운로드된 파일에서 설치

requirements.txt 관리

기본 형식

# requirements.txt
requests==2.31.0
numpy>=1.26.0,<2.0
pandas~=2.1.0 # ~= 는 호환 가능한 버전 (>=2.1.0, <2.2.0)
flask>=3.0
# 주석 가능

# 로컬 패키지 설치
-e ./my_local_package

# 다른 파일 포함
-r requirements-base.txt

환경별 파일 분리 패턴

requirements/
base.txt # 공통 의존성
dev.txt # 개발 환경 추가
prod.txt # 프로덕션 추가
test.txt # 테스트 환경 추가
# requirements/base.txt
fastapi==0.110.0
sqlalchemy==2.0.28
pydantic==2.6.3
# requirements/dev.txt
-r base.txt
pytest==8.1.1
pytest-asyncio==0.23.5
black==24.2.0
ruff==0.3.2
# requirements/prod.txt
-r base.txt
uvicorn[standard]==0.27.1
gunicorn==21.2.0
# 환경별 설치
pip install -r requirements/dev.txt
pip install -r requirements/prod.txt

pyproject.toml — 현대적 패키지 설정

PEP 517/518/621에 따른 현대적인 Python 프로젝트 설정 파일입니다. setup.py, setup.cfg, requirements.txt를 통합합니다.

# pyproject.toml
[build-system]
requires = ["setuptools>=68", "setuptools-scm"]
build-backend = "setuptools.backends.legacy:build"

[project]
name = "my-awesome-package"
version = "1.0.0"
description = "정말 유용한 패키지"
readme = "README.md"
license = { text = "MIT" }
authors = [
{ name = "홍길동", email = "hong@example.com" }
]
requires-python = ">=3.12"
keywords = ["utility", "tools"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Programming Language :: Python :: 3.12",
"License :: OSI Approved :: MIT License",
]

# 런타임 의존성
dependencies = [
"requests>=2.28",
"pydantic>=2.0",
]

[project.optional-dependencies]
dev = [
"pytest>=8.0",
"black>=24.0",
"ruff>=0.3",
"mypy>=1.8",
]
docs = [
"sphinx>=7.0",
"sphinx-rtd-theme",
]

[project.urls]
Homepage = "https://github.com/example/my-package"
Documentation = "https://my-package.readthedocs.io"

[project.scripts]
my-tool = "mypackage.cli:main" # CLI 진입점

[tool.setuptools.packages.find]
where = ["src"]

도구별 설정을 pyproject.toml에 통합

[tool.black]
line-length = 88
target-version = ["py312"]

[tool.ruff]
line-length = 88
target-version = "py312"

[tool.ruff.lint]
select = ["E", "F", "I", "UP"]

[tool.mypy]
python_version = "3.12"
strict = true

[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"

[tool.coverage.run]
source = ["src"]

uv — 초고속 Python 패키지 관리자

uv는 Rust로 작성된 차세대 Python 패키지 관리자입니다. pip보다 10~100배 빠르며, 가상환경 관리, 패키지 잠금, Python 버전 관리를 통합합니다.

# uv 설치
curl -LsSf https://astral.sh/uv/install.sh | sh
# 또는 pip install uv

# 새 프로젝트 시작
uv init my-project
cd my-project

# 패키지 추가
uv add requests
uv add "fastapi>=0.110"
uv add --dev pytest black ruff

# 패키지 제거
uv remove requests

# 의존성 동기화 (uv.lock 기준)
uv sync
uv sync --dev # 개발 의존성 포함

# 스크립트 실행
uv run python main.py
uv run pytest
uv run -- python -c "import requests; print(requests.__version__)"

# Python 버전 관리
uv python install 3.12
uv python list
# uv가 생성하는 pyproject.toml
[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"requests>=2.31.0",
"fastapi>=0.110.0",
]

[dependency-groups]
dev = [
"pytest>=8.1.1",
"black>=24.2.0",
]
# uv.lock — 완전한 의존성 잠금 파일 (git에 커밋 권장)
version = 1
requires-python = ">=3.12"

[[package]]
name = "requests"
version = "2.31.0"
source = { registry = "https://pypi.org/simple" }
...

가상환경과 패키지 격리

각 프로젝트마다 독립적인 Python 환경을 사용해 의존성 충돌을 방지합니다.

venv (내장)

# 가상환경 생성
python -m venv .venv

# 활성화
source .venv/bin/activate # Linux/macOS
.venv\Scripts\activate.bat # Windows CMD
.venv\Scripts\Activate.ps1 # Windows PowerShell

# 활성화 확인
which python # .venv/bin/python
pip list # 이 환경에 설치된 패키지만 표시

# 비활성화
deactivate

uv로 가상환경 관리

# uv는 자동으로 .venv 관리
uv venv # .venv 생성
uv venv --python 3.12 # 특정 버전 지정
source .venv/bin/activate # 수동 활성화 (선택)
uv sync # uv.lock 기반 동기화

pyenv (Python 버전 관리)

# pyenv 설치 후
pyenv install 3.12.2
pyenv local 3.12.2 # 현재 디렉터리용 버전 설정
pyenv global 3.12.2 # 전역 기본 버전 설정

의존성 해결 전략

의존성 잠금 (Locking)

재현 가능한 빌드를 위해 모든 의존성의 정확한 버전을 기록합니다.

# pip-tools 방식
pip install pip-tools

# requirements.in — 직접 의존성만 기술
cat > requirements.in << EOF
requests>=2.28
fastapi>=0.100
EOF

# requirements.txt 생성 (모든 의존성 잠금)
pip-compile requirements.in -o requirements.txt
pip-compile requirements-dev.in -o requirements-dev.txt

# 동기화
pip-sync requirements.txt

보안 취약점 검사

# pip-audit
pip install pip-audit
pip-audit

# safety
pip install safety
safety check

# uv
uv audit

의존성 트리 시각화

pip install pipdeptree
pipdeptree
pipdeptree --reverse # 역방향 (누가 이 패키지를 사용하는지)

# 특정 패키지
pipdeptree -p requests

실전 예제: 프로젝트 환경 자동화 스크립트

#!/usr/bin/env python3
"""프로젝트 초기화 스크립트"""

import subprocess
import sys
from pathlib import Path


def run(cmd: list[str], check: bool = True) -> subprocess.CompletedProcess:
"""명령 실행"""
print(f"$ {' '.join(cmd)}")
return subprocess.run(cmd, check=check, capture_output=True, text=True)


def setup_project(project_dir: str = ".") -> None:
"""프로젝트 환경 설정"""
project_path = Path(project_dir)

# Python 버전 확인
if sys.version_info < (3, 12):
print("Python 3.12 이상이 필요합니다.")
sys.exit(1)

# uv 설치 여부 확인
result = run(["uv", "--version"], check=False)
if result.returncode != 0:
print("uv를 설치합니다...")
run(["pip", "install", "uv"])

# 가상환경 생성 및 동기화
run(["uv", "venv", "--python", "3.12"])
run(["uv", "sync", "--dev"])

print("\n환경 설정 완료!")
print("다음 명령으로 시작하세요:")
print(" source .venv/bin/activate")
print(" uv run python main.py")


if __name__ == "__main__":
setup_project()

고수 팁

팁 1: pip install --dry-run으로 설치 전 확인

pip install --dry-run fastapi uvicorn

팁 2: PYTHONDONTWRITEBYTECODE으로 .pyc 파일 생성 억제

export PYTHONDONTWRITEBYTECODE=1
# Docker 이미지에서 용량 절약에 유용

팁 3: extras_require로 선택적 의존성 제공

# pyproject.toml
[project.optional-dependencies]
postgres = ["asyncpg>=0.29", "psycopg>=3.1"]
redis = ["redis>=5.0"]
all = ["mypackage[postgres,redis]"]
pip install "mypackage[postgres]"
pip install "mypackage[all]"

팁 4: uv run으로 venv 없이 스크립트 실행

# 인라인 의존성 선언 (PEP 723)
# script.py의 맨 위에:
# /// script
# dependencies = ["requests", "rich"]
# ///
uv run script.py # 자동으로 임시 환경 생성 후 실행
Advertisement