Monorepo for PolicyEngine's API infrastructure, containing all services, libraries, and deployment configuration.
- Docker and Docker Compose
- Python 3.13+
- uv package manager
- gcloud CLI (for deployment)
- Terraform 1.5+ (for deployment)
Start all services:
make up # Start services on ports 8081-8083
make logs # View logs
make down # Stop servicesRun the test suite:
make test # Unit tests only
make test-integration-with-services # Full integration tests (manages services automatically)
make test-complete # Everything: unit + integration testsThe repository contains three main API services:
- api-full (port 8081): Main PolicyEngine API with household calculations
- api-simulation (port 8082): Economic simulation engine
- api-tagger (port 8083): Cloud Run revision management
Each service generates OpenAPI specs and Python client libraries for integration testing.
- Edit code locally - services hot-reload automatically when running via
make up - Run tests:
make test-complete - Commit changes to a feature branch
- Open a PR - GitHub Actions will run tests automatically
Unit tests run in isolated containers:
make test # All services
make test-service service=api-full # Single serviceIntegration tests use generated client libraries:
make generate-clients # Generate OpenAPI clients (done automatically by test commands)
make test-integration # Run integration tests (requires services running)/
├── projects/ # Service applications
│ ├── policyengine-api-full/
│ ├── policyengine-api-simulation/
│ ├── policyengine-api-tagger/
│ └── policyengine-apis-integ/ # Integration tests
├── libs/ # Shared libraries
│ └── policyengine-fastapi/ # Common FastAPI utilities
├── deployment/ # Deployment configuration
│ ├── docker-compose.yml # Local development
│ ├── docker-compose.prod.yml # Production builds
│ └── terraform/ # Infrastructure as code
├── scripts/ # Utility scripts
└── .github/workflows/ # CI/CD pipelines
Important: Most development should be done locally. Cloud deployment is slow and harder to debug.
- Configure environment:
cp deployment/.env.example deployment/.env
# Edit deployment/.env with your GCP project details- Deploy infrastructure:
make deploy # Builds images, pushes to registry, runs terraformFor existing GCP projects with resources:
make terraform-import # Import existing resources
./deployment/terraform/handle-existing-workflows.sh $PROJECT_ID --delete # Handle workflowsSee deployment guide for detailed instructions.
The repository includes automated deployment pipelines:
- Pull requests: Runs tests and builds
- Merge to main:
- Deploys to beta environment
- Runs integration tests
- Deploys to production
- Publishes API client packages to PyPI
Configure GitHub environments with these variables:
PROJECT_ID: GCP project IDREGION: GCP region (usually us-central1)_GITHUB_IDENTITY_POOL_PROVIDER_NAME: Workload identity provider
- Wait after bootstrap: GCP permission propagation can take up to an hour
- Workflows can't be imported: Use the provided script to handle existing workflows
- Always test locally first: Cloud debugging is painful
- Check terraform state: If deployments fail, check if resources already exist
make up- Start services locallymake down- Stop servicesmake logs- View service logsmake build- Build Docker images
make test- Run unit testsmake test-integration- Run integration testsmake test-complete- Run all tests with service managementmake generate-clients- Generate API client libraries
make deploy- Full deployment to GCPmake terraform-plan- Preview infrastructure changesmake terraform-import- Import existing resourcesmake terraform-destroy- Remove all infrastructuremake publish-clients- Publish API clients to PyPI (requires PYPI_TOKEN)
- Check Docker is running
- Ensure ports 8081-8083 are free
- Run
make buildto rebuild images
- Regenerate clients:
make generate-clients - Check services are healthy:
make logs - Verify port configuration matches docker-compose.yml
- Check deployment/.env configuration
- Verify GCP authentication:
gcloud auth list - For "already exists" errors:
make terraform-import - For workflow errors:
./deployment/terraform/handle-existing-workflows.sh
- Create a feature branch
- Make changes and test locally
- Ensure
make test-completepasses - Open a PR with a clear description
- Wait for CI checks to pass