Python FastAPI

Tutorial 56 of 65 · pythondeck.com Python course

FastAPI is a modern, async, type-driven web framework. It uses Python type hints to validate input and generate OpenAPI docs automatically. Excellent for high-performance JSON APIs.

FastAPI builds on Starlette and Pydantic: type-annotated routes, automatic OpenAPI docs, and native async support for modern APIs and microservices.

Validation at the boundary catches bad clients early and generates interactive docs stakeholders can try.

Teams shipping JSON-first products reach for FastAPI when WebSockets, streaming, and high concurrency matter more than server-rendered HTML.

Path operations — decorators with response_model for output schema.

Dependency injection — Depends() for DB sessions, auth, settings.

Pydantic models — request/response validation v2 with clear errors.

Async routes — await DB/drivers that are async-safe.

Background tasks — lightweight post-response work; heavy jobs need queues.

Deployment — uvicorn/gunicorn with workers; reverse proxy for TLS.

OpenAPI schema drives client SDK generation—keep models stable and version breaking changes. Lifespan context managers replace startup/shutdown events for shared clients (HTTP, Redis). For CPU-bound endpoints, offload to workers; async won't parallelize Python compute.

Pair with SQLAlchemy 2 async session or repositories; test with TestClient and dependency overrides for fake DB layers.

Middleware stacks handle CORS, gzip, and trusted hosts; order matters when multiple layers touch the same response. WebSocket routes share the same dependency injection model as HTTP handlers.

Rate limiting and OAuth2 password flows have community packages—evaluate maintenance before baking custom auth.

Blocking ORM calls inside async def routes stalling the event loop.

Returning ORM objects without response_model leaking lazy relations.

No authentication on auto-generated /docs in public deployments.

Giant monolithic routers instead of APIRouter modules.

Structure app as routers + services + repositories; inject config via settings class.

Use HTTPException with consistent error body schema.

Enable CORS deliberately; avoid wildcard with credentials.

Load test with realistic payload sizes before launch.

Version OpenAPI and publish breaking-change notes when response_model fields rename.

Re-read the examples below with these ideas in mind; change variable names and inputs to match your own project.

The program below demonstrates hello fastapi. Read the comments on each line, run the code, then change names or values to see how the output shifts.

# Example: Hello FastAPI
# Run in the REPL or save as a .py file and execute with python.
from fastapi import FastAPI
app = FastAPI()

@app.get("/")
def home():
    return {"hello": "world"}

# run with:
#   uvicorn main:app --reload

This sample walks through path + query params in a small, runnable script. Paste it into the REPL or save it as a .py file before you continue to the next block.

# Example: Path + query params
# Run in the REPL or save as a .py file and execute with python.
from fastapi import FastAPI
app = FastAPI()

@app.get("/items/{item_id}")
def get_item(item_id: int, q: str | None = None):
    return {"id": item_id, "q": q}

Here is a hands-on illustration of pydantic body. Follow the inline comments first; only then execute the snippet and compare the result with what you expected.

# Example: Pydantic body
# Run in the REPL or save as a .py file and execute with python.
from fastapi import FastAPI
from pydantic import BaseModel

class Item(BaseModel):
    name: str
    price: float

app = FastAPI()

@app.post("/items")
def create(item: Item):
    return {"saved": item.model_dump()}

The program below demonstrates path params. Read the comments on each line, run the code, then change names or values to see how the output shifts.

# FastAPI uses type hints for validation and OpenAPI docs
from fastapi import FastAPI  # ASGI framework
app = FastAPI()  # application

@app.get("/items/{item_id}")  # path parameter
def read_item(item_id: int):  # auto-coerce to int
    return {"item_id": item_id}  # JSON body

@app.get("/health")  # simple probe
def health():  # no parameters
    return {"ok": True}  # status payload
# Run: uvicorn main:app --reload

This sample walks through post body in a small, runnable script. Paste it into the REPL or save it as a .py file before you continue to the next block.

# Pydantic models validate request bodies
from fastapi import FastAPI  # fastapi
from pydantic import BaseModel  # schema
app = FastAPI()  # app

class Item(BaseModel):  # request schema
    name: str  # required field
    price: float  # numeric field

@app.post("/items")  # create endpoint
def create(item: Item):  # body parsed to Item
    return {"received": item.name, "price": item.price}  # echo

« Python Django All tutorials Python Tkinter »