Skip to content

FastAPI API Reference & Cheatsheet

DodaTech Updated Jun 6, 2026 4 min read

FastAPI is a modern, fast (high-performance) Python web framework for building APIs with Python 3.7+ based on standard Python type hints. This reference covers everything you need for daily FastAPI development.

What’s in This Reference

  • Basic application setup and path operations
  • Pydantic models for request/response validation
  • Dependency injection system
  • Security and authentication patterns
  • WebSocket support
  • Testing with TestClient
  • Deployment with Uvicorn
    flowchart TD
    A["Request"] --> B["Path Operation"]
    B --> C["Dependencies"]
    C --> D["Pydantic Validation"]
    D --> E["Route Handler"]
    E --> F["Response"]
    style A fill:#dbeafe,stroke:#3b82f6,color:#1e3a5f
    style B fill:#fef3c7,stroke:#f59e0b,color:#78350f
    style D fill:#d1fae5,stroke:#10b981,color:#064e3b
    style F fill:#dbeafe,stroke:#3b82f6,color:#1e3a5f
  
Prerequisite: This is a reference, not a tutorial. You should already understand Python type hints and REST API concepts. For tutorials, see FastAPI.

Basic Setup

from fastapi import FastAPI

app = FastAPI(title="My API", version="1.0.0")

@app.get("/")
def read_root():
    return {"message": "Hello World"}

Path Operations

from fastapi import FastAPI, Path, Query

@app.get("/items/{item_id}")
def read_item(
    item_id: int = Path(gt=0, description="The item ID"),
    q: str | None = Query(None, max_length=50),
    skip: int = Query(0, ge=0),
    limit: int = Query(10, ge=1, le=100),
):
    return {"item_id": item_id, "q": q, "skip": skip, "limit": limit}

@app.post("/items/", status_code=201)
def create_item(item: Item):
    return item

@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
    return {"item_id": item_id, **item.model_dump()}

@app.delete("/items/{item_id}", status_code=204)
def delete_item(item_id: int):
    return None

Pydantic Models

Pydantic handles request validation and serialization. Define models with type hints:

from pydantic import BaseModel, EmailStr, Field
from datetime import datetime

class Item(BaseModel):
    name: str = Field(min_length=1, max_length=100)
    price: float = Field(gt=0)
    description: str | None = None
    is_offer: bool = False
    tags: list[str] = []

class User(BaseModel):
    email: EmailStr
    username: str = Field(min_length=3, max_length=50)
    password: str = Field(min_length=8)

class Order(BaseModel):
    user: User
    items: list[Item]
    created_at: datetime = datetime.now()

# Nested models are validated recursively
# FastAPI generates OpenAPI docs automatically

Dependency Injection

Dependencies let you share logic across endpoints:

from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

# Database dependency
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

# Auth dependency
async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = verify_token(token)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid credentials",
        )
    return user

# Use dependencies in endpoints
@app.get("/users/me")
def read_users_me(
    current_user = Depends(get_current_user),
    db = Depends(get_db)
):
    return current_user

# Class-based dependencies
class Pagination:
    def __init__(self, skip: int = Query(0), limit: int = Query(10)):
        self.skip = skip
        self.limit = limit

@app.get("/items/")
def list_items(pagination: Pagination = Depends()):
    return {"skip": pagination.skip, "limit": pagination.limit}

Async Support

@app.get("/async-data")
async def get_async_data():
    # Non-blocking call — frees the server for other requests
    data = await fetch_from_database()
    return data

@app.get("/sync-data")
def get_sync_data():
    # Blocking call — simple but can block the server
    data = fetch_from_database_sync()
    return data

WebSocket Support

from fastapi import WebSocket, WebSocketDisconnect

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    try:
        while True:
            data = await websocket.receive_text()
            await websocket.send_text(f"Echo: {data}")
    except WebSocketDisconnect:
        print("Client disconnected")

Error Handling

from fastapi import HTTPException
from fastapi.exception_handlers import http_exception_handler

@app.get("/items/{item_id}")
def read_item(item_id: int):
    if item_id not in items:
        raise HTTPException(
            status_code=404,
            detail="Item not found",
            headers={"X-Error": "Invalid ID"},
        )
    return items[item_id]

# Custom exception handler
@app.exception_handler(ValueError)
async def value_error_handler(request, exc):
    return JSONResponse(
        status_code=400,
        content={"error": str(exc)},
    )

Testing

from fastapi.testclient import TestClient
from main import app

client = TestClient(app)

def test_read_main():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"message": "Hello World"}

def test_create_item():
    response = client.post(
        "/items/",
        json={"name": "Widget", "price": 9.99},
    )
    assert response.status_code == 201
    data = response.json()
    assert data["name"] == "Widget"

Deployment

# Install
pip install uvicorn

# Development
uvicorn main:app --reload --port 8000

# Production
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4

# With Gunicorn for process management
pip install gunicorn
gunicorn -k uvicorn.workers.UvicornWorker main:app

Common Mistakes

1. Forgetting await in Async Endpoints

@app.get("/data")
async def get_data():
    return await fetch_data()  # Missing await = no result

2. Not Validating Path Parameters

Always add validation to path params: item_id: int = Path(gt=0).

3. Mixing Sync and Async Database Calls

Use async database drivers with async endpoints. Blocking calls in async endpoints defeat the purpose.

4. Exposing Sensitive Fields in Pydantic Models

Use model_config to hide sensitive fields from serialization.

FAQ

How is FastAPI different from Flask?
FastAPI is async-first, auto-generates OpenAPI docs, validates with Pydantic, and is significantly faster. Flask is synchronous and more minimal.
Does FastAPI support both sync and async endpoints?
Yes. Declare async def for async, def for sync. FastAPI handles both transparently using thread pools for sync functions.
How does FastAPI generate automatic docs?
FastAPI reads your Pydantic models, path operation parameters, and type hints to generate OpenAPI 3.0 schemas. The docs are available at /docs (Swagger UI) and /redoc (ReDoc).

Try It Yourself

Run this basic FastAPI app:

from fastapi import FastAPI

app = FastAPI(title="My API", version="1.0.0")

@app.get("/")
def read_root():
    return {"message": "Hello World"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

Visit http://localhost:8000/docs for the auto-generated Swagger UI.

What’s Next

TopicDescriptionLink
Flask ReferenceCompare with Flaskhttps://tutorials.dodatech.com/programming-languages/python/flask/reference/
Django ReferenceCompare with Djangohttps://tutorials.dodatech.com/programming-languages/python/django/reference/
Python BasicsReview core Python conceptshttps://tutorials.dodatech.com/programming-languages/python/py-basics/
REST APIREST API design principlesREST API

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro