Skip to content

Repository files navigation

Template Python Library

A Copier template for bootstrapping a Python library with modern tooling and CI/CD.

What's included

AreaTooling
Packaginguv with uv_build build backend
Linting & formattingruff, prettier via prek
Type checkingmypy + pyright
Testingpytest with coverage, xdist, randomly
DocsMkDocs Material + mkdocstrings
Releasespython-semantic-release
CI/CDGitHub Actions — CI (split jobs, SHA-pinned), Docs deploy, Semantic Release, PyPI publishing
Secret scanninggitleaks
Dependency updatesDependabot
Community filesCONTRIBUTING.md, CODE_OF_CONDUCT.md, SECURITY.md

Prerequisites

  • Copier >= 9.0 (pipx install copier or uv tool install copier)
  • uv
  • prek (uv tool install prek)

Usage

Create a new project

copier copy --trust gh:mumblepins/template-python-library my-new-project

Or from a local clone:

copier copy --trust /path/to/template-python-library my-new-project

The --trust flag is required because this template runs post-generation tasks (git init, dependency installation, pre-commit setup).

Copier will prompt for:

PromptDescriptionDefault
project_nameHuman-readable nameMy Python Library
project_slugKebab-case identifier (URLs, package)derived from name
package_namePython import name (snake_case)derived from slug
descriptionShort project description(empty)
author_nameAuthor name(empty)
author_emailAuthor email(empty)
github_orgGitHub org or usernamemumblepins
licenseMIT / Apache-2.0 / BSD-3-Clause / GPL-3.0 / AGPL-3.0 / NoneMIT
python_versionMinimum Python (3.11–3.14)3.14

After prompting, Copier will:

  1. Render all .jinja templates with your answers
  2. Run git init
  3. Remove the LICENSE file if you chose None
  4. Run uv sync --all-groups to install dependencies
  5. Install pre-commit hooks via prek install
  6. Run prek run --all-files to lint and format everything

Update an existing project

If you generated a project from this template and want to pull in template changes:

cd my-project
uv run poe update
# or directly:
copier update --trust

Copier will replay your original answers and prompt for any new or changed values, then merge the diff.

Project structure (generated)

my-project/
├── src/
│ └── <package_name>/
│ ├── __init__.py # __version__ lives here
│ ├── app.py # starter module
│ └── py.typed # PEP 561 marker
├── tests/
│ ├── __init__.py
│ ├── conftest.py
│ └── test_app.py
├── docs/
│ ├── index.md
│ └── api/
│ └── index.md
├── .github/
│ ├── workflows/
│ │ ├── ci.yml # lint + type-check + test (matrix) + coverage + gate
│ │ ├── docs.yml # build + deploy MkDocs to GitHub Pages
│ │ ├── release.yml # semantic release + GitHub release assets
│ │ └── publish.yml # PyPI publishing (disabled by default)
│ └── dependabot.yml
├── .copier-answers.yml # stores your Copier answers for updates
├── .editorconfig
├── .gitignore
├── .pre-commit-config.yaml
├── .python-version
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE # omitted if license = None
├── mkdocs.yml
├── pyproject.toml
├── README.md
└── SECURITY.md

Developer commands

Once inside a generated project, common tasks are available via poethepoet:

CommandWhat it does
uv run poe syncUpgrade and install all dependency groups
uv run poe testRun pytest with coverage (html, term, xml)
uv run poe prekRun all pre-commit hooks on all files
uv run poe buildBuild sdist + wheel via uv build
uv run poe docsBuild MkDocs site
uv run poe docs-serveServe docs locally with live reload
uv run poe checkFull pre-flight: sync → prek → test
uv run poe updatePull template updates via copier update

CI/CD workflows

  • CI — runs on push/PR to main: split into lint, type-check, test (Python matrix), coverage, and an all-checks-pass gate. All actions pinned by SHA.
  • Docs — builds MkDocs and deploys to GitHub Pages via GitHub Pages Actions (separate build + deploy jobs).
  • Release — uses python-semantic-release to create versioned GitHub releases from conventional commits.
  • Publish — PyPI publishing with Trusted Publishers and Sigstore provenance attestation. Disabled by default (workflow_dispatch only); edit the workflow trigger to push: tags: ["v*"] to enable.

Conventional commits

Semantic release depends on conventional commit messages:

  • feat: → minor bump
  • fix: / perf: → patch bump
  • build:, chore:, ci:, docs:, refactor:, style:, test: → no version bump

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages