Building APIs with FastAPI
The Ferrari of Python Web Frameworks. High performance, auto-documented, and type-safe.
1. The Big Idea (ELI5)
👶 Explain Like I'm 10: The Modern Restaurant
Old frameworks (like Flask/Django) are like a Traditional Butler. They take one order, walk to the kitchen, wait for the food, and bring it back. They can only serve one person at a time per thread.
FastAPI is like a Waiter with a Tablet using Async IO.
- Async: They take an order, hit "Send to Kitchen", and immediately go to the next table while the kitchen cooks. They don't wait.
- Type Hints: The Tablet forces the customer to pick valid options. You literally cannot order a "Purple Hamburger" because the menu (Schema) rejects it instantly.
2. The Syntax: Types are NOT Optional
FastAPI uses Python's modern Type Hints to do three things at once: Validate Data, Convert Types (Serialization), and Generate Documentation.
from fastapi import FastAPI
app = FastAPI()
# Input Validation: 'item_id' MUST be an int
# Output Documentation: Returns a Dictionary
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "query": q}
# Calling /items/foo returns a standard 422 JSON Error:
# "value is not a valid integer"3. Pydantic: The Data Guardian
For complex data (like a User Registration), we define a Schema using Pydantic. This is your first line of defense against bad data.
from pydantic import BaseModel, EmailStr
class UserSignup(BaseModel):
username: str
email: EmailStr # Validates explicitly as email
age: int
is_premium: bool = False
@app.post("/users/")
async def create_user(user: UserSignup):
# If we get here, 'user' is GUARANTEED to be valid.
# No need for manual checks like "is email valid?".
# We can access data as attributes
if user.age < 18:
return {"error": "Too young"}
return {"message": f"Welcome {user.username}!"}4. The Magic: Automatic Interactive Docs
Because you used Type Hints, FastAPI writes the manual for you. Navigate to /docs to see a full Swagger UI. You can test your API endpoints directly from the browser without writing a single line of HTML.
5. Deep Dive: Dependency Injection (`Depends`)
This is FastAPI's "Killer Feature". It lets you share logic (like Auth or DB connections) across thousands of endpoints cleanly.
from fastapi import Depends, HTTPException
# 1. logical function to get current user
async def get_current_user(token: str):
if token != "secret-token":
raise HTTPException(status_code=401, detail="Unauthorized")
return {"user": "admin"}
# 2. Inject it into the route
# The route CODE will only run if dependencies succeed
@app.get("/dashboard")
async def dashboard(user: dict = Depends(get_current_user)):
return {"message": "Secret Data", "user": user}6. Deployment: The Uvicorn Engine
FastAPI is just the framework. To run it in production, you need an ASGI Server. The standard is Uvicorn (Lightning Fast).
# Development (Auto-Reload)
uvicorn main:app --reload
# Production (Multiple Workers)
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker