FastAPI Cheat Sheet

This page contains a condensed overview of FastAPI. It covers installing and running an app, routes and HTTP methods, path and query parameters, request bodies, responses and errors, dependencies, the interactive docs, and testing with TestClient. You can also download the information as a printable cheat sheet:

Free Bonus: FastAPI Cheat Sheet

Get a FastAPI Cheat Sheet (PDF) and keep routes, parameters, request bodies, dependencies, and testing patterns at your fingertips:

FastAPI Cheat Sheet

Practice with hands-on coding exercises, quizzes, and guided learning paths. Not sure where to begin? Start here.

New to FastAPI?

Install and Run

  • Install inside a virtual environment
  • [standard] adds the fastapi CLI and Uvicorn
  • dev auto-reloads on save; run is for production
Language: Shell Filename: Install FastAPI
$ python -m pip install "fastapi[standard]"
Language: Python Filename: Create a Minimal App (main.py)
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def home():
    return {"message": "Hello, FastAPI!"}
Language: Shell Filename: Start the Server
$ fastapi dev main.py
$ fastapi run main.py
$ uvicorn main:app --reload --port 8000

Setting up your first API?

Routes and HTTP Methods

  • Returned dicts, lists, and models become JSON
  • Use async def for I/O-bound work
Language: Python Filename: Map Methods to Operations
@app.get("/books")         # Read all
@app.post("/books")        # Create
@app.get("/books/{id}")    # Read one
@app.put("/books/{id}")    # Replace
@app.patch("/books/{id}")  # Update
@app.delete("/books/{id}") # Delete

Sync or async endpoints?

Path and Query Parameters

  • {name} in the path makes a path parameter
  • Other args are query parameters; defaults make them optional
  • Bad types return 422 automatically
  • Declare fixed paths like /books/new before /books/{book_id}
Language: Python Filename: Path Parameter
@app.get("/books/{book_id}")
def get_book(book_id: int):
    return {"id": book_id}

# GET /books/42  -> {"id": 42}
# GET /books/abc -> 422
Language: Python Filename: Query Parameters
@app.get("/books")
def list_books(
    limit: int = 10,
    q: str | None = None,
):
    return {"limit": limit, "q": q}

# GET /books?limit=5&q=py
# -> {"limit": 5, "q": "py"}
Language: Python Filename: Add Constraints
from typing import Annotated
from fastapi import Query

Limit = Annotated[int, Query(ge=1, le=100)]

@app.get("/items")
def items(limit: Limit = 10):
    return {"limit": limit}

# GET /items?limit=0 -> 422

What happens to a bad value?

Request Bodies

  • A Pydantic model argument reads the JSON body
  • Field() adds validation and docs
  • Invalid bodies get a 422 before your code runs
  • Mix path, query, and body parameters freely
Language: Python Filename: Define a Model
from pydantic import BaseModel, Field

class Book(BaseModel):
    title: str = Field(min_length=1)
    pages: int = Field(gt=0)
    author: str | None = None
Language: Python Filename: Accept a JSON Body
@app.post("/books")
def create_book(book: Book):
    return book

# {"title": "Python Basics", "pages": 635}
# -> {..., "author": null}

Think you’ve got request bodies down?

Responses and Errors

  • response_model filters out extra fields
  • A return type hint works the same way
  • status.HTTP_201_CREATED names the code 201
  • raise an HTTPException, don’t return it
Language: Python Filename: Filter the Output
class BookOut(BaseModel):
    id: int
    title: str

@app.post(
    "/books",
    response_model=BookOut,
    status_code=201,
)
def create_book(book: Book):
    return {"id": 1, **book.model_dump()}
# 201 {"id": 1, "title": "..."}
Language: Python Filename: Raise an HTTP Error
from fastapi import HTTPException

@app.get("/books/{book_id}")
def get_book(book_id: int):
    if book_id not in books:
        raise HTTPException(
            status_code=404,
            detail="Book not found",
        )
    return books[book_id]

# 404 {"detail": "Book not found"}

Why raise and not return?

Dependencies

  • Depends() runs a function before the endpoint
  • Code after yield runs after the response
  • Dependencies can take their own parameters
Language: Python Filename: Share Query Parameters
from fastapi import Depends

def paginate(skip: int = 0, limit: int = 10):
    return {"skip": skip, "limit": limit}
Page = Annotated[dict, Depends(paginate)]

@app.get("/books")
def list_books(page: Page):
    return page
Language: Python Filename: Open and Close a Resource
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.get("/users")
def users(db=Depends(get_db)):
    return db.query(User).all()

Still fuzzy on dependencies?

Interactive Docs

  • Built from your type hints; Try it out sends real requests
URL Shows
/docs Swagger UI playground
/redoc ReDoc reference
/openapi.json Raw OpenAPI schema
Language: Python Filename: Name Your API
app = FastAPI(title="Books", version="1.0")

Want to document your API well?

Testing With TestClient

  • TestClient calls your app without a server
  • Run the tests with pytest
Language: Python Filename: Test an Endpoint (test_main.py)
from fastapi.testclient import TestClient
from main import app

client = TestClient(app)

def test_create_book():
    response = client.post(
        "/books",
        json={"title": "Py", "pages": 1},
    )
    assert response.status_code == 201
    assert response.json()["title"] == "Py"
Language: Python Filename: Swap In a Fake Dependency
def fake_db():
    return FakeSession()

app.dependency_overrides[get_db] = fake_db

Ready to test yourself on testing?

Ready to go beyond the cheat sheet?

You can download this information as a printable cheat sheet:

Free Bonus: FastAPI Cheat Sheet

Get a FastAPI Cheat Sheet (PDF) and keep routes, parameters, request bodies, dependencies, and testing patterns at your fingertips:

FastAPI Cheat Sheet