FastAPI backend for CICosts - Track and optimize your CI/CD costs.
| Environment | URL |
|---|---|
| Production | https://api.cicosts.dev |
| Development | https://dev-api.cicosts.dev |
| API Docs | https://dev-api.cicosts.dev/docs |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AWS Lambda β
β βββββββββββββββββββ βββββββββββββββββββββββββββ β
β β handler.py β β workers.py β β
β β (API Lambda) β β (Workers Lambda) β β
β β β β β β
β β FastAPI + β β SQS β Process webhooks β β
β β Mangum β β Calculate costs β β
β ββββββββββ¬βββββββββ ββββββββββββββ¬βββββββββββββ β
β β β β
β ββββββββββββββββββ¬βββββββββββββββββ β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β app/ ββ
β β routers/ β API endpoints (auth, dashboard, alerts) ββ
β β services/ β Business logic (cost calc, alerts, email) ββ
β β workers/ β Webhook processing (workflow_run, job) ββ
β β models/ β SQLAlchemy models ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββ
β Supabase Postgres β
β (Transaction Pooler) β
βββββββββββββββββββββββββ
- Framework: FastAPI (Python 3.11)
- ORM: SQLAlchemy 2.0
- Database: PostgreSQL (Supabase)
- Auth: GitHub OAuth + JWT
- Email: AWS SES
- Queue: AWS SQS
- Testing: pytest + SQLite in-memory
- Deployment: AWS Lambda via GitHub Actions
- Python 3.11+
- PostgreSQL (or Supabase connection)
# Create virtual environment
python -m venv venv
source venv/bin/activate # or `venv\Scripts\activate` on Windows
# Install dependencies
pip install -r requirements.txt
# Copy environment file
cp .env.example .env
# Edit .env with your credentials
# Run development server
uvicorn app.main:app --reload --port 8000- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
cicosts-api/
βββ handler.py # Lambda API entry point
βββ workers.py # Lambda workers entry point
βββ app/
β βββ main.py # FastAPI application
β βββ config.py # Environment settings
β βββ database.py # Database connection
β βββ dependencies.py # Auth middleware
β βββ routers/
β β βββ health.py # Health check
β β βββ auth.py # GitHub OAuth
β β βββ dashboard.py # Dashboard data
β β βββ alerts.py # Alerts CRUD
β β βββ settings.py # User settings
β β βββ webhooks.py # GitHub/Stripe webhooks
β βββ models/
β β βββ user.py
β β βββ organization.py
β β βββ org_membership.py
β β βββ workflow_run.py
β β βββ job.py
β β βββ alert.py
β β βββ github_installation.py
β βββ services/
β β βββ cost_calculator.py # Runner pricing
β β βββ alert_service.py # Alert logic
β β βββ email_service.py # AWS SES
β βββ workers/
β βββ handler.py # SQS processing
βββ alembic/ # Database migrations
βββ tests/ # Test suite (189 tests)
βββ scripts/
β βββ seed_data.py # Sample data
β βββ simulate_webhooks.py
βββ requirements.txt
GET /health # Full health check
GET /health/ready # Readiness probe
GET /health/live # Liveness probe
GET /api/v1/auth/login # Initiate GitHub OAuth
GET /api/v1/auth/callback # OAuth callback
GET /api/v1/auth/me # Get current user
POST /api/v1/auth/logout # Logout
POST /api/v1/auth/refresh # Refresh token
GET /api/v1/dashboard/summary # Cost summary (today, week, month)
GET /api/v1/dashboard/trends # Cost trends over time
GET /api/v1/dashboard/top-workflows # Top workflows by cost
GET /api/v1/dashboard/recent-runs # Recent workflow runs
GET /api/v1/dashboard/workflows # Paginated workflow list
GET /api/v1/alerts # List alerts
POST /api/v1/alerts # Create alert
GET /api/v1/alerts/{id} # Get alert
PUT /api/v1/alerts/{id} # Update alert
DELETE /api/v1/alerts/{id} # Delete alert
GET /api/v1/alerts/{id}/triggers # Alert trigger history
POST /api/v1/alerts/{id}/check # Manually check alert
GET /api/v1/settings/user # Get user profile
PATCH /api/v1/settings/user # Update profile
GET /api/v1/settings/notifications # Notification preferences
PATCH /api/v1/settings/notifications # Update notifications
GET /api/v1/settings/organizations # List organizations
POST /api/v1/settings/organizations/{id}/leave # Leave org
DELETE /api/v1/settings/account # Delete account
POST /api/v1/webhooks/github # GitHub App webhooks
POST /api/v1/webhooks/stripe # Stripe webhooks
# Run all tests (189 tests)
python -m pytest tests/ -v
# With coverage
python -m pytest tests/ --cov=app --cov-report=html
# Specific test file
python -m pytest tests/test_cost_calculator.py -v
# With short tracebacks
python -m pytest tests/ -v --tb=short| Test File | Tests | Description |
|---|---|---|
test_cost_calculator.py |
34 | Runner pricing logic |
test_email_service.py |
11 | Email templates |
test_dashboard.py |
26 | Dashboard endpoints |
test_alerts_router.py |
34 | Alerts CRUD |
test_auth.py |
18 | OAuth flow |
test_settings.py |
17 | User settings |
test_webhooks.py |
9 | Webhook handling |
test_worker_handler.py |
12 | SQS processing |
Total: 189/189 passing (100%)
For local development, populate the database:
python scripts/seed_data.pyGitHub Actions runner pricing (per minute):
| Runner | Price/min |
|---|---|
| ubuntu-latest (2-core) | $0.008 |
| ubuntu-latest-4-cores | $0.016 |
| ubuntu-latest-8-cores | $0.032 |
| ubuntu-latest-16-cores | $0.064 |
| windows-latest | $0.016 |
| macos-latest | $0.080 |
| macos-latest-large | $0.120 |
| ubuntu-latest-arm | $0.005 |
Unified pipeline via .github/workflows/ci-cd.yml:
Push to main β Test β Lint β Build β Deploy Dev β Deploy Prod
β
(requires approval)
| Stage | Description |
|---|---|
| Test | pytest with coverage + Codecov upload |
| Lint | ruff + mypy (non-blocking) |
| Build | Create Lambda package β upload artifact |
| Deploy Dev | Update cicosts-dev-api + cicosts-dev-workers |
| Deploy Prod | Update cicosts-prod-api + cicosts-prod-workers (requires approval) |
pip install -r requirements.txt -t package/
cp -r app package/
cp handler.py workers.py package/
cd package && zip -r ../lambda-package.zip .
aws lambda update-function-code \
--function-name cicosts-prod-api \
--zip-file fileb://lambda-package.zip| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL connection string |
JWT_SECRET |
JWT signing secret |
GITHUB_CLIENT_ID |
OAuth client ID |
GITHUB_CLIENT_SECRET |
OAuth client secret |
GITHUB_APP_PRIVATE_KEY |
GitHub App private key |
GITHUB_WEBHOOK_SECRET |
Webhook signature secret |
AWS_SQS_QUEUE_URL |
SQS queue for webhooks |
STRIPE_SECRET_KEY |
Stripe API key |
RESEND_API_KEY |
Email service API key |
As of December 21, 2025:
- 41 workflow runs tracked
- 64 jobs with cost data
- $0.22 total costs calculated
- 35.78 minutes billable time
- spec-cost-calculation.md - Cost calculation logic
- spec-data-lifecycle.md - Data retention
- spec-error-handling.md - Error handling