Contributing
This page describes how to set up a local development environment, run tests, and understand the CI gates for Typus.
Environment
- Python 3.10+ (CI runs on 3.10, 3.11, 3.12)
- Use
uvand Makefile shortcuts (no plainpipin scripts/CI): - Preferred bootstrap path for contributors:
./dev/scripts/bootstrap-dev.sh # ensures uv + Python 3.10, syncs .venv, installs hooks
- Lower-level env sync targets remain available when you only need to refresh part of the setup:
make dev-setup # creates .venv (py310) and installs -e .[dev,sqlite,loader]
make dev-install # installs pre-commit hooks
Formatting & Lint
make format # uv run ruff format .
make lint # uv run ruff check --fix .
make lint-check # uv run ruff format --check . && uv run ruff check .
Type checking
make typecheck # uv run ty check (warnings fail)
Canonical local quality gate
make check-all # lint-check + typecheck + schemas-check + ci
Tests
Lightweight SQLite-backed tests that match the CI gate:
make ci
Broader default local suite (SQLite + tests that do not require optional Postgres access):
make test
Postgres-backed tests (optional, requires a running DB):
export TYPUS_TEST_DSN=postgresql+asyncpg://<user>:<pass>@<host>:5432/ibrida-v0
export POSTGRES_DSN=$TYPUS_TEST_DSN
export ELEVATION_DSN=$TYPUS_TEST_DSN
export ELEVATION_TABLE=elevation_raster
# Smoke-check DSN / DB / required table before optional PG tests
make test-pg-smoke
# Optional Postgres marker subset (dataset-dependent)
make test-pg
# Elevation smoke tests (guarded; requires raster table)
TYPUS_ELEVATION_TEST=1 uv run pytest -q -k elevation_service
Important: `make test` and CI exclude `pg_optional` tests by marker. Run
`make test-pg-smoke` + `make test-pg` explicitly when you want live Postgres coverage. Some tests
assert counts that are specific to the SQLite sample fixture and will not match
the full production dataset. The recommended workflow is:
1) Run `make ci` / `make test` to exercise the SQLite fixture path.
2) Run `make test-pg-smoke` and then `make test-pg` for Postgres-specific coverage.
Notes:
- Ensure the Postgres database contains the required
expanded_taxatable with the recommended indexes. You can bootstrap indexes with:
uv run typus-pg-ensure-indexes
Pre-commit
make dev-install
Hooks run on commit and in CI:
- ruff (lint)
- ruff-format (check-only in CI)
- whitespace/yaml fixers
- pytest-lite (fast subset; mirrors make ci test selection)
JSON Schemas
If you add or change public Pydantic models, append the dotted path to
typus/export_schemas.py and regenerate schemas:
uv run python -m typus.export_schemas
Generated JSON files live under typus/schemas/ and are committed to the repo.
CI and release workflows enforce schema freshness with make schemas-check.
Perf Harness (optional)
make perf
Writes a report to dev/agents/perf_report.md. You can enable TYPUS_PERF_VERIFY=1 for strict checks,
and TYPUS_PERF_EXPLAIN=1 to append EXPLAIN snippets for Postgres.
Service Backends
- SQLite: for offline/dev; loader creates indexes by default.
- Postgres: for production or full datasets;
typus-pg-ensure-indexesadds recommended indexes. - Elevation: Postgres-only; use
ELEVATION_DSNandELEVATION_TABLE(defaultelevation_raster).
CI/CD Overview
- CI workflow (
.github/workflows/ci.yml): - Matrix on Python 3.10/3.11/3.12.
- Installs dev dependencies, then runs
make check-all. make check-allcoversmake lint-check,make typecheck,make schemas-check, andmake ci.- Triggers on PRs and pushes to
main(to avoid duplicate branch + PR runs for the same commit). - Publish workflow (
.github/workflows/publish.yml): - Blocks build/publish on the same
make check-allgate used locally and in CI. - Builds and uploads wheels, then deploys docs on tag.