Skip to content

Packaging

This guide explains the packaging setup in this Python package template, including how dependencies are managed, the build system, and how to customize it for your project.

Overview

This template uses modern Python packaging standards with pyproject.toml as the configuration file. It leverages:

  • Hatchling: A fast, modern build backend
  • Hatch-VCS: For automatic version management from Git tags
  • Optional Dependencies: Grouped extras for different use cases

pyproject.toml Structure

The pyproject.toml file contains all packaging metadata and configuration:

Build System

[build-system]
requires = ["hatchling", "hatch-vcs"]
build-backend = "hatchling.build"

This specifies Hatchling as the build backend with VCS version management.

Project Metadata

[project]
name = "python_package_template"
authors = [{ name = "Isaac C. F. Wong" }]
description = "A GitHub template repository for a Python package"
readme = "README.md"
classifiers = [
  "Development Status :: 3 - Alpha",
  "Intended Audience :: Developers",
  "License :: OSI Approved :: BSD License",
  "Programming Language :: Python :: 3 :: Only",
  "Programming Language :: Python :: 3.12",
  "Programming Language :: Python :: 3.13",
  "Programming Language :: Python :: 3.14",
]
requires-python = ">=3.12"
dynamic = ["version"]

Key fields:

  • name: Package name on PyPI
  • authors: Author information
  • description: Short description
  • classifiers: PyPI classifiers for discoverability
  • requires-python: Minimum Python version
  • dynamic: Fields computed at build time (version from Git)

Dependencies

dependencies = ["typer>=0.24.1"]

Core runtime dependencies. Add your package's dependencies here.

Optional Dependencies

[project.optional-dependencies]
test = [
  "bandit[toml]>=1.9.4",
  "ruff>=0.15.8",
  "pre-commit>=4.5.1",
  "pytest-cov>=7.1.0",
  "pytest-mock>=3.15.1",
  "pytest-runner>=6.0.1",
  "pytest>=9.0.2",
]
ci = ["pytest-github-actions-annotate-failures>=0.4.0"]
dev = ["pre-commit>=4.5.1", "python_package_template[test,docs]"]
docs = ["zensical>=0.0.31", "mkdocstrings-python>=2.0.3"]
build = ["hatch>=1.16.5"]

Extras allow users to install additional features:

uv pip install "your-package[dev,docs]"

Scripts/Entry Points

[project.scripts]

Defines command-line scripts. This creates the python_package_template command.

URLs

[project.urls]
Documentation = "https://isaac-cf-wong.github.io/python-package-template"
Source = "https://github.com/isaac-cf-wong/python-package-template"
Tracker = "https://github.com/isaac-cf-wong/python-package-template/issues"
Home = "https://github.com/isaac-cf-wong/python-package-template"

Links for PyPI project page.

Version Management

Version is managed automatically using Hatch-VCS:

[tool.hatch.version]

Versions are derived from Git tags (e.g., tag v1.2.3 → version 1.2.3).

Tool Configurations

The file also includes configurations for various tools:

  • Coverage: Test coverage settings
  • Flake8: Linting rules
  • Black: Code formatting
  • Pytest: Test configuration
  • Pyright: Type checking

Customizing for Your Project

1. Update Project Metadata

Change the name, description, authors, and URLs to match your project.

2. Add Dependencies

Add your runtime dependencies to the dependencies list.

For development dependencies, add to the appropriate optional groups.

3. Configure Tools

Adjust tool settings in the [tool.*] sections to match your preferences.

4. Add Scripts

If your package has CLI commands, add them to [project.scripts].

Building and Publishing

Local Building

Build the package locally:

python -m build

This creates dist/ with wheel and source distributions.

Publishing to PyPI

After building:

# Using uv (recommended)
uv publish

# Or using twine
pip install twine
twine upload dist/*

For Test PyPI first:

uv publish --publish-url https://test.pypi.org/legacy/

Common Tasks

Adding a New Dependency

  1. Add to dependencies or an optional group in pyproject.toml
  2. Update your environment: uv pip install -e ".[dev]" (or equivalent)
  3. Test that it works

Changing Python Version Requirements

Update requires-python and the classifiers list.

Adding a New Optional Feature

Create a new key under [project.optional-dependencies] with the feature name.

Troubleshooting

  • Build fails: Ensure Hatchling and Hatch-VCS are installed
  • Version not updating: Check Git tags match the expected format
  • Dependencies not found: Verify extras are installed correctly

For more details, see the PyPA packaging guide and Hatch documentation.