Skip to content

nullhack/python-project-template

Repository files navigation

Python Project Template



Contributors Forks Stargazers Issues MIT License Coverage CI Python

Production-ready Python scaffolding with a structured AI-agent workflow — from idea to shipped feature.


Quick Start

git clone https://github.com/nullhack/python-project-template
cd python-project-template
curl -LsSf https://astral.sh/uv/install.sh | sh  # skip if uv installed
uv sync --all-extras
opencode && @setup-project                        # personalise for your project
uv run task test && uv run task lint && uv run task static-check

Why this template?

Most Python templates give you a folder structure and a Makefile. This one gives you a complete delivery system:

  • No feature starts without written acceptance criteria — Gherkin Example: blocks traced to tests
  • No feature ships without adversarial review — the reviewer's default hypothesis is "broken"
  • No guesswork on test stubs — they are generated automatically from your .feature files
  • No manual @id tags — assigned automatically when you run tests
  • AI agents for every role — PO, SE, and reviewer each have scoped instructions; none can exceed their authority

How it works

5-step delivery cycle

SCOPE → ARCH → TDD LOOP → VERIFY → ACCEPT
Step Role Output
1 · SCOPE Product Owner Discovery interviews + Gherkin stories + acceptance criteria
2 · ARCH Software Engineer Module stubs, ADRs, auto-generated test stubs
3 · TDD LOOP Software Engineer RED → GREEN → REFACTOR, one criterion at a time
4 · VERIFY Reviewer Adversarial check — lint, types, coverage, semantic review
5 · ACCEPT Product Owner Demo, validate, ship

WIP limit: 1 feature at a time. Features are .feature files that move through folders:

docs/features/backlog/      ← waiting
docs/features/in-progress/  ← building (max 1)
docs/features/completed/    ← shipped

AI agents included

Agent Responsibility
@product-owner Scope, stories, acceptance criteria, delivery acceptance
@software-engineer Architecture, TDD loop, git, releases
@reviewer Adversarial verification — default position: broken
@setup-project One-time project initialisation

Quality tooling, pre-configured

Tool Role
uv Package & environment management
ruff Lint + format (Google docstrings)
pyright Static type checking — 0 errors
pytest + hypothesis Tests + property-based testing
pytest-beehave Auto-generates test stubs from .feature files
pytest-cov Coverage — 100% required
pdoc API docs → GitHub Pages
taskipy Task runner

Commands

uv run task test          # Full suite + coverage
uv run task test-fast     # Fast, no coverage (use during TDD loop)
uv run task lint          # ruff check + format
uv run task static-check  # pyright
uv run task run           # Run the app

Code standards

Coverage 100%
Type errors 0
Function length ≤ 20 lines
Class length ≤ 50 lines
Max nesting 2 levels
Principles YAGNI › KISS › DRY › SOLID › Object Calisthenics

Test convention

Write acceptance criteria in Gherkin:

@id:a3f2b1c4
Example: User sees version on startup
  Given the application starts
  When no arguments are passed
  Then the version string is printed to stdout

Run tests once — a traced, skipped stub appears automatically:

@pytest.mark.skip(reason="not yet implemented")
def test_display_version_a3f2b1c4() -> None:
    """
    Given the application starts
    When no arguments are passed
    Then the version string is printed to stdout
    """

Each test is traced to exactly one acceptance criterion. No orphan tests. No untested criteria.


Versioning

v{major}.{minor}.{YYYYMMDD} — each release gets a unique adjective-animal name.


License

MIT — see LICENSE.

Author: @nullhack · Documentation