Antler by Autoflux

Examples

Representative end-to-end code for the patterns most FastAPI applications reach for first.

Path: examples

Third-party documentation. This is independently authored analysis of the public FastAPI codebase — not the official docs, and not reviewed or endorsed by the FastAPI team.

Examples

A few representative examples of the patterns most FastAPI applications reach for. Each is deliberately minimal — real handlers add error handling, logging, and persistence on top of the same shapes.

Examples

A minimal path operation

A minimal path operation
typescript
from fastapi import FastAPI
 
app = FastAPI()
 
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
STATUSexample

item_id is a path parameter typed as int, so a request to /items/abc is rejected with a 422 before the function body ever runs; q is an optional query parameter.

Request body validation with Pydantic

Request body validation with Pydantic
typescript
from pydantic import BaseModel
 
class Item(BaseModel):
name: str
price: float
is_offer: bool | None = None
 
@app.post("/items/")
async def create_item(item: Item):
return item
STATUSexample

Declaring a Pydantic model as a parameter tells FastAPI to parse and validate the JSON request body against it, and to document its exact shape in the generated OpenAPI schema.

Dependency injection with cleanup

Dependency injection with cleanup
typescript
async def get_db():
db = Session()
try:
yield db
finally:
db.close()
 
@app.get("/users/{user_id}")
async def read_user(user_id: int, db: Session = Depends(get_db)):
return db.query(User).get(user_id)
STATUSexample

The code after yield always runs after the response is sent (or the request fails), even if the endpoint raises — FastAPI's standard pattern for any resource that needs teardown.

Background tasks

Background tasks
typescript
from fastapi import BackgroundTasks
 
def write_log(message: str):
with open("log.txt", "a") as f:
f.write(message + "\n")
 
@app.post("/notify/{email}")
async def notify(email: str, background_tasks: BackgroundTasks):
background_tasks.add_task(write_log, f"notification sent to {email}")
return {"message": "notification sent"}
STATUSexample

Background tasks run after the response has already been sent to the client, covering lightweight fire-and-forget work without needing a separate task queue.

Edge Cases

  • A request body model whose fields are all optional will still validate an empty JSON object ({}) as valid input — required-ness must be declared explicitly per field.
  • Returning a raw ORM object as a response is still validated (and filtered) against response_model, so fields not declared on the model are silently dropped rather than leaked.
  • A dependency's teardown code (after yield) runs regardless of whether the endpoint succeeded or raised, but it runs after the response has already been sent — it cannot change what the client received.