fastapi-app
Build or fix a FastAPI backend the way this owner builds them: async SQLAlchemy
2.0 with asyncpg, Alembic migrations, Pydantic v2 settings, a layered structure
(routers, services, models, schemas), JWT auth, and the house git and CI
workflow. Deployable to a container or Vercel.
First read the shared rules (they override anything you remember):
../shared/house-rules.md, ../shared/intake.md,
../shared/no-ai-attribution.md, ../shared/git-and-ci.md,
../shared/docs-and-context.md, ../shared/hardening.md, and (for public
repos) ../shared/open-source-docs.md.
Step 0. Detect the mode, run the intake (hard stop)
Follow ../shared/intake.md exactly: detect new-app vs existing-app mode from
the directory and the user's words, then ask the matching intake batch. Do not
run any scaffolding or editing command until it is answered.
Existing-app mode: skip to ../shared/existing-app.md and follow it,
using this skill's references/ as the standard to audit against. Steps 1-5
below are for new-app mode only.
New-app mode: the intake covers brief, app type, visibility, scale, and
deploy target. The only stack variants left to settle, each with a default the
app type usually decides (ask ONLY the ones the answers leave ambiguous, in
the same batch):
- Auth: JWT via PyJWT (default), OAuth (Google), API-key, or none yet.
better-auth has no Python runtime; PyJWT is the FastAPI standard.
- Database: Postgres via async SQLAlchemy + asyncpg (default), or none yet.
- Dependency tooling:
uv (default, fast) or pip + requirements.txt.
- Admin UI: SQLAdmin, or none (default: none).
If the user already answered something in their prompt, do not re-ask.
Step 1. Verify environment and current versions
- Check Python (
python3 --version, want a current supported 3.x).
- Run
scripts/check-latest.sh for current stable versions from PyPI. Pin those,
not versions from memory (../shared/house-rules.md rule 2).
- Pull current FastAPI, SQLAlchemy 2.0, and Pydantic v2 docs via Context7 before
writing code (
../shared/docs-and-context.md). SQLAlchemy 2.0 async and
Pydantic v2 both broke v1 patterns; do not write v1-era code from memory.
Step 2. Scaffold the project
Create a virtualenv and the layout from references/structure.md. With uv:
uv init <name> && cd <name>
uv add fastapi "uvicorn[standard]" "sqlalchemy[asyncio]" asyncpg alembic \
pydantic-settings pyjwt httpx python-multipart
uv add --dev ruff pytest pytest-asyncio
With pip, install the same set and freeze into requirements.txt. Let the tool
resolve current versions; do not force numbers you remember.
Step 3. Apply structure and conventions
- Layered app structure, async DB session, dependency-injected DB, settings, JWT
auth:
references/structure.md.
- Best practices, scalable domain-modular architecture, and nothing hardcoded:
references/best-practices.md.
- Dependency set and version-boundary notes:
references/stack.md.
- Production hardening (docs and schema disabled or gated in prod, generic error
bodies, debug off, CORS locked):
../shared/hardening.md.
- The no-god-code rule and layer separation:
../shared/house-rules.md rule 8.
Step 4. Git, CI, docs, security
- Git branch model, conventional commits, auto-merge:
../shared/git-and-ci.md.
- CI (ruff + pytest), Docker, migrations:
references/quality-gates.md.
- Gitignore
.env* and any service-account JSON. Provide .env.example.
Settings load from env through pydantic-settings, never hardcoded.
- Add
docs/ and a README. For a public repo, ship the full open-source docs set
per ../shared/open-source-docs.md and run the open-source hard gate in
../shared/no-ai-attribution.md before the first push.
Step 5. Verify before declaring done
Run the gates in references/quality-gates.md: ruff check, pytest, the app
imports and starts, /health responds, and Alembic can generate a revision.
Then run the done gate in ../shared/house-rules.md rule 10 and echo each
answer. Report real results.
1---2name: fastapi-app3description: Bootstrap a new FastAPI backend, or audit and retrofit an existing one, with async SQLAlchemy 2.0, asyncpg, Alembic, Pydantic v2, and no deprecated APIs. Use when the user wants to start, scaffold, or set up a new FastAPI service, a Python REST API, an async backend, or asks to "create a new fastapi app" or "new python backend". ALSO use on an existing FastAPI or Python API codebase when the user asks to audit, review, fix, clean up, refactor, modernize, upgrade, harden, or "bring up to standard" the service, migrate off SQLAlchemy 1.x or Pydantic v1 patterns, remove deprecated APIs, or improve the structure. Handles JWT auth, layered app structure, Docker + Postgres, and Vercel or container deploy.4---56# fastapi-app78Build or fix a FastAPI backend the way this owner builds them: async SQLAlchemy92.0 with asyncpg, Alembic migrations, Pydantic v2 settings, a layered structure10(routers, services, models, schemas), JWT auth, and the house git and CI11workflow. Deployable to a container or Vercel.1213First read the shared rules (they override anything you remember):14`../shared/house-rules.md`, `../shared/intake.md`,15`../shared/no-ai-attribution.md`, `../shared/git-and-ci.md`,16`../shared/docs-and-context.md`, `../shared/hardening.md`, and (for public17repos) `../shared/open-source-docs.md`.1819## Step 0. Detect the mode, run the intake (hard stop)2021Follow `../shared/intake.md` exactly: detect new-app vs existing-app mode from22the directory and the user's words, then ask the matching intake batch. Do not23run any scaffolding or editing command until it is answered.2425**Existing-app mode:** skip to `../shared/existing-app.md` and follow it,26using this skill's `references/` as the standard to audit against. Steps 1-527below are for new-app mode only.2829**New-app mode:** the intake covers brief, app type, visibility, scale, and30deploy target. The only stack variants left to settle, each with a default the31app type usually decides (ask ONLY the ones the answers leave ambiguous, in32the same batch):33341. Auth: JWT via PyJWT (default), OAuth (Google), API-key, or none yet.35 better-auth has no Python runtime; PyJWT is the FastAPI standard.362. Database: Postgres via async SQLAlchemy + asyncpg (default), or none yet.373. Dependency tooling: `uv` (default, fast) or `pip` + `requirements.txt`.384. Admin UI: SQLAdmin, or none (default: none).3940If the user already answered something in their prompt, do not re-ask.4142## Step 1. Verify environment and current versions4344- Check Python (`python3 --version`, want a current supported 3.x).45- Run `scripts/check-latest.sh` for current stable versions from PyPI. Pin those,46 not versions from memory (`../shared/house-rules.md` rule 2).47- Pull current FastAPI, SQLAlchemy 2.0, and Pydantic v2 docs via Context7 before48 writing code (`../shared/docs-and-context.md`). SQLAlchemy 2.0 async and49 Pydantic v2 both broke v1 patterns; do not write v1-era code from memory.5051## Step 2. Scaffold the project5253Create a virtualenv and the layout from `references/structure.md`. With `uv`:5455```56uv init <name> && cd <name>57uv add fastapi "uvicorn[standard]" "sqlalchemy[asyncio]" asyncpg alembic \58 pydantic-settings pyjwt httpx python-multipart59uv add --dev ruff pytest pytest-asyncio60```6162With pip, install the same set and freeze into `requirements.txt`. Let the tool63resolve current versions; do not force numbers you remember.6465## Step 3. Apply structure and conventions6667- Layered app structure, async DB session, dependency-injected DB, settings, JWT68 auth: `references/structure.md`.69- Best practices, scalable domain-modular architecture, and nothing hardcoded:70 `references/best-practices.md`.71- Dependency set and version-boundary notes: `references/stack.md`.72- Production hardening (docs and schema disabled or gated in prod, generic error73 bodies, debug off, CORS locked): `../shared/hardening.md`.74- The no-god-code rule and layer separation: `../shared/house-rules.md` rule 8.7576## Step 4. Git, CI, docs, security7778- Git branch model, conventional commits, auto-merge: `../shared/git-and-ci.md`.79- CI (ruff + pytest), Docker, migrations: `references/quality-gates.md`.80- Gitignore `.env*` and any service-account JSON. Provide `.env.example`.81 Settings load from env through `pydantic-settings`, never hardcoded.82- Add `docs/` and a README. For a public repo, ship the full open-source docs set83 per `../shared/open-source-docs.md` and run the open-source hard gate in84 `../shared/no-ai-attribution.md` before the first push.8586## Step 5. Verify before declaring done8788Run the gates in `references/quality-gates.md`: `ruff check`, `pytest`, the app89imports and starts, `/health` responds, and Alembic can generate a revision.90Then run the done gate in `../shared/house-rules.md` rule 10 and echo each91answer. Report real results.