A personal copier template for bootstrapping
Python projects with the Astral toolchain (uv, ruff, ty) plus pytest,
all pre-configured.
# One-time: install copier
uv tool install copier
# Generate a new project
copier copy --UNSAFE gh:kaparoo/python-project-template my-new-project--UNSAFE is required because the template runs post-generation tasks
(git init, uv lock, uv sync, and an initial commit). Review
copier.yml before trusting it.
Pull later template improvements into an existing project:
cd my-new-project
copier update --UNSAFEThe .copier-answers.yml file in each generated project records the
answers, so copier update can re-render against newer template
versions without losing your customizations.
copier copy prompts for the following:
| Question | Type | Default | Notes |
|---|---|---|---|
project_name |
str | (required) | PEP 503 form: lowercase, hyphens |
project_description |
str | "" |
One-line summary |
package_name |
str | derived | snake_case of project_name |
author_name |
str | Jaewoo Park |
Used in pyproject + LICENSE |
author_email |
str | kaparoo2001@gmail.com |
|
github_username |
str | kaparoo |
|
repo_name |
str | {{ project_name }} |
|
python_version |
choice | 3.14 |
Oldest supported; CI tests it and every newer choice. 3.13 / 3.14 / 3.15 |
license_year |
int | 2026 |
Copyright year |
is_library |
bool | true |
Adds [build-system] + py.typed |
release_automation |
choice | manual |
manual / github-oidc; github-oidc ships publish.yml (libraries only) |
use_testpypi |
bool | true |
Stage on TestPyPI before PyPI (libraries only) |
use_pytest |
bool | true |
Adds tests/ + pytest config |
coverage_fail_under |
int | 0 |
Branch-coverage gate; 0 = off (pytest only) |
include_todo |
bool | true |
Generates TODO.md + a README 📋 TODO section |
release_automation, use_testpypi, and coverage_fail_under are only
asked when their parent feature is enabled (a library, or pytest).
is_library = falseproduces an application (no build system, nopy.typedmarker); uv treats it as a non-distributable project.use_pytest = falseomits the entire pytest layer (tests/, config, ruffPTrule), useful for ML/DL projects where deterministic test workflows are impractical.
.
├── .agents/ ← task guides for AI assistants (not shipped)
├── .github/workflows/ ← CI for this repo (not shipped)
├── copier.yml ← questions, tasks, after-action messages
├── pyproject.toml ← workspace dev tooling (copier + pytest + ruff)
├── template/ ← files rendered into generated projects
│ ├── pyproject.toml.jinja
│ ├── {{ package_name }}/
│ └── ...
├── tests/ ← tests for the template itself
├── TODO.md ← open work on the template
└── AGENTS.md ← guide for AI assistants working on this repo
git clone https://github.com/kaparoo/python-project-template
cd python-project-template
uv sync --group dev
uv run pytest # generation-scenario tests
uv run pytest -m "not slow" # skip the real-toolchain integration testsCI runs ruff and the same tests on
Ubuntu and Windows for every push to main or pytorch and every
pull request.
Commits use a Gitmoji, a concrete imperative verb, and the name of what
changed (✨ Add `ensure_dir` to `filesystem.utils`). The full rules,
with the emoji table and fixed forms, are in
template/.agents/commits.md.jinja; this
repository follows them too, with the few differences listed in
AGENTS.md.
See TODO.md for open work on the template.
See CHANGELOG.md for the template's version history.
The pytorch branch keeps an independent variant changelog with its
own pytorch-v* tag line.
This project is distributed under the terms of the MIT license.