This repository contains sample code for publishing Python packages to PyPI. I manage multiple Python projects, and the configurations for publishing them to PyPI are almost identical. In this playground, I experiment with different configurations to optimize CI processes and streamline project management.
List of Spun-off Repositories
- python-richset: A rich set implementation for Python.
- dict_zip: A utility for zipping and unzipping dictionaries.
- python-throttle-controller: A Python library for rate-limiting and throttling control.
- cachepot: A caching utility to simplify working with in-memory caches.
- python-template-analysis: A template analysis tool for Python projects.
- python-timevec: A library for time vector manipulations in Python.
I have various code snippets and boilerplate code in private repositories or local directories. I plan to spin them off and place them in this repository. I will also use this repository to incubate these codes until they are mature enough to become independent repositories. During this process, I will add tests, CI, documentation, and other improvements.
This repository is a monorepo containing multiple packages. To manage these packages, namespace packages are used. For more information, refer to the official Python packaging guide on namespace packages.
Each package is organized within the src directory, and the packages are published to PyPI independently.
Install dependencies with uv If you don't have uv installed, you can install it with the following command.
If you don't have pipx installed, you can install it with the following command in macOS
brew install pipxpipx install uvuv syncuv run poe testuv run poe formatuv run poe checkThis repository uses lefthook to run the same checks as CI locally, so problems surface before they reach CI.
# Install dependencies
uv sync
# Install the Git hooks (once; requires lefthook on your PATH)
lefthook installOnce installed, the hooks run automatically:
- pre-commit:
uv run poe checkand./scripts/check-spelling.sh - pre-push: the same checks,
uv run poe test,uv run poe build, and./scripts/check-dependencies.sh
The spelling and dependency checks use the same scripts in CI and in the hooks.
The first run downloads the pinned typos tool and pip-audit via uv.
The dependency audit checks locked direct and transitive dependencies for the
current Python version and platform without resolving them again. CI runs the
same command in its own environment; a local audit does not cover every
platform. The audit queries an online vulnerability database, so it needs
network access. A failed check prevents the commit or push.
The hooks check the working tree, not a snapshot of staged or pushed content. Before committing partially staged files, make sure their working-tree contents match what you intend to commit. Run the pre-push checks with a clean working tree to check the content being pushed.
You can also run the checks manually:
uv run poe check
uv run poe test
uv run poe build
./scripts/check-spelling.sh
./scripts/check-dependencies.shCI still runs the full matrix (see .github/workflows/); the hooks only bring that
feedback earlier on your machine.
BSD 3-Clause License
A GitHub Release builds all four packages from its tag. The workflow checks
that every wheel and source distribution has the tag's version before uploads
begin. Configure a PyPI Trusted Publisher for each package with owner kitsuyui,
repository pypi-playground, workflow pypi-publish.yml, and no environment.
For a package that does not yet exist, register a pending publisher in PyPI.
Prereleases require equivalent publishers on TestPyPI.
Uploads are independent and cannot be atomic across packages. If one upload fails, inspect the registry and workflow before retrying; already published versions cannot be overwritten. Publish only the missing package manually from the validated tag or use a new version for all packages.