FastAPI
This skill provides comprehensive guidance for building APIs with FastAPI.
Quick Navigation
| Topic |
Reference |
| Getting started |
references/first-steps.md |
| Path parameters |
references/path-parameters.md |
| Query parameters |
references/query-parameters.md |
| Request body |
references/request-body.md |
| Validation |
references/validation.md |
| Body advanced |
references/body-advanced.md |
| Cookies/Headers |
references/cookies-headers.md |
| Pydantic models |
references/models.md |
| Forms/Files |
references/forms-files.md |
| Error handling |
references/error-handling.md |
| Path config |
references/path-config.md |
| Dependencies |
references/dependencies.md |
| Security |
references/security.md |
| Middleware |
references/middleware.md |
| CORS |
references/cors.md |
| Database |
references/sql-databases.md |
| Project structure |
references/bigger-applications.md |
| Background tasks |
references/background-tasks.md |
| Metadata/Docs |
references/metadata-docs.md |
| Testing |
references/testing.md |
| Advanced responses |
references/responses-advanced.md |
| WebSockets |
references/websockets.md |
| Templates |
references/templates.md |
| Settings/Env vars |
references/settings.md |
| Lifespan events |
references/lifespan.md |
| OpenAPI advanced |
references/openapi-advanced.md |
When to Use
- Creating REST APIs with Python
- Adding endpoints with automatic validation
- Implementing OAuth2/JWT authentication
- Working with Pydantic models
- Adding dependency injection
- Configuring CORS, middleware
- Uploading files, handling forms
- Testing API endpoints
Installation
Requires Python 3.10+. Install: pip install "fastapi[standard]" (full with uvicorn) or pip install fastapi (minimal). Add python-multipart for forms/files.
Release Highlights (0.139.2 -> 0.141.1)
- Frontend dev experience (
0.141.0): check_dir on app.frontend() now defaults to "auto", which skips the frontend-directory existence check (with a warning) when FASTAPI_ENV=development and enforces it otherwise. fastapi dev sets FASTAPI_ENV=development automatically unless already set, so running the dev server before the frontend is built no longer raises an error.
- Frontend fixes (
0.141.1): background tasks and response headers produced by dependencies used on frontend routes (dependency support was added in 0.139.0) are now applied correctly instead of being silently dropped. FASTAPI_ENV is documented in the FastAPI CLI guide.
- Dependency-injection memory refactor (
0.140.0 – 0.140.7): internal dependency trees are no longer repeatedly flattened for OpenAPI generation, request-parameter resolution, and body-field handling, reducing memory use in large applications; the internal lru_cache limit for dependency resolution was also raised to fit bigger apps. This is an internal optimization with no required code changes.
- Streaming fixes (
0.140.8 – 0.140.13): include_router() no longer loses the declared stream item type from a nested router's yield-based endpoints; response_model_* params (e.g. response_model_exclude) are now honored on plain (non-generator) endpoints that return an Iterable[Model], not only on yield-based ones; status_code set on SSE/JSONL streaming endpoints is now honored instead of always returning 200; a dedicated API reference page for fastapi.sse was added.
jsonable_encoder fix (0.140.9): exclude_defaults now propagates into dict keys and values, not only into top-level model fields.
Release Highlights (0.137.0 -> 0.139.2)
- Frontend serving (
0.138.0): app.frontend("/", directory="dist") serves a built static frontend directly from the FastAPI app. 0.139.0 adds dependencies support in app.frontend(), enabling automatic cookie authentication for frontends, and 0.139.1 fixes fallback for dotted paths like /users/john.doe.
- Router internals (
0.137.0): include_router() now preserves APIRouter/APIRoute instances instead of cloning routes, so routes added after inclusion are reflected automatically and memory use drops. Custom APIRouter/APIRoute subclasses gain .matches()/.handle() (alpha) for advanced routing.
- Thread safety (
0.139.2): route building is refactored to be thread-safe, mainly relevant for tests running across parallel threads.
Release Highlights (0.133.0 → 0.136.1)
- 0.134.0: streaming JSON Lines and streaming binary data support using
yield.
- 0.135.0: first-class Server-Sent Events (SSE) support (
EventSourceResponse).
- 0.135.1: fix around
TaskGroup usage in request async exit stack (stability fix).
- 0.136.1: FastAPI updates its Pydantic v2 code to avoid deprecations and bumps Starlette to
1.0.0.
Patch Notes (0.136.2 → 0.136.3)
- SSE responses now validate event fields more strictly, so malformed
ServerSentEvent payloads fail earlier instead of quietly streaming invalid frames.
- Header parameters no longer accept underscore-named incoming headers when
convert_underscores=True (the default). If a client truly sends underscore headers, declare Header(convert_underscores=False) and verify that your proxy chain allows them.
Quick Start
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
Run: fastapi dev main.py
Core Patterns
Type-Safe Parameters
from typing import Annotated
from fastapi import Path, Query
@app.get("/items/{item_id}")
def read_item(
item_id: Annotated[int, Path(ge=1)],
q: Annotated[str | None, Query(max_length=50)] = None
):
return {"item_id": item_id, "q": q}
Request Body with Validation
from pydantic import BaseModel, Field
class Item(BaseModel):
name: str = Field(min_length=1, max_length=100)
price: float = Field(gt=0)
@app.post("/items/", response_model=Item)
def create_item(item: Item):
return item
Dependencies
from fastapi import Depends
async def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/users/")
def list_users(db: Annotated[Session, Depends(get_db)]):
return db.query(User).all()
Authentication
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
return decode_token(token)
@app.get("/users/me")
def read_me(user: Annotated[User, Depends(get_current_user)]):
return user
API Documentation
- Swagger UI:
/docs
- ReDoc:
/redoc
- OpenAPI:
/openapi.json
Best Practices
- Use
Annotated[Type, ...] for parameters
- Define Pydantic models for request/response
- Use
response_model for output filtering
- Add
status_code for proper HTTP codes
- Use
tags for API organization
- Add
dependencies at router/app level for auth
Prohibitions
- ❌ Return raw database models (use response models)
- ❌ Store passwords in plain text (use bcrypt/passlib)
- ❌ Mix
Body with Form/File in same endpoint
- ❌ Use sync blocking I/O in async endpoints
- ❌ Skip HTTPException for error handling
Links
1---2name: fastapi3description: FastAPI Python framework. Covers REST APIs, validation, dependencies, security. Use when building Python web APIs with FastAPI, configuring Pydantic models, implementing dependency injection, or setting up OAuth2/JWT authentication. Keywords: FastAPI, Pydantic, async, OAuth2, JWT, REST API.4---5
6# FastAPI
7
8This skill provides comprehensive guidance for building APIs with FastAPI.
9
10## Quick Navigation
11
12| Topic | Reference |
13| ------------------ | ----------------------------------- |
14| Getting started | `references/first-steps.md` |
15| Path parameters | `references/path-parameters.md` |
16| Query parameters | `references/query-parameters.md` |
17| Request body | `references/request-body.md` |
18| Validation | `references/validation.md` |
19| Body advanced | `references/body-advanced.md` |
20| Cookies/Headers | `references/cookies-headers.md` |
21| Pydantic models | `references/models.md` |
22| Forms/Files | `references/forms-files.md` |
23| Error handling | `references/error-handling.md` |
24| Path config | `references/path-config.md` |
25| Dependencies | `references/dependencies.md` |
26| Security | `references/security.md` |
27| Middleware | `references/middleware.md` |
28| CORS | `references/cors.md` |
29| Database | `references/sql-databases.md` |
30| Project structure | `references/bigger-applications.md` |
31| Background tasks | `references/background-tasks.md` |
32| Metadata/Docs | `references/metadata-docs.md` |
33| Testing | `references/testing.md` |
34| Advanced responses | `references/responses-advanced.md` |
35| WebSockets | `references/websockets.md` |
36| Templates | `references/templates.md` |
37| Settings/Env vars | `references/settings.md` |
38| Lifespan events | `references/lifespan.md` |
39| OpenAPI advanced | `references/openapi-advanced.md` |
40
41## When to Use
42
43- Creating REST APIs with Python
44- Adding endpoints with automatic validation
45- Implementing OAuth2/JWT authentication
46- Working with Pydantic models
47- Adding dependency injection
48- Configuring CORS, middleware
49- Uploading files, handling forms
50- Testing API endpoints
51
52## Installation
53
54Requires Python 3.10+. Install: `pip install "fastapi[standard]"` (full with uvicorn) or `pip install fastapi` (minimal). Add `python-multipart` for forms/files.
55
56## Release Highlights (0.139.2 -> 0.141.1)
57
58- **Frontend dev experience (`0.141.0`)**: `check_dir` on `app.frontend()` now defaults to `"auto"`, which skips the frontend-directory existence check (with a warning) when `FASTAPI_ENV=development` and enforces it otherwise. `fastapi dev` sets `FASTAPI_ENV=development` automatically unless already set, so running the dev server before the frontend is built no longer raises an error.
59- **Frontend fixes (`0.141.1`)**: background tasks and response headers produced by dependencies used on frontend routes (dependency support was added in `0.139.0`) are now applied correctly instead of being silently dropped. `FASTAPI_ENV` is documented in the FastAPI CLI guide.
60- **Dependency-injection memory refactor (`0.140.0` – `0.140.7`)**: internal dependency trees are no longer repeatedly flattened for OpenAPI generation, request-parameter resolution, and body-field handling, reducing memory use in large applications; the internal `lru_cache` limit for dependency resolution was also raised to fit bigger apps. This is an internal optimization with no required code changes.
61- **Streaming fixes (`0.140.8` – `0.140.13`)**: `include_router()` no longer loses the declared stream item type from a nested router's `yield`-based endpoints; `response_model_*` params (e.g. `response_model_exclude`) are now honored on plain (non-generator) endpoints that `return` an `Iterable[Model]`, not only on `yield`-based ones; `status_code` set on SSE/JSONL streaming endpoints is now honored instead of always returning 200; a dedicated API reference page for `fastapi.sse` was added.
62- **`jsonable_encoder` fix (`0.140.9`)**: `exclude_defaults` now propagates into dict keys and values, not only into top-level model fields.
63
64## Release Highlights (0.137.0 -> 0.139.2)
65
66- **Frontend serving (`0.138.0`)**: `app.frontend("/", directory="dist")` serves a built static frontend directly from the FastAPI app. `0.139.0` adds dependencies support in `app.frontend()`, enabling automatic cookie authentication for frontends, and `0.139.1` fixes fallback for dotted paths like `/users/john.doe`.
67- **Router internals (`0.137.0`)**: `include_router()` now preserves `APIRouter`/`APIRoute` instances instead of cloning routes, so routes added after inclusion are reflected automatically and memory use drops. Custom `APIRouter`/`APIRoute` subclasses gain `.matches()`/`.handle()` (alpha) for advanced routing.
68- **Thread safety (`0.139.2`)**: route building is refactored to be thread-safe, mainly relevant for tests running across parallel threads.
69
70## Release Highlights (0.133.0 → 0.136.1)
71
72- **0.134.0:** streaming JSON Lines and streaming binary data support using `yield`.
73- **0.135.0:** first-class Server-Sent Events (SSE) support (`EventSourceResponse`).
74- **0.135.1:** fix around `TaskGroup` usage in request async exit stack (stability fix).
75- **0.136.1:** FastAPI updates its Pydantic v2 code to avoid deprecations and bumps Starlette to `1.0.0`.
76
77## Patch Notes (0.136.2 → 0.136.3)
78
79- SSE responses now validate event fields more strictly, so malformed `ServerSentEvent` payloads fail earlier instead of quietly streaming invalid frames.
80- Header parameters no longer accept underscore-named incoming headers when `convert_underscores=True` (the default). If a client truly sends underscore headers, declare `Header(convert_underscores=False)` and verify that your proxy chain allows them.
81
82## Quick Start
83
84```python
85from fastapi import FastAPI
86
87app = FastAPI()
88
89@app.get("/")
90def read_root():
91 return {"Hello": "World"}
92
93@app.get("/items/{item_id}")
94def read_item(item_id: int, q: str | None = None):
95 return {"item_id": item_id, "q": q}
96```
97
98Run: `fastapi dev main.py`
99
100## Core Patterns
101
102### Type-Safe Parameters
103
104```python
105from typing import Annotated
106from fastapi import Path, Query
107
108@app.get("/items/{item_id}")
109def read_item(
110 item_id: Annotated[int, Path(ge=1)],
111 q: Annotated[str | None, Query(max_length=50)] = None
112):
113 return {"item_id": item_id, "q": q}
114```
115
116### Request Body with Validation
117
118```python
119from pydantic import BaseModel, Field
120
121class Item(BaseModel):
122 name: str = Field(min_length=1, max_length=100)
123 price: float = Field(gt=0)
124
125@app.post("/items/", response_model=Item)
126def create_item(item: Item):
127 return item
128```
129
130### Dependencies
131
132```python
133from fastapi import Depends
134
135async def get_db():
136 db = SessionLocal()
137 try:
138 yield db
139 finally:
140 db.close()
141
142@app.get("/users/")
143def list_users(db: Annotated[Session, Depends(get_db)]):
144 return db.query(User).all()
145```
146
147### Authentication
148
149```python
150from fastapi.security import OAuth2PasswordBearer
151
152oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
153
154async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
155 return decode_token(token)
156
157@app.get("/users/me")
158def read_me(user: Annotated[User, Depends(get_current_user)]):
159 return user
160```
161
162## API Documentation
163
164- Swagger UI: `/docs`
165- ReDoc: `/redoc`
166- OpenAPI: `/openapi.json`
167
168## Best Practices
169
170- Use `Annotated[Type, ...]` for parameters
171- Define Pydantic models for request/response
172- Use `response_model` for output filtering
173- Add `status_code` for proper HTTP codes
174- Use `tags` for API organization
175- Add `dependencies` at router/app level for auth
176
177## Prohibitions
178
179- ❌ Return raw database models (use response models)
180- ❌ Store passwords in plain text (use bcrypt/passlib)
181- ❌ Mix `Body` with `Form`/`File` in same endpoint
182- ❌ Use sync blocking I/O in async endpoints
183- ❌ Skip HTTPException for error handling
184
185## Links
186
187- [Documentation](https://fastapi.tiangolo.com/)
188- [Releases](https://github.com/fastapi/fastapi/releases)
189- [GitHub](https://github.com/fastapi/fastapi)
190- [PyPI](https://pypi.org/project/fastapi/)