This template provides a standardized Python project structure with sensible defaults, tailored to use in Python projects. It streamlines project setup and encourages best practices from the start.
The following tools must be installed:
- Python 3.10 or newer
- uv or pipx (if you want to install Copier in an isolated environment, accessible everywhere)
- copier
-
Install Copier (if not already):
pipx install copier
or
uv tool install copier
-
Generate files in your target repository (interactive):
copier copy /path/to/copier-template /path/to/your-repo
Replace
/path/to/copier-templatewith the path to this template, and/path/to/your-repowith your target repository.Note: If you're testing with unreleased template changes, use
--vcs-ref=HEAD:copier copy --vcs-ref=HEAD /path/to/copier-template /path/to/your-repo
-
Generate non-interactively using the provided sample data file: A sample data file is provided at
examples/config-basic.yml.copier copy --data-file examples/config-basic.yml /path/to/copier-template /path/to/your-repo
You can duplicate and modify that file to create variants (e.g.,
data-with-ruff.yml).Note: This template uses conditional tasks (see Tasks Behavior), which require the
--trustflag:copier copy --trust --data-file examples/config-basic.yml /path/to/copier-template /path/to/your-repo
-
(Optional) Override specific values at the CLI: You can still override one or more answers on the fly:
copier copy --trust --data-file examples/config-basic.yml -d project_name=override_name /path/to/template /dest
-
Review and commit the generated files:
cd /path/to/your-repo git add . git commit -m "feat: Bootstrap repository from template"
This template uses conditional tasks to manage optional features (LICENSE file, GitHub integration). Understanding their behavior is important for safe updates:
Tasks always run at the end of both copier copy and copier update operations, after all files are generated. This means:
- Files are created/updated first
- Tasks execute based on your current answers
- Any deletions from tasks are permanent for that operation
When you generate a new project with conditions set:
- ✅
include_license=true→ LICENSE file is kept - ✅
include_license=false→LICENSEfile is removed after generation - ✅
github_integration=true→.github/files (templates, workflows) are kept - ✅
github_integration=false→.github/directory is removed after generation
Tasks are executed again during updates. This is important:
- ✅ Safe with
--defaults(keeps your previous answers as-is) - ✅ Safe if you keep boolean settings unchanged
⚠️ Dangerous if you change boolean settings when you have customizations
Recommended - Keeps all previous answers:
copier update --defaults --trust
# Your github_integration and include_license settings remain unchangedSafe if no customizations in affected directories:
copier update --trust --data github_integration=false
# OK if you haven't customized .github/ subdirectories# Initial generation WITH GitHub integration
copier copy --trust --vcs-ref=HEAD \
--data project_name=myproject \
--data github_integration=true \
/template /myproject
# Later: You customize workflows in .github/workflows/
# Then: Update but accidentally change github_integration to false
copier update --trust --data github_integration=false
# Result: 🔴 rm -rf .github DELETES ALL CUSTOM WORKFLOWS!If you need to disable GitHub integration after customizing .github/:
-
Manually back up your customizations:
cp -r .github/workflows /tmp/my-workflows-backup cp LICENSE /tmp/my-license-backup # if customized -
Run the update to disable features:
copier update --trust --data github_integration=false
-
Restore your customizations:
cp -r /tmp/my-workflows-backup /path/to/.github/workflows
-
Commit your changes:
git add .github/ git commit -m "Restore custom workflows"
| File | Purpose |
|---|---|
.copier-answers.yml |
Auto-maintained answers file for future updates (never edit manually). Now explicitly generated because the template includes .copier-answers.yml.jinja. |
examples/config-basic.yml |
Example data file passed with --data-file (excluded from rendered projects). |
The template excludes helper folders (examples/, my_tests/) from generated projects via _exclude in copier.yaml. This keeps consumer projects clean.
To create a new variant template from existing data file configuration:
copier copy --data-file /path/to/config-basic.yml /path/to/template /destFor advanced configuration (tasks, migrations, multiple templates) see the Copier docs sections: tasks, migrations, applying multiple templates.
You can edit the template files (*.jinja) to fit your team's standards. See Copier documentation for advanced templating and options.
This template includes comprehensive validation tests to ensure generated projects meet expected standards.
# Run all validation tests
make testTests use session-scoped fixtures for optimal performance:
- Session-scoped fixtures: Generated projects created once per test session, reused across all test modules
- Module-scoped wrappers: Clean test API with ~50% faster execution vs module scope alone
- All tests read-only: No mutations to generated projects ensures fixture reuse is safe
Test files are located in my_tests/ folder.
| File | Purpose |
|---|---|
test_core_structure.py |
Validates required files, directories, and project structure |
test_exclusions.py |
Ensures excluded files (copier.yaml, etc.) are not rendered |
test_conditional_sections.py |
Tests conditional rendering based on dependencies (e.g., Ruff) |
See my_tests/conftest.py for fixture definitions.
Project-specific guides and workflows:
| Topic | Location |
|---|---|
| CI/CD Pipeline | docs/ci.md |
| Development Setup | docs/development.md |
| Template Architecture | docs/architecture.md |
For framework and tool documentation:
- Overview of Python Packaging
- Python classifiers: PyPI Classifiers
- Python Packaging: PEP 621 - pyproject.toml
- System Package Data Exchange: SPDX License List
- Writing your pyproject.toml
- Copier Framework: Copier Documentation
- Pre-commit Hooks: pre-commit Framework
- Ruff Formatter: Ruff Documentation
- UV Package Manager: UV Documentation