PyPI에 패키지 배포하기

파이썬 패키지를 PyPI에 배포하기

권장 프로젝트 구조

your-project/
├─ src/
│  └─ mypkg/
│     ├─ __init__.py
│     └─ core.py
├─ tests/
│  └─ test_core.py
├─ README.md
├─ LICENSE
├─ .gitignore
└─ pyproject.toml

pyproject.toml 작성

[build-system]
requires = ["setuptools>=68"]      # PEP 621 지원
build-backend = "setuptools.build_meta"

[project]
name = "mypkg"                               # PyPI 전체에서 유일해야 함
version = "0.1.0"                            # 릴리스마다 올릴 것
description = "My package does awesome things."
readme = "README.md"
requires-python = ">=3.8"
license = { file = "LICENSE" }
authors = [{ name = "Your Name", email = "you@example.com" }]
keywords = ["example", "demo", "tutorial"]
classifiers = [
  "Programming Language :: Python :: 3",
  "License :: OSI Approved :: MIT License",
  "Operating System :: OS Independent",
]
dependencies = [
  # "requests>=2.31",
]

[project.optional-dependencies]
dev = ["pytest>=8"]

[project.urls]
Homepage = "https://github.com/yourname/mypkg"
Issues = "https://github.com/yourname/mypkg/issues"
Documentation = "https://github.com/yourname/mypkg#readme"

# 콘솔 스크립트 (선택): `mypkg` 명령어를 설치한다
[project.scripts]
mypkg = "mypkg.cli:main"

# src 레이아웃용 setuptools 패키지 탐색 (선택)
[tool.setuptools.packages.find]
where = ["src"]

# 패키지 데이터 포함 (선택)
[tool.setuptools.package-data]
"mypkg" = ["py.typed", "data/*.txt"]

빌드와 배포

pip install --upgrade build twine

# 패키지 빌드
python -m build

# PyPI에 업로드 (테스트 또는 실제)
twine upload dist/*

🔴 꼭 알아둘 것: dist/에는 현재 버전만 남겨라

PyPI는 같은 파일명을 다시 올리는 것을 허용하지 않는다 (파일명에 이름 + 버전 + 빌드 태그가 들어 있다). dist/에 예전 산출물이나 중복 파일이 남아 있으면 “File already exists” 또는 버전/파일 충돌이 발생한다.

빌드 전에 항상 dist/를 비워서 새 버전만 들어 있게 하자:

rm -rf dist && python -m build

한 번 업로드한 파일은 PyPI에서 덮어쓸 수 없다. 잘못된 빌드를 올렸다면 버전을 올려서 다시 업로드해야 한다.

.pypirc (선택)

매번 자격 증명을 입력하지 않으려면 홈 디렉토리에 .pypirc 파일을 만들면 된다:

[pypi]
username = __token__
password = your-token