home / skills / wdm0006 / python-skills / packaging

packaging skill

/skills/packaging

This skill guides Python library packaging with modern pyproject.toml, build backends, and PyPI publishing, helping you package, publish, and troubleshoot

npx playbooks add skill wdm0006/python-skills --skill packaging

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
3.0 KB
---
name: packaging-python-libraries
description: Packages and distributes Python libraries using modern pyproject.toml, build backends (setuptools, hatchling), PyPI publishing with trusted publishing, and wheel building. Use when packaging libraries for distribution, publishing to PyPI, or troubleshooting packaging issues.
---

# Python Library Packaging

## pyproject.toml Essentials

```toml
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "my-package"
version = "1.0.0"
description = "Short description"
readme = "README.md"
requires-python = ">=3.10"
license = {text = "MIT"}
dependencies = []

[project.optional-dependencies]
dev = ["pytest>=7.0", "ruff>=0.1", "mypy>=1.0"]

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

[project.scripts]
mycli = "my_package.cli:main"

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

## Building

```bash
pip install build
python -m build              # Creates dist/
twine check dist/*           # Validate
```

## Publishing to PyPI

**First time setup:**
```bash
# Create API token at pypi.org/manage/account/token/
export TWINE_USERNAME=__token__
export TWINE_PASSWORD=pypi-xxx...
```

**Publish:**
```bash
twine upload --repository testpypi dist/*  # Test first
twine upload dist/*                         # Production
```

## GitHub Actions (Trusted Publishing)

```yaml
# .github/workflows/publish.yml
on:
  release:
    types: [published]

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
      - run: pip install build && python -m build
      - uses: pypa/gh-action-pypi-publish@release/v1
```

## Dependency Best Practices

```toml
# DO: Minimum versions
dependencies = ["requests>=2.28", "click>=8.0"]

# DON'T: Exact pins (locks users)
dependencies = ["requests==2.28.1"]

# DO: Optional for features
[project.optional-dependencies]
cli = ["click>=8.0"]
```

## Including Package Data

```toml
[tool.setuptools.package-data]
my_package = ["py.typed", "data/*.json"]
```

```python
from importlib.resources import files
data = files("my_package.data").joinpath("file.json").read_text()
```

For detailed templates, see:
- **[PYPROJECT_FULL.md](PYPROJECT_FULL.md)** - Complete pyproject.toml
- **[CONDA.md](CONDA.md)** - Conda packaging guide

## Checklist

```
Before Release:
- [ ] pyproject.toml valid
- [ ] README.md informative
- [ ] LICENSE file exists
- [ ] Version set correctly
- [ ] twine check passes

After Release:
- [ ] pip install works
- [ ] Import works
- [ ] GitHub release created
```

## Learn More

This skill is based on the [Distribution](https://mcginniscommawill.com/guides/python-library-development/#distribution-reaching-your-users) section of the [Guide to Developing High-Quality Python Libraries](https://mcginniscommawill.com/guides/python-library-development/) by [Will McGinnis](https://mcginniscommawill.com/).

Overview

This skill packages and distributes Python libraries using modern pyproject.toml workflows, build backends (setuptools, hatchling), and secure PyPI publishing. It guides you through building wheels, validating distributions, and setting up trusted CI publishing. The goal is reproducible, user-friendly releases that install and import cleanly.

How this skill works

The skill inspects and generates pyproject.toml examples, configures build-system and project metadata, and shows how to include package data and entry points. It walks through local builds (python -m build), validation (twine check), and secure publishing steps using PyPI tokens and GitHub Actions for trusted releases. It also highlights dependency rules and pre/post-release checklists to catch common packaging issues.

When to use it

  • Preparing a new library for distribution to PyPI or TestPyPI
  • Migrating from setup.py to pyproject.toml and modern build backends
  • Automating trusted publishing with GitHub Actions and PyPI API tokens
  • Troubleshooting wheel or sdist build and install failures
  • Ensuring package data and type hints are included and discoverable

Best practices

  • Use pyproject.toml with a build-system and project table instead of setup.py for clarity
  • Specify minimum dependency versions (x.y+) rather than exact pins in project dependencies
  • Validate built artifacts with twine check before uploading to TestPyPI or PyPI
  • Use API tokens (TWINE_USERNAME=__token__) and GitHub Actions with least-permission id-token for trusted publishing
  • Include LICENSE, README, and correct versioning; run a pre-release checklist and smoke tests after publish

Example use cases

  • Create a minimal pyproject.toml for a library that lives under src/ and exposes a CLI via [project.scripts]
  • Build wheel and sdist locally, run twine check, then upload to TestPyPI for verification
  • Configure GitHub Actions to build on release and publish using pypa/gh-action-pypi-publish for automated trusted releases
  • Package and include JSON data and py.typed files so runtime code can use importlib.resources and type checkers can find types
  • Resolve packaging errors by checking build-backend settings and ensuring required build dependencies (setuptools, wheel) are listed

FAQ

How do I test a publish without affecting production?

Upload first to TestPyPI using twine upload --repository testpypi dist/* to validate installation and metadata before pushing to production PyPI.

How should I store PyPI credentials in CI?

Create a PyPI API token, store it as a secret in your CI provider, and use TWINE_USERNAME=__token__ and TWINE_PASSWORD set to that secret; prefer dedicated publish actions with minimal permissions.