Python Packaging¶
Status: 🟢 Active | Owner: Python Guild
Package vs Application¶
| Project Type | Build Tool | Distribution |
|---|---|---|
| Internal library / SDK | Poetry + build | Internal PyPI (Artifactory) |
| Service / application | Poetry | Docker image |
| CLI tool | Poetry + pyproject.toml entry point | Internal PyPI or Docker |
| Data science notebook | N/A | Not packaged — repo only |
Building a Distributable Library¶
# pyproject.toml for a library
[tool.poetry]
name = "acme-shared-auth"
version = "1.2.0"
description = "Shared authentication middleware for ACME services"
authors = ["Platform Team <[email protected]>"]
readme = "README.md"
packages = [{include = "acme_shared_auth", from = "src"}]
[tool.poetry.dependencies]
python = "^3.10"
pydantic = "^2.0"
Use src/ layout for libraries to prevent accidental imports from the project root:
my-library/
├── src/
│ └── acme_shared_auth/
│ ├── __init__.py
│ └── middleware.py
├── tests/
├── pyproject.toml
└── README.md
Versioning¶
Library versions follow SemVer:
- Patch (1.2.0 → 1.2.1): Bug fixes, no API changes.
- Minor (1.2.x → 1.3.0): New features, backward compatible.
- Major (1.x → 2.0.0): Breaking API changes — requires migration guide.
Use poetry version to bump:
poetry version patch # 1.2.0 → 1.2.1
poetry version minor # 1.2.1 → 1.3.0
poetry version major # 1.3.0 → 2.0.0
Publishing to Internal PyPI¶
Publishing is automated via CI. Do not publish manually.
# .github/workflows/publish.yml
- name: Build and publish
run: |
poetry config repositories.internal ${{ vars.INTERNAL_PYPI_URL }}
poetry config http-basic.internal ${{ secrets.PYPI_USER }} ${{ secrets.PYPI_TOKEN }}
poetry build
poetry publish --repository internal
Installing from Internal PyPI¶
Configure pip or Poetry to look at the internal registry:
# pyproject.toml
[[tool.poetry.source]]
name = "internal"
url = "https://pypi.acme.internal/simple/"
priority = "primary"
Entry Points for CLI Tools¶
This registers a acme-deploy command when the package is installed.
References¶
Last reviewed: 2025-Q4 | Owner: Python Guild