Python PyPI Package Builder Skill
A complete, battle-tested guide for building, testing, linting, versioning, typing, and
publishing a production-grade Python library to PyPI — from first commit to community-ready
release.
AI Agent Instruction:
Read this entire file before writing a single line of code or
creating any file. Every decision — layout, backend, versioning strategy, patterns, CI —
has a decision rule here. Follow the decision trees in order. This skill applies to any
Python package type (utility, SDK, CLI, plugin, data library). Do not skip sections.
Quick Navigation
Section in this file
What it covers
1. Skill Trigger
When to load this skill
2. Package Type Decision
Identify what you are building
3. Folder Structure Decision
src/ vs flat vs monorepo
4. Build Backend Decision
setuptools / hatchling / flit / poetry
5. PyPA Packaging Flow
The canonical publish pipeline
6. Project Structure Templates
Full layouts for every option
7. Versioning Strategy
PEP 440, semver, dynamic vs static
Reference file
What it covers
references/pyproject-toml.md
All four backend templates,
setuptools_scm
,
py.typed
, tool configs
references/library-patterns.md
OOP/SOLID, type hints, core class design, factory, protocols, CLI
references/testing-quality.md
conftest.py
, unit/backend/async tests, ruff/mypy/pre-commit
references/ci-publishing.md
ci.yml
,
publish.yml
, Trusted Publishing, TestPyPI, CHANGELOG, release checklist
references/community-docs.md
README, docstrings, CONTRIBUTING, SECURITY, anti-patterns, master checklist
references/architecture-patterns.md
Backend system (plugin/strategy), config layer, transport layer, CLI, backend injection
references/versioning-strategy.md
PEP 440, SemVer, pre-release, setuptools_scm deep-dive, flit static, decision engine
references/release-governance.md
Branch strategy, branch protection, OIDC, tag author validation, prevent invalid tags
references/tooling-ruff.md
Ruff-only setup (replaces black/isort), mypy config, pre-commit, asyncio_mode=auto
Scaffold script:
run
python skills/python-pypi-package-builder/scripts/scaffold.py --name your-package-name
to generate the entire directory layout, stub files, and
pyproject.toml
in one command.
1. Skill Trigger
Load this skill whenever the user wants to:
Create, scaffold, or publish a Python package or library to PyPI
Build a pip-installable SDK, utility, CLI tool, or framework extension
Set up
pyproject.toml
, linting, mypy, pre-commit, or GitHub Actions for a Python project
Understand versioning (
setuptools_scm
, PEP 440, semver, static versioning)
Understand PyPA specs:
py.typed
,
MANIFEST.in
,
RECORD
, classifiers
Publish to PyPI using Trusted Publishing (OIDC) or API tokens
Refactor an existing package to follow modern Python packaging standards
Add type hints, protocols, ABCs, or dataclasses to a Python library
Apply OOP/SOLID design patterns to a Python package
Choose between build backends (setuptools, hatchling, flit, poetry)
Also trigger for phrases like:
"build a Python SDK", "publish my library", "set up PyPI CI",
"create a pip package", "how do I publish to PyPI", "pyproject.toml help", "PEP 561 typed",
"setuptools_scm version", "semver Python", "PEP 440", "git tag release", "Trusted Publishing".
2. Package Type Decision
Identify what the user is building
before
writing any code. Each type has distinct patterns.
Decision Table
Type
Core Pattern
Entry Point
Key Deps
Example Packages
Utility library
Module of pure functions + helpers
Import API only
Minimal
arrow
,
humanize
,
boltons
,
more-itertools
API client / SDK
Class with methods, auth, retry logic
Import API only
httpx
or
requests
boto3
,
stripe-python
,
openai
CLI tool
Command functions + argument parser
[project.scripts]
or
[project.entry-points]
click
or
typer
black
,
ruff
,
httpie
,
rich
Framework plugin
Plugin class, hook registration
[project.entry-points."framework.plugin"]
Framework dep
pytest-
,
django-
,
flask-
Data processing library
Classes + functional pipeline
Import API only
Optional:
numpy
,
pandas
pydantic
,
marshmallow
,
cerberus
Mixed / generic
Combination of above
Varies
Varies
Many real-world packages
Decision Rule:
Ask the user if unclear. A package can combine types (e.g., SDK with a CLI
entry point) — use the primary type for structural decisions and add secondary type patterns on top.
For implementation patterns of each type, see
references/library-patterns.md
.
Package Naming Rules
PyPI name: all lowercase, hyphens —
my-python-library
Python import name: underscores —
my_python_library
Check availability:
https://pypi.org/search/
before starting
Avoid shadowing popular packages (verify
pip install
How it works:
git tag v1.0.0 → installed version = 1.0 .0 git tag v1.1.0 → installed version = 1.1 .0 ( commits after tag ) → version = 1.1 .0.post1 ( suffix stripped for PyPI )
In code — NEVER hardcode when using setuptools_scm:
from importlib.metadata import version, PackageNotFoundError try: version = version ( "your-package" ) except PackageNotFoundError: version = "0.0.0-dev"
Fallback for uninstalled dev checkouts
Required pyproject.toml config: [ tool.setuptools_scm ] version_scheme = "post-release" local_scheme = "no-local-version"
Prevents +g from breaking PyPI uploads
Critical: always set fetch-depth: 0 in every CI checkout step. Without full git history, setuptools_scm cannot find tags and the build version silently falls back to 0.0.0+dev . Static versioning (flit, hatchling manual, poetry)
your_package/init.py
version
"1.0.0"
Update this before every release
Version specifier best practices for dependencies
In [project] dependencies:
"httpx>=0.24"
Minimum version — PREFERRED for libraries
"httpx>=0.24,<1.0"
Upper bound only when a known breaking change exists
"httpx==0.27.0"
Pin exactly ONLY in applications, NOT libraries
NEVER do this in a library — it breaks dependency resolution for users:
"httpx~=0.24.0" # Too tight
"httpx==0.27.*" # Fragile
Version bump → release flow
1. Update CHANGELOG.md — move [Unreleased] entries to [x.y.z] - YYYY-MM-DD
2. Commit the changelog
git add CHANGELOG.md git commit -m "chore: prepare release vX.Y.Z"
3. Tag and push — this triggers publish.yml automatically
git tag vX.Y.Z git push origin main --tags
4. Monitor GitHub Actions → verify on https://pypi.org/project/your-package/
For complete pyproject.toml templates for all four backends, see references/pyproject-toml.md . Where to Go Next After understanding decisions and structure: Set up pyproject.toml → references/pyproject-toml.md All four backend templates (setuptools+scm, hatchling, flit, poetry), full tool configs, py.typed setup, versioning config. Write your library code → references/library-patterns.md OOP/SOLID principles, type hints (PEP 484/526/544/561), core class design, factory functions, init.py , plugin/backend pattern, CLI entry point. Add tests and code quality → references/testing-quality.md conftest.py , unit/backend/async tests, parametrize, ruff/mypy/pre-commit setup. Set up CI/CD and publish → references/ci-publishing.md ci.yml , publish.yml with Trusted Publishing (OIDC, no API tokens), CHANGELOG format, release checklist. Polish for community/OSS → references/community-docs.md README sections, docstring format, CONTRIBUTING, SECURITY, issue templates, anti-patterns table, and master release checklist. Design backends, config, transport, CLI → references/architecture-patterns.md Backend system (plugin/strategy pattern), Settings dataclass, HTTP transport layer, CLI with click/typer, backend injection rules. Choose and implement a versioning strategy → references/versioning-strategy.md PEP 440 canonical forms, SemVer rules, pre-release identifiers, setuptools_scm deep-dive, flit static versioning, decision engine (DEFAULT/BEGINNER/MINIMAL). Govern releases and secure the publish pipeline → references/release-governance.md Branch strategy, branch protection rules, OIDC Trusted Publishing setup, tag author validation in CI, tag format enforcement, full governed publish.yml . Simplify tooling with Ruff → references/tooling-ruff.md Ruff-only setup replacing black/isort/flake8, mypy config, pre-commit hooks, asyncio_mode=auto (remove @pytest.mark.asyncio), migration guide.