A comprehensive template for AI-driven Python development with full CI/CD pipeline support.
- Multi-version Python support: Works with Python 3.9-3.13
- Comprehensive testing: pytest with async support and coverage reporting
- Code quality: Ruff (linting + formatting) + mypy (type checking)
- Pre-commit hooks: Automated code quality checks before commits
- CI/CD pipeline: GitHub Actions CI/CD with Python 3.13
- Changelog management: Scriv for conflict-free changelog (like Changesets in JS)
- Release automation: Automatic PyPI publishing and GitHub releases
- API documentation: Sphinx + GitHub Pages deploy on push to
main
- Click "Use this template" on GitHub to create a new repository
- Clone your new repository
- Update
pyproject.tomlwith your package name and description - Rename
src/my_packageto your package name - Update imports in tests and examples
- Install dependencies and start developing!
# Clone the repository
git clone https://github.com/link-foundation/python-ai-driven-development-pipeline-template.git
cd python-ai-driven-development-pipeline-template
# Create a virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install in editable mode with development dependencies
pip install -e ".[dev]"
# Install pre-commit hooks
pip install pre-commit
pre-commit install# Run all tests
pytest
# Run with coverage
pytest --cov=src --cov-report=term --cov-report=html
# Run specific test file
pytest tests/test_my_package.py
# Run with verbose output
pytest -v# Lint code (check for issues)
ruff check .
# Format code
ruff format .
# Type check
mypy src/
# Check file size limits
python scripts/check_file_size.py
# Run all checks
ruff check . && ruff format --check . && mypy src/ && python scripts/check_file_size.py.
├── .github/
│ └── workflows/
│ ├── docs.yml # Sphinx build + GitHub Pages deploy
│ └── release.yml # CI checks + release automation (PyPI + GitHub)
├── changelog.d/ # Changelog fragments (like .changeset/)
│ ├── README.md # Fragment instructions
│ └── *.md # Individual changelog entries
├── docs/ # Sphinx documentation source
│ ├── conf.py # Sphinx configuration
│ ├── index.md # Documentation landing page
│ ├── api.md # Auto-generated API reference
│ └── requirements.txt # Documentation build dependencies
├── examples/
│ └── basic_usage.py # Usage examples
├── scripts/
│ ├── check_file_size.py # File size validation script
│ ├── bump_version.py # Version bumping utility
│ ├── version_and_commit.py # CI/CD version management
│ ├── publish_to_pypi.py # PyPI publishing script
│ └── create_github_release.py # GitHub release creation
├── src/
│ └── my_package/
│ ├── __init__.py # Package entry point
│ └── py.typed # Type marker file
├── tests/
│ ├── __init__.py
│ └── test_my_package.py # Test suite
├── .gitignore # Git ignore patterns
├── .pre-commit-config.yaml # Pre-commit hooks configuration
├── .ruff.toml # Ruff additional configuration
├── pyproject.toml # Project configuration and dependencies
├── CHANGELOG.md # Project changelog
├── CONTRIBUTING.md # Contribution guidelines
├── LICENSE # Unlicense (public domain)
└── README.md # This file
This template uses modern Python packaging standards:
- pyproject.toml: Single source of truth for project configuration
- hatchling: Modern build backend (PEP 517)
- src layout: Prevents accidental imports from source directory
- py.typed: Marks package as type-hinted for mypy
-
Ruff: Ultra-fast Python linter and formatter (replaces flake8, black, isort)
- Configured for strict code quality standards
- Integrates with pre-commit hooks
- Consistent formatting across the project
-
mypy: Static type checker
- Strict mode enabled for maximum type safety
- Ensures code correctness before runtime
-
pytest: Modern testing framework
- Support for async tests via pytest-asyncio
- Coverage reporting via pytest-cov
- Organized test structure with classes
Automated checks run before each commit:
- Basic checks (trailing whitespace, file endings, etc.)
- Ruff linting and formatting
- mypy type checking
This ensures code quality is maintained throughout development.
This template uses Scriv for changelog management, which works similarly to Changesets in JavaScript projects:
- Fragment-based: Each PR adds a changelog fragment to
changelog.d/ - Conflict-free: Multiple PRs can add fragments without merge conflicts
- Auto-collection: Fragments are automatically merged during release
- Category-based: Supports Added, Changed, Deprecated, Removed, Fixed, Security
# Create a changelog fragment (similar to `npx changeset`)
scriv create
# View pending fragments
ls changelog.d/*.mdThe GitHub Actions workflow provides:
- Linting: Ruff linting, formatting, and mypy type checking
- Changelog check: Warns if PRs are missing changelog fragments
- Testing: Python 3.13 test suite
- Building: Package building and validation
- Coverage: Automatic upload to Codecov
API documentation is built with Sphinx and deployed
to GitHub Pages on every push to main. Pull requests build the docs (without
deploying) to catch regressions before they merge.
# Install docs dependencies
pip install -e ".[docs]"
# Build locally (output goes to _site/)
sphinx-build -W --keep-going -b html docs _site
# Preview in a browser
python -m http.server --directory _site 8000The Sphinx config in docs/conf.py autodiscovers src/my_package via
sphinx.ext.autodoc + sphinx.ext.autosummary and renders Google-style
docstrings with sphinx.ext.napoleon. When you bootstrap a new repository from
this template, update project, author, and the autosummary target in
docs/conf.py and docs/api.md to point at your package.
The Docs workflow (.github/workflows/docs.yml) builds on every push and
pull request, and deploys to GitHub Pages only on push to main (matching
the JS and Rust template patterns; see
link-foundation/relative-meta-logic#170
for the bug this guards against).
One-time setup per repository: open Settings → Pages and set
Source = GitHub Actions. Without this, the first deploy run fails on
actions/deploy-pages with Get Pages site failed. This cannot be configured
from a workflow.
The release workflow (release.yml) provides:
- Integrated CI checks: Runs lint, test, and build before any release
- Auto-release on push: Detects version changes and publishes automatically
- Manual release: Trigger releases via workflow_dispatch
- Fragment collection: Automatically collects changelog fragments
- PyPI publishing: OIDC trusted publishing (no tokens needed)
- GitHub releases: Automatic creation with CHANGELOG content
Important: All releases require passing CI checks (lint + test + build). No release will ever happen without passing tests, ensuring code quality and stability.
After creating a repository from this template:
-
Update
pyproject.toml:- Change
namefield - Update
project.urls - Update
tool.hatch.build.targets.wheel.packages
- Change
-
Rename
src/my_package/directory to your package name -
Update imports:
tests/test_my_package.pyexamples/basic_usage.py.ruff.toml(known-first-party)
Customize Ruff in pyproject.toml under [tool.ruff]. Current configuration:
- 88-character line length (Black-compatible)
- Comprehensive linting rules (E, W, F, I, N, UP, B, etc.)
- Strict equality enforcement
- Automatic import sorting
Configured in pyproject.toml under [tool.mypy]:
- Strict mode enabled
- No implicit optionals
- Warn on unused ignores
- Full type checking coverage
Configured in pyproject.toml under [tool.pytest.ini_options]:
- Test discovery in
tests/directory - Source path includes
src/ - Strict marker enforcement
- Coverage configuration included
| Script | Description |
|---|---|
pytest |
Run all tests |
pytest --cov=src |
Run tests with coverage |
ruff check . |
Lint code |
ruff format . |
Format code |
mypy src/ |
Type check code |
python scripts/check_file_size.py |
Check file size limits |
pre-commit run --all-files |
Run all pre-commit hooks |
scriv create |
Create a changelog fragment |
scriv collect --version X.Y.Z |
Collect fragments into CHANGELOG.md |
from my_package import add, multiply, delay
import asyncio
# Basic arithmetic
result = add(2, 3) # 5
product = multiply(2, 3) # 6
# Async operations
async def main():
await delay(1.0) # Wait for 1 second
asyncio.run(main())See examples/basic_usage.py for more examples.
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Make your changes and add tests
- Run quality checks:
ruff check . && ruff format . && mypy src/ && pytest - Commit your changes (pre-commit hooks will run automatically)
- Push and create a Pull Request
This project maintains high test coverage and uses pytest for testing:
- Unit tests for all functions
- Async test support
- Coverage reporting
- Cross-platform compatibility testing
Unlicense - Public Domain
This is free and unencumbered software released into the public domain. See LICENSE for details.
Inspired by js-ai-driven-development-pipeline-template.