Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 20 additions & 19 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "Python 3",
"build": { "dockerfile": "Dockerfile" },

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "pip3 install --user -r requirements.txt",

// Configure tool-specific properties.
// "customizations": {},

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
"remoteUser": "root"
"name": "project",
"image": "mcr.microsoft.com/devcontainers/python:3",
"features": {
"ghcr.io/devcontainers-extra/features/mise:1": {}
},
"customizations": {
"vscode": {
"extensions": [
"hverlin.mise-vscode",
"tamasfe.even-better-toml",
"redhat.vscode-yaml",
"charliermarsh.ruff",
"ms-python.python"
]
}
},
"postCreateCommand": "echo 'eval \"$(mise activate bash)\"' >> ~/.bashrc",
"forwardPorts": [
"8000:8000"
]
}
13 changes: 6 additions & 7 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@ jobs:
- "3.12"
steps:
- uses: actions/checkout@v6
- name: Install uv and setup Python
uses: astral-sh/setup-uv@v7
- uses: jdx/mise-action@v4
with:
python-version: ${{ matrix.python-version }}
enable-cache: true
tool_versions: |
python ${{ matrix.python-version }}
- name: Install dependencies
run: make install
run: mise run install
- name: Format and lint
run: make lint
run: mise run lint
- name: Run tests
run: make test
run: mise run test
16 changes: 2 additions & 14 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: 3.12
- uses: jdx/mise-action@v4
- name: Configure Git Credentials
run: |
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
- uses: actions/cache@v5
with:
key: mkdocs-material-${{ env.cache_id }}
path: .cache
restore-keys: |
mkdocs-material-
- name: Install dependencies
run: pip install mkdocs-material mkdocstrings[python]
- name: Publish to GitHub Pages
run: mkdocs gh-deploy --force
run: mise run docs
25 changes: 20 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
repos:
- repo: local
# General hygiene
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: lint
name: Linting
entry: make lint
language: system
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-toml
- id: check-json
- id: check-merge-conflict
- id: check-added-large-files
args: [--maxkb=1000]
- id: no-commit-to-branch
args: [--branch, main]

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.12
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
46 changes: 44 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,45 @@
{
"makefile.configureOnOpen": false
}
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true,
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.codeActionsOnSave": {
"source.fixAll.ruff": "explicit",
"source.organizeImports.ruff": "explicit"
}
},
"[toml]": {
"editor.defaultFormatter": "tamasfe.even-better-toml"
},
"[yaml]": {
"editor.defaultFormatter": "redhat.vscode-yaml"
},
"python.testing.pytestEnabled": true,
"python.testing.unittestEnabled": false,
"python.testing.pytestArgs": [
"--tb=short"
],
"files.exclude": {
"**/__pycache__": true,
"**/*.pyc": true,
"**/.pytest_cache": true,
"**/.ruff_cache": true,
"**/cdk.out": true,
"**/.venv": true
},
"search.exclude": {
"**/__pycache__": true,
"**/.venv": true,
"**/cdk.out": true,
"**/node_modules": true,
"uv.lock": true
},
"editor.rulers": [
120
],
"editor.insertSpaces": true,
"editor.tabSize": 4,
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true
}
62 changes: 27 additions & 35 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ This is a **Python project template** that provides a pre-configured, production
- **Documentation** via [MkDocs](https://www.mkdocs.org) with [mkdocstrings](https://mkdocstrings.github.io), auto-deployed to GitHub Pages
- **CI/CD** via GitHub Actions
- **Containerisation** via Docker and Dev Containers
- **Environment & Task Management** via [mise](https://mise.jdx.dev)

---

Expand All @@ -30,71 +31,62 @@ This is a **Python project template** that provides a pre-configured, production
│ ├── README.md # Project README and MkDocs home page
│ ├── CONTRIBUTING.md # Contributing guidelines
│ └── reference/ # Auto-generated API reference pages
├── project/ # Main source package (renamed via `make project`)
├── project/ # Main source package (renamed via `mise run project`)
│ ├── __init__.py
│ └── app.py # CLI entry point
├── tests/ # Test suite
│ ├── conftest.py # Shared pytest fixtures and hooks
│ └── test_app.py # Sample tests
├── compose.yml # Docker Compose file
├── Dockerfile # App container
├── Makefile # Workflow automation targets
├── mise.toml # Workflow automation tasks
├── mkdocs.yml # MkDocs configuration
├── pyproject.toml # Project metadata, dependencies, and tool configuration
└── uv.lock # Locked dependency versions (do not edit manually)
```

> **Note:** The `project/` folder is the template placeholder. After initialising a real project with `make project NAME=...`, it is renamed to the chosen package name.
> **Note:** The `project/` folder is the template placeholder. After initialising a real project with `mise run project name=...`, it is renamed to the chosen package name.

---

## Setup

### Prerequisites

- Python 3.12+
- [pipx](https://pipx.pypa.io) (to install uv)
- [mise](https://mise.jdx.dev)
- Docker (for Dev Container or containerised runs)

### First-time setup

```bash
# 1. Install uv (if not already installed)
make uv

# 2. Install all dependencies
make install

# 3. Install pre-commit hooks
make precommit

# 4. Activate the virtual environment
make venv
# Install tools, project dependencies, and pre-commit hooks
mise run dev
```

### Rename the template for a new project (run once)

```bash
make project NAME="my-project" DESCRIPTION="My app" AUTHOR="Your Name" EMAIL="you@example.com" GITHUB="your-username"
mise run project --name "my-project" --description "My app" --author "Your Name" --email "you@example.com" --github "your-username"
```

---

## Common Commands

| Task | Command |
|---|---|
| Install dependencies | `make install` |
| Update dependencies | `make update` |
| Lint and format | `make lint` |
| Run tests with coverage | `make test` |
| Run app locally | `app` (after `make venv`) or `uv run app` |
| Run app in Docker | `docker compose run app` |
| Serve docs locally | `make local` |
| Deploy docs to GitHub Pages | `make docs` |
| Full setup from scratch | `make all` |

> Refer to `docs/README.md` for the full list of available targets. Add new targets to `Makefile` as needed.
| Task | Command | Alias |
|---|---|---|
| Install dependencies | `mise run install` | `i` |
| Update dependencies | `mise run update` | `u` |
| Lint and format | `mise run lint` | `l` |
| Run tests with coverage | `mise run test` | `t` |
| Run app locally | `mise run app` | `a` |
| Run app in Docker | `docker compose run app` | |
| Serve docs locally | `mise run local-docs` | `d` |
| Deploy docs to GitHub Pages | `mise run docs` | |
| Setup dev environment | `mise run dev` | |
| Full setup from scratch | `mise run all` | |

> Refer to `docs/README.md` for the full list of available targets. Add new targets to `mise.toml` as needed.

---

Expand All @@ -104,15 +96,15 @@ make project NAME="my-project" DESCRIPTION="My app" AUTHOR="Your Name" EMAIL="yo
- **Linter/formatter**: `ruff` — enforces `E` (pycodestyle errors) and `I` (isort) rules
- **Type checker**: `pyright` — all imports must resolve; missing imports are errors
- **Pre-commit**: hooks run `ruff` automatically before every commit
- Run `make lint` to format, sort imports, and check types manually
- Run `mise run lint` to format, sort imports, and check types manually
- All public functions and classes must have docstrings (used by `mkdocstrings` for API docs)

---

## Testing

- Tests live in the `tests/` directory and mirror the source structure
- Run the full test suite with coverage using `make test` (runs `pytest` via `coverage`)
- Run the full test suite with coverage using `mise run test` (runs `pytest` via `coverage`)
- Coverage is measured with branch coverage enabled; the report is printed to the terminal and exported as `coverage.xml`
- Shared fixtures belong in `tests/conftest.py`
- Test files must be named `test_*.py`
Expand Down Expand Up @@ -140,15 +132,15 @@ make project NAME="my-project" DESCRIPTION="My app" AUTHOR="Your Name" EMAIL="yo
- Use `pytest` monkeypatch and `pytest-mock` for mocking instead of `unittest.MagicMock`
- Do not cheat! Never modify source code just to make a failing test pass. Fix real bugs in source code and fix incorrect assertions in tests

## Make Targets
## Mise Tasks

Use `make` targets for all common workflows: lint, test, run locally, and deploy. Refer to `docs/README.md` for currently available targets. Add new targets to `Makefile` as needed.
Use `mise` tasks for all common workflows: lint, test, run locally, and deploy. Refer to `docs/README.md` for currently available tasks. Add new tasks to `mise.toml` as needed.

## Notes

- Python 3.12+ required
- Dependencies are managed via `pyproject.toml` and locked in `uv.lock`
- Do not edit `uv.lock` directly; use `make update` to update dependencies
- Do not edit `uv.lock` directly; use `mise run update` to update dependencies

## Coding Conventions

Expand Down
5 changes: 2 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
FROM python:3.12-alpine
FROM python:3.14-alpine
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /code
RUN apk add -u make
COPY . .
RUN make install
RUN uv sync
ENTRYPOINT ["uv", "run", "app"]
58 changes: 0 additions & 58 deletions Makefile

This file was deleted.

Loading