---
name: build-fastapi-backend
description: Scaffolds a production-ready Python API with FastAPI - a clear folder layout, Pydantic models, settings from environment variables, dependency injection for the database and auth, async routes and a first pytest suite. Use when the user wants a Python backend, a FastAPI project, a REST API or server in Python, or to tidy a messy FastAPI app.
license: MIT
compatibility: Needs Python 3.11+
metadata:
  category: backend
  tags: "python,fastapi,api,rest"
  author: johnny-bravo
  version: "1.0"
  updated: "2026-11-02"
  status: published
  aliases: "fastapi project, python api, python backend"
  source_url: "https://github.com/wshobson/agents/tree/7e2fb559cf4b824b27f1fec49fe88f7511066d26/plugins/api-scaffolding/skills/fastapi-templates"
  source_license: MIT
  copyright: "Copyright (c) 2024 Seth Hobson"
  original_author: "Seth Hobson (wshobson/agents, fastapi-templates)"
  modified: "Adapted by TheSkillVault: rewritten as a beginner build order with a smaller layout and short original code; dropped the long templates and repository-pattern examples; added secrets handling, gotchas and done-when."
  imported_on: "2026-11-02"
---

# Build a FastAPI backend

FastAPI gives you a typed Python API with automatic docs at `/docs`. Start small and keep each layer in its own folder.

## When to use
- You want a backend in Python rather than JavaScript.
- You need a REST API for a web or mobile front end.
- Your FastAPI app has grown into one big `main.py`.

## Steps
1. Create a project with a virtual environment (or `uv init`) and install `fastapi`, `uvicorn[standard]`, `pydantic-settings` and `pytest` plus `httpx`.
2. Use this layout:

```text
app/
  main.py        # creates the app, includes routers
  config.py      # Settings read from env vars
  api/           # one router file per resource
  models/        # database models
  schemas/       # Pydantic request and response models
  services/      # business logic, no HTTP code
tests/
```

3. Read settings with `pydantic-settings` from environment variables and a git-ignored `.env`.
4. Write request and response schemas first. Never return database objects straight to the client.
5. Add a database session as a dependency with `Depends(get_db)`, so tests can swap it.
6. Add auth as a dependency too (`Depends(current_user)`), and use it on every private route.
7. Use `async def` routes with an async driver, or plain `def` with a sync one. Do not mix them in one call path.
8. Raise `HTTPException` with clear status codes, and add one handler for unexpected errors.
9. Write tests with `TestClient` or `httpx.AsyncClient` and override dependencies for the database.
10. Run with `uvicorn app.main:app --reload` and check `/docs`.

```python
@router.get("/items/{item_id}", response_model=ItemOut)
async def read_item(item_id: int, db: Session = Depends(get_db), user: User = Depends(current_user)):
    item = await items.get_for_user(db, item_id, user.id)
    if item is None:
        raise HTTPException(status_code=404, detail="Item not found")
    return item
```

## Gotchas
- Calling a blocking library inside `async def` freezes the whole server. Use an async client or a sync route.
- Keep `.env` out of git and never print the database password or API keys in logs.
- Lock CORS to your front-end origins; `allow_origins=["*"]` with cookies is a security hole.
- Use migrations (Alembic) for schema changes, not `create_all` in production.

## Portability
Works with Postgres, SQLite or MySQL through SQLAlchemy or SQLModel. If you use Django or Flask instead, the same split of schemas, services and dependencies still applies.

## Example prompt
"Set up a FastAPI backend with users and items, settings from env vars, auth on private routes and pytest tests."

## Done when
- `/docs` shows every route with request and response schemas.
- Settings come from the environment; no secrets in code.
- Private routes reject requests without auth.
- `pytest` passes with the database dependency overridden.

---
Adapted from "fastapi-templates" in wshobson/agents (MIT, Copyright (c) 2024 Seth Hobson). See LICENSE.txt.
