A comprehensive, opinionated template for modern Python projects -- featuring uv packaging, Ruff for linting and formatting, justfile, pytest testing with code coverage upload to codecov, MkDocs documentation with configuration for Read The Docs, pre-commit hooks, .editorconfig, .devcontainer, GitHub Actions CI, GitHub issue and pull request templates, architectural decision record (ADR) templates and automated semantic releases.
The goal is to help you start writing code immediately without having to spend time deciding what tools or conventions to use.
- π± Create a New Repository on GitHub
- Click "Use this template".
- Choose βCreate a new repositoryβ.
- Pick a name for your new project (for example,
my-awesome-package). - Clone your new repo locally
- π‘ Customise the repository
- Rename your package directory
cd src; mv package_name my_package - Update pyproject.toml with your package name, author, and description.
- Update all references to package_name in:
- package_name/tests/
- docs/
- release-please-config.json
- GitHub Actions workflow
- This README (including badge links)
- Update the
"package-name"field in release-please-config.json with your package name for automatically bumping the version number in uv.lock (see release-please issue #2561). - Customise this README with a description of your project and planned features.
- Customise the documentation configuration in mkdocs.yml (see the Material for MkDocs documentation for details)
- Clear the CHANGELOG.
- Enable automated releases by permitting GitHub Actions to open PRs (Settings -> Actions -> Workflow permissions) and add an initial commit hash to bootstrap the release-please in .release-please-manifest.json.
- Enable publishing to GitHub Pages (Settings -> Pages) and/or add your project to RTD.
- Rename your package directory
- Python project directory structure
- README template with badges
- Packaging and dependency management via uv: pyproject.toml
- Linting and formatting via Ruff: .pre-commit-config.yaml
- Testing framework using pytest
- CI using GitHub Actions: .github/workflows/ci.yaml
- Pre-commit hooks (linting and formatting)
- Automated tests
- Package build with smoke test
- Templates for GitHub issues: bug report (01-bug.yml) and feature request (02-feature.yml)
- Template for GitHub pull request: .github/pull_request_template.md
- Docs (MkDocs + mkdocstrings): mkdocs.yml
- Automated deployment to
gh-pagesbranch via GitHub action: .github/workflows/docs-pages.yaml - Configuration for Read The Docs integration: .readthedocs.yaml
- Template for documenting architectural decisions: docs/architecture/adr/template.md.
- ADR to explain the rationale for using ADRs: docs/architecture/adr/001-use-architectural-decision-records.md.
- Automated deployment to
- Release automation via GitHub action from release-please: .github/release-please-config.json
- Citation metadata, automatically updated for each new release: CITATION.cff
- BSD-3-Clause: LICENSE
- EditorConfig configuration for consistent coding style across editors: .editorconfig
A Dockerfile and configuration in ./devcontainer can be used in VSCode or GitHub Codespaces to work in a pre-configured development environment. It uses a Python 3.14 base image and installs uv, just and all Python dependencies.
To open the project in the container VSCode, you will need to add the Dev Containers extension and download Docker (or Podman -- and configure VSCode to use podman instead of Docker) -- see the VSCode tutorial on devcontainers for more details on using devcontainers. Then run:
Dev Containers: Reopen in Container- Install uv
- Clone and install the project using uv:
git clone https://github.com/gemmadanks/python-project-template
cd python-project-template
uv sync --all-groups- Install just.
- Install pre-commit hooks (only needs to be done once)
just pre-commit-installHook definitions: .pre-commit-config.yaml
from package_name.greet import say_hello
print(say_hello("World"))Several common tasks have been added as recipes to a justfile in the root of the repository:
just install # uv sync
just test # run quick (non-slow) tests
just test-notebooks
just lint # ruff check
just format # ruff format
just type-check # pyright type-check
just docs-serve # live docs
just docs-build # build docs
just pre-commit # run all pre-commit hooks
just clean # remove generated files and folders- Configuration: mkdocs.yml
- Content pages (following the DiΓ‘taxis framework):
- docs/index.md
- docs/reference.md (autogenerated API documentation from docstrings via mkdocstrings).
- docs/tutorials.md
- docs/explanation.md
- Architecture pages
- Template for documenting architectural decisions: docs/architecture/adr/template.md.
- ADR to explain the rationale for using ADRs: docs/architecture/adr/001-use-architectural-decision-records.md.
- Index of ADRs: docs/architecture/adr/index.md.
Managed by release-please: (conventional commits drive semantic versioning and an autogenerated CHANGELOG). - Configuration: .github/release-please-config.json - Version source: pyproject.toml
.
βββ src/
β βββ package_name/ # Source package
β βββ __init__.py
β βββ greet.py # Example module (replace with real code)
βββ tests/ # Test suite
β βββ conftest.py
β βββ unit/
β βββ test_greet.py # Example unit test (replace with real tests)
βββ docs/ # Documentation (DiΓ‘taxis layout)
β βββ index.md # Documentation homepage
β βββ tags.md # Tag index
β βββ reference/
β β βββ index.md # API reference (mkdocstrings)
β βββ tutorials/
β β βββ index.md # Tutorials overview
β βββ how-to/
β β βββ index.md # How-to guides
β βββ explanation/
β β βββ index.md # Conceptual guides
β βββ architecture/
β βββ index.md # Architecture overview
β βββ adr/ # Architectural decision records
β βββ index.md # ADRs index
β βββ template.md # Template for new ADR
β βββ 001-use-architectural-decision-records.md
β βββ 002-manage-dependencies-with-uv.md
βββ notebooks/ # Jupyter notebooks
β βββ example.ipynb
βββ .github/
β βββ workflows/
β β βββ ci.yaml # Lint / test / build
β β βββ release-please.yaml # Automated releases
β βββ ISSUE_TEMPLATE/ # Issue forms
β β βββ 01-bug.yml
β β βββ 02-feature.yml
β βββ pull_request_template.md # Pull request template
β βββ dependabot.yml # Dependency update automation
βββ .pre-commit-config.yaml # Pre-commit hook definitions
βββ .devcontainer/ # Dev container configuration
β βββ devcontainer.json
β βββ Dockerfile
βββ pyproject.toml # Project metadata + dependencies (uv)
βββ uv.lock # Locked dependency versions (uv)
βββ README.md # Project overview (you are here)
βββ mkdocs.yml # MkDocs configuration
βββ CITATION.cff # Citation metadata
βββ LICENSE # License
βββ CHANGELOG.md # Generated by release-please (post-release)
βββ .release-please-manifest.json # Release-please state
βββ release-please-config.json # Release-please configuration
βββ .python-version # pyenv version pin
βββ justfile # justfile containing recipes for common tasks
βββ .editorconfig # Ensures consistent code style across editors
βββ .gitignore
Note that while it is common practice to keep the config files at the root of the
repository, and this is what I recommend, it is possible to customise the
location of some of them if you prefer
(e.g. the path to release-please-config.json [can be specified in the
release-please.yaml file for the GitHub action]
(https://github.com/googleapis/release-please-action?tab=readme-ov-file#advanced-release-configuration)
and the path to the mkdocs.yaml can be configured using the --config-file option
and setting the path in the .readthedocs.yaml file.)
Use conventional commit messages (feat:, fix:, docs:, etc.). Ensure:
- Lint & format clean
- Tests pass
- Docs build without warnings
- ADR drafted for architecturally significant changes
Suggestions and improvements to this template are very welcome β feel free to open an issue or pull request if you spot something that could be refined, added or removed.
If used in research, cite via CITATION.cff.
BSD-3-Clause β see LICENSE.
Happy coding! π