Skip to content

Add fastapi-postgres-app template#236

Open
sysopmatt wants to merge 1 commit into
databricks:mainfrom
sysopmatt:add-fastapi-postgres-app
Open

Add fastapi-postgres-app template#236
sysopmatt wants to merge 1 commit into
databricks:mainfrom
sysopmatt:add-fastapi-postgres-app

Conversation

@sysopmatt

@sysopmatt sysopmatt commented Jun 8, 2026

Copy link
Copy Markdown

Summary

Adds a fastapi-postgres-app/ template — a minimal FastAPI service that connects to a Lakebase Autoscaling (Postgres) database.

Unlike the sibling *-postgres-app templates (Flask / Dash / Streamlit) which use sync psycopg, this one uses an async stack (SQLAlchemy AsyncEngine + asyncpg) because FastAPI is async-first — sync DB drivers inside async def handlers block the event loop. Background OAuth token refresh every 50 min, no front-end.

Why

The repo has Lakebase Autoscaling templates for Flask (flask-postgres-app), Dash (dash-postgres-app), Streamlit (streamlit-postgres-app), and Node.js (appkit-lakebase) — but no FastAPI equivalent. Customers building Python REST/async backends on Databricks Apps have been copy-pasting from the apps-cookbook.dev FastAPI + Lakebase recipe, which is written against Lakebase Provisioned. This template fills that gap and adapts the recipe for Autoscaling (w.postgres.generate_database_credential(endpoint=...) instead of the Provisioned credential call).

Conventions

Matches the existing *-postgres-app peers where it makes sense:

  • postgres_spec in manifest.yaml, resource key postgres, permission CAN_CONNECT_AND_CREATE
  • Endpoint resource path injected via PGENDPOINT env var (valueFrom: postgres in app.yaml)
  • requirements.txt for deps (web-app family uses requirements.txt; agent/MCP family uses pyproject.toml)
  • databricks-sdk>=0.81.0 aligned with peers

Justified divergences (FastAPI-idiomatic):

  • Async DB stack (asyncpg + SQLAlchemy AsyncEngine) — peers are sync
  • Modern FastAPI lifespan (@asynccontextmanager) for engine init / token-refresh task
  • APIRouter + structured layout (config/, routes/) — peers are flat
  • Pydantic response models on the health endpoints (LivenessResponse, ReadinessResponse) for OpenAPI/Swagger clarity
  • Depends(get_async_db) wiring on /api/health to demonstrate the per-request session pattern users will extend
  • Background 50-min token refresh rather than per-connection lazy regeneration — fewer mint calls, single hot path

Layout

fastapi-postgres-app/
├── main.py                FastAPI entrypoint + lifespan
├── config/database.py     Lakebase connection + token refresh + Depends helper
├── routes/health.py       /healthz, /api/health
├── manifest.yaml          Resource binding (postgres_spec)
├── app.yaml               uvicorn + PGENDPOINT valueFrom
├── requirements.txt
└── .env.example           Local dev only

Customer flow on Databricks Apps

  1. Create the app
  2. Settings → Resources → Add resource: Lakebase Autoscaling project, permission Can connect and create, resource key postgres
  3. Deploy

The resource binding auto-injects PG* env vars and app.yaml's valueFrom: postgres populates PGENDPOINT. No manual env config needed for deploy.

Routes

Method Path Hits Postgres? Description
GET / No Hello world
GET /docs No OpenAPI / Swagger UI
GET /healthz No Liveness probe — process is up
GET /api/health Yes Readiness probe — round-trips SELECT 1

The Swagger UI clearly labels which endpoint touches the DB and which doesn't.

The README also includes a Postman service-principal recipe (Client Credentials grant) for exercising the deployed API.

What this template intentionally doesn't include

Kept minimal as a starting point — no front-end, no application table queries, no writes, no user-authorized queries (connects as the app SP), no Alembic migrations.

Minimal FastAPI service that connects to a Lakebase Autoscaling
(Postgres) database. Async stack (SQLAlchemy AsyncEngine + asyncpg),
background OAuth token refresh every 50 minutes, no front-end.

Pairs with the apps-cookbook.dev FastAPI + Lakebase recipe, adapted for
Autoscaling — uses w.postgres.generate_database_credential(endpoint=...)
instead of the Provisioned variant.

Layout:
  fastapi-postgres-app/
  ├── main.py                FastAPI entrypoint + lifespan
  ├── config/database.py     Lakebase connection + token refresh
  ├── routes/health.py       /healthz, /api/health
  ├── manifest.yaml          Resource binding (postgres_spec)
  ├── app.yaml               uvicorn + PGENDPOINT valueFrom
  ├── requirements.txt
  └── .env.example           Local dev only

Customer flow on Databricks Apps:
  1. Create the app
  2. Settings → Resources → Add resource: Lakebase Autoscaling project,
     Permission 'Can connect and create', Resource key 'postgres'
  3. Deploy

The resource binding auto-injects PG* env vars and app.yaml's
`valueFrom: postgres` populates PGENDPOINT. No manual env config needed
for deploy.

Naming and conventions match the existing peer templates
(flask-postgres-app, dash-postgres-app, streamlit-postgres-app):
`postgres_spec` in manifest, resource key `postgres`, env var
`PGENDPOINT`, requirements.txt for deps.

Fills a gap: the repo had flask/dash/streamlit-postgres-app and
appkit-lakebase (Node.js) but no FastAPI equivalent for Lakebase
Autoscaling.

README also includes a Postman service-principal recipe for exercising
the deployed API.
@sysopmatt
sysopmatt force-pushed the add-fastapi-postgres-app branch from 5240d47 to 1d6d863 Compare June 8, 2026 21:52
@sysopmatt
sysopmatt marked this pull request as ready for review June 8, 2026 21:58
@sysopmatt

Copy link
Copy Markdown
Author

Heads up on the base README.md — the Database section currently only lists the *-database-app (Provisioned) templates. The existing *-postgres-app (Autoscaling) family — flask-postgres-app, dash-postgres-app, streamlit-postgres-app — isn't indexed there either, so this PR doesn't add a row for fastapi-postgres-app to avoid making a scope decision unilaterally.

Happy to add a row for this template (or fill in the whole Autoscaling family) if you'd like.

@LuuOW LuuOW left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technical audit: Implementation verified for system consistency and engineering integrity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants