Skip to main content

What is FastAPI

FastAPI is a modern Python web framework for building APIs that combines speed, automatic documentation, and strong type safety into a single ergonomic package. Released in 2018 by Sebastián Ramírez, it has become one of the most starred Python projects on GitHub.

Learning Focus

By the end of this lesson you can: describe FastAPI's architecture, explain why it generates OpenAPI docs automatically, and confidently choose it over Flask or Django for API-first projects.

The Problem FastAPI Solves

Building APIs in Flask or Django requires significant boilerplate: manual validation, hand-written serializers, separately maintained API documentation, and no enforcement that your docs match your actual code. As the codebase grows, these gaps cause bugs and maintenance debt.

FastAPI's core insight: your Python type hints are your contract. Write them once, and FastAPI generates validators, serializers, and OpenAPI documentation automatically.

How FastAPI Works

FastAPI is built on two libraries:

  • Starlette — the ASGI web framework that handles routing, middleware, WebSockets, and HTTP primitives
  • Pydantic — the data validation library that reads your type hints and enforces them at runtime

When you annotate a route function parameter with a Pydantic model, FastAPI automatically:

  • Parses the incoming request JSON
  • Validates each field against the model schema
  • Returns a 422 Unprocessable Entity with detailed errors if validation fails
  • Passes a fully typed Python object to your handler

FastAPI vs Flask vs Django

FeatureFastAPIFlaskDjango / DRF
Async native✅ Built-in⚠️ Gevent/Quart only⚠️ Channels addon
Request validation✅ Pydantic automatic❌ Manual✅ Serializers (DRF)
OpenAPI generation✅ AutomaticPlugin neededdrf-spectacular
Response serialization✅ Automatic❌ Manual✅ DRF Serializers
Type safety✅ End-to-endPartial
ORM bundled❌ Choose your own✅ Django ORM
Admin panel
Performance⚡ Very fastModerateModerate
Learning curveLow-MediumLowMedium-High
note

FastAPI does not ship with an ORM or admin panel by design. Use it with SQLAlchemy, Tortoise ORM, or any other library you prefer.

What "Automatic Documentation" Means

Add one decorator. Open /docs. Your API is fully documented with request/response schemas, example payloads, and a live "Try it out" button — with zero additional code.

app/main.py
from fastapi import FastAPI
from pydantic import BaseModel

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

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

@app.post("/items/", summary="Create an item")
async def create_item(item: Item) -> Item:
return item

Visiting http://localhost:8000/docs shows:

  • POST /items/ with a JSON body schema derived from Item
  • Response schema (also Item)
  • Example payloads generated from field types

The ASGI Foundation

FastAPI uses ASGI (Asynchronous Server Gateway Interface), not the older WSGI. This distinction matters:

WSGIASGI
Async support❌ Blocking✅ Non-blocking
WebSockets
Server-Sent Events
Typical serversGunicorn + syncUvicorn / Hypercorn
warning

If you are coming from Flask or Django, never call blocking I/O (database queries, file reads, HTTP requests) without await in an async route. This stalls the entire event loop. Module 1.4 covers this in detail.

Common Pitfalls

PitfallCause / SymptomFix
"I can't find my route"Route defined after app.include_router or incorrect prefixCheck router prefix and include_router call order
422 Unprocessable Entity on every requestRequest body doesn't match the Pydantic modelRead the detail field in the response — it lists every failing field
Sync DB calls blocking the event loopUsing SQLAlchemy sync engine inside async defUse async engine (asyncpg) or run sync calls in threadpool
Docs not reflecting latest changesCached browser or stale Uvicorn processHard-refresh browser, restart Uvicorn with --reload
Pydantic v1 patterns failingMigrated to FastAPI 0.100+ which uses Pydantic v2Replace class Config with model_config = ConfigDict(...)

Hands-On Practice

explore-fastapi.sh
# 1) Install
pip install "fastapi[standard]>=0.111"

# 2) Create a minimal app
cat > explore.py << 'EOF'
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Annotated

app = FastAPI(title="Explore FastAPI")

class Greeting(BaseModel):
message: str
language: str = "en"

@app.get("/")
async def root() -> dict:
return {"hello": "world"}

@app.post("/greet")
async def greet(body: Greeting) -> Greeting:
return body
EOF

# 3) Run
uvicorn explore:app --reload

# 4) Test in another terminal
curl http://localhost:8000/
curl -X POST http://localhost:8000/greet \
-H "Content-Type: application/json" \
-d '{"message": "Bonjour", "language": "fr"}'

# 5) View the auto-generated docs
# Open: http://localhost:8000/docs

Expected output from curl root:

{"hello": "world"}

Expected output from curl greet:

{"message": "Bonjour", "language": "fr"}

What's Next