| name | fastapi-verification |
| description | Verification loop for FastAPI projects: Alembic migration checks, linting, async tests with coverage, security scans, and deployment readiness before release or PR. |
| origin | local |
FastAPI Verification Loop
Run before PRs, after major changes, and pre-deploy to ensure FastAPI application quality and security.
When to Activate
- Before opening a pull request for a FastAPI project
- After model changes, Alembic migration updates, or dependency upgrades
- Pre-deployment verification for staging or production
- Running full environment → lint → migrations → tests → security → config pipeline
Phase 1: Environment Check
python --version
which python
uv pip list --outdated
python -c "
import os
required = ['DATABASE_URL', 'SECRET_KEY']
missing = [v for v in required if not os.environ.get(v)]
if missing:
print('MISSING:', missing)
else:
print('All required env vars set')
"
If environment is misconfigured, stop and fix before proceeding.
Phase 2: Code Quality & Formatting
mypy app/ --ignore-missing-imports
ruff check . --fix
ruff format . --check
ruff format .
black . --check && black .
isort . --check-only && isort .
Common issues:
- Missing type hints on public functions (mypy)
- Unused imports, undefined names (ruff)
- Async functions not awaited
- Pydantic v1 patterns used instead of v2
Phase 3: Alembic Migrations
alembic current
alembic history --verbose
alembic check
alembic upgrade head --sql | head -50
alembic upgrade head
alembic downgrade -1
alembic upgrade head
Report:
- Current migration revision
- Any unapplied migrations
- Any ORM changes without a corresponding migration
Migration safety checklist:
Phase 4: Tests + Coverage
pytest --cov=app --cov-report=term-missing --cov-report=html
pytest -m "not slow and not integration"
pytest -v
open htmlcov/index.html
Report:
- Total: X passed, Y failed, Z skipped
- Overall coverage: XX%
- Per-module coverage breakdown
Coverage targets:
| Component | Target |
|---|
| Routers | 85%+ |
| Services | 90%+ |
| Auth / security | 90%+ |
| Schemas / validators | 80%+ |
| Overall | 80%+ |
Fail verification if overall coverage drops below 80%.
Phase 5: Security Scan
pip-audit
bandit -r app/ -f json -o bandit-report.json
bandit -r app/
gitleaks detect --source . --verbose
uv pip check
Report:
- Vulnerable packages + CVE IDs
- Bandit: HIGH/MEDIUM issues to fix, LOW to review
- Exposed secrets (should be zero; stop deployment if any found)
Auto-fail conditions:
- Any HIGH severity bandit finding
- Any known CVE with a fix available (pip-audit)
- Any hardcoded secret detected
Phase 6: Configuration Review
from app.config import get_settings
s = get_settings()
checks = {
"debug is False": not s.debug,
"secret_key is set": bool(s.secret_key),
"database_url is set": bool(s.database_url),
"cors_origins not wildcard": s.cors_origins != ["*"],
"access_token_expire set": s.access_token_expire_minutes > 0,
}
for check, result in checks.items():
icon = "✓" if result else "✗"
print(f"{icon} {check}")
Phase 7: Performance Checks
grep -rn "requests\." app/ --include="*.py" | grep -v test
grep -rn "time\.sleep" app/ --include="*.py" | grep -v test
grep -rn "lazy=" app/models/ --include="*.py"
Report:
- Sync calls in async routes (blocks the event loop)
- Relationships with unsafe lazy loading for async
Phase 8: API Schema Validation
python -c "
import json
from app.main import app
schema = app.openapi()
with open('openapi.json', 'w') as f:
json.dump(schema, f, indent=2)
print(f'Schema generated: {len(schema[\"paths\"])} paths')
"
python -c "import json; json.load(open('openapi.json')); print('Valid JSON')"
spectral lint openapi.json
Phase 9: Diff Review
git diff --stat
git diff | grep -n "print("
git diff | grep -n "TODO\|FIXME\|HACK"
git diff | grep -n "debug=True"
git diff | grep -n "password\s*=\s*['\"]"
git diff | grep -n "secret\s*=\s*['\"]"
git diff --name-only
Checklist:
Output Template
FASTAPI VERIFICATION REPORT
============================
Phase 1: Environment
✓ Python 3.12.2
✓ Virtual environment active
✓ DATABASE_URL, SECRET_KEY set
Phase 2: Code Quality
✓ mypy: no errors
✗ ruff: 2 issues (auto-fixed)
✓ ruff format: OK
Phase 3: Alembic Migrations
✓ Current: abc123 (head)
✓ No unapplied migrations
✓ alembic check: no new changes detected
✓ Downgrade/upgrade roundtrip OK
Phase 4: Tests + Coverage
Tests: 134 passed, 0 failed, 3 skipped
Coverage:
Overall: 86%
app/routers: 88%
app/services: 91%
app/auth: 94%
Phase 5: Security Scan
✓ pip-audit: no vulnerabilities
✗ bandit: 1 MEDIUM issue (B105 hardcoded_password_string — review)
✓ No secrets detected
Phase 6: Configuration
✓ debug = False
✓ secret_key set
✓ database_url set
✓ cors_origins not wildcard
✓ token expiry configured
Phase 7: Performance
✓ No sync blocking calls found
✓ Relationships using selectin loading
Phase 8: API Schema
✓ OpenAPI schema valid
✓ 18 paths exported
Phase 9: Diff Review
Files changed: 7
+210, -45 lines
✓ No debug statements
✓ No hardcoded secrets
✓ Migration included
RECOMMENDATION: ⚠️ Review bandit B105 finding before merging
NEXT STEPS:
1. Fix bandit MEDIUM finding
2. Re-run security scan
3. Merge PR
Pre-Deployment Checklist
Continuous Integration (GitHub Actions)
name: FastAPI Verification
on: [push, pull_request]
jobs:
verify:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: test_db
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@v3
- name: Install dependencies
run: uv sync
Quick Reference
| Check | Command |
|---|
| Type check | mypy app/ |
| Lint + format | ruff check . && ruff format . --check |
| Migration state | alembic current && alembic check |
| Apply migrations | alembic upgrade head |
| Tests + coverage | pytest --cov=app |
| Dependency CVEs | pip-audit |
| Security lint | bandit -r app/ |
| Secret scan | gitleaks detect --source . |
| Diff stats | git diff --stat |
Remember: Automated verification catches common issues but does not replace manual code review and staging environment testing.