FastAPI service for PolicyEngine microsimulations with Supabase backend and object storage.
- RESTful API for tax-benefit microsimulations
- Supabase for PostgreSQL database and object storage
- Background worker for simulation processing
- SQLModel for type-safe database models
- Logfire observability and monitoring
- Terraform deployment to GCP Cloud Run
- Supabase CLI
- Docker and Docker Compose
- Python 3.13+ with uv
- Set up environment
cp .env.example .envThe defaults in .env.example work with local Supabase. Key settings:
SUPABASE_URL=http://127.0.0.1:54321
SUPABASE_DB_URL=postgresql://postgres:[email protected]:54322/postgres
STORAGE_BUCKET=datasets- Start Supabase
supabase startCreates a local instance with PostgreSQL (port 54322), Storage API, and Studio dashboard at http://localhost:54323.
- Initialise database
make initThis resets the database, creates tables, storage bucket, and RLS policies.
- Seed data
make seedSeeds UK and US tax-benefit models with variables, parameters, and datasets.
- Start the API
docker compose upAPI available at http://localhost:8000. Visit http://localhost:8000/docs for interactive documentation.
Base URL: http://localhost:8000
GET /health → Health check
GET /datasets → List datasets
POST /datasets → Create dataset
GET /policies → List policies
POST /policies → Create policy
GET /dynamics → List dynamics
POST /dynamics → Create dynamic
GET /simulations → List simulations
POST /simulations → Create simulation
GET /simulations/{id} → Get simulation status
GET /variables → List variables
GET /parameters → List parameters
GET /parameter-values → List parameter values
GET /tax-benefit-models → List models
GET /tax-benefit-model-versions → List model versions
GET /aggregates → List aggregates
POST /aggregates → Create aggregate
GET /aggregates/{id} → Get aggregate
GET /change-aggregates → List change aggregates
POST /change-aggregates → Create change aggregate
GET /change-aggregates/{id} → Get change aggregate
DELETE /change-aggregates/{id} → Delete change aggregate
- Create simulation:
POST /simulationswith dataset and policy - Poll status:
GET /simulations/{id}until status is "completed" - Request aggregates:
POST /aggregateswith simulation_id and variable - Compare reforms:
POST /change-aggregateswith baseline and reform simulation IDs
make init # Reset and initialise Supabase (tables, buckets, permissions)
make seed # Seed UK/US models only
make integration-test # Full setup: init, seeding, tests
make reset # Reset Supabase database (supabase db reset)make db-reset-prod # Reset production database (requires confirmation)Warning: db-reset-prod drops all tables and storage, recreates everything, and reseeds data. Requires typing "yes" to confirm.
make format # Format code with ruff
make lint # Lint and fix with ruff
make test # Run unit testsSchema is defined in two parts:
SQLModel tables (src/policyengine_api/models/): All table definitions use SQLModel for type safety and single source of truth.
SQL migrations (supabase/migrations/): Row-level security policies, storage buckets, and Postgres-specific features.
To reset and recreate everything:
uv run python scripts/init.pyThis drops all tables, deletes the storage bucket, then recreates tables from SQLModel and applies RLS policies.
Logfire instruments HTTP requests, database queries, and performance metrics. View traces at the Logfire dashboard.
- API server: FastAPI application (port 8000)
- Database: Supabase PostgreSQL
- Storage: Supabase object storage for .h5 dataset files
- Worker: Polling worker for background simulations
- Datasets: Microdata files in Supabase storage
- DatasetVersions: Versioned dataset snapshots
- Policies: Parameter reforms
- Dynamics: Dynamic behavioural responses
- Simulations: Tax-benefit calculations
- Variables: Model outputs (income_tax, universal_credit)
- Parameters: System settings (personal_allowance, benefit_rates)
- ParameterValues: Time-bound parameter values
- Aggregates: Statistics from simulations
- ChangeAggregates: Reform impact analysis
policyengine-api-v2/
├── src/policyengine_api/
│ ├── api/ # FastAPI routers
│ ├── config/ # Settings
│ ├── models/ # SQLModel database models
│ ├── services/ # Database, storage
│ ├── tasks/ # Background worker
│ └── main.py # FastAPI app
├── supabase/
│ └── migrations/ # RLS policies and storage
├── scripts/ # Database init and seeding
├── terraform/ # GCP Cloud Run deployment
├── tests/ # Test suite
└── docker-compose.yml # Local services
AGPL-3.0