When Python developers get tired of Flask’s “casualness” and Django’s “heaviness,” FastAPI appears. Named for being “fast,” it quickly became the new favorite in the Python web development world.
What is FastAPI?#
FastAPI is a modern Python web framework created by Sebastian Ramirez in 2018. Its core characteristics are: high performance, async support, automatic documentation, and modern Python.
Understanding Through Analogy#
| Aspect | Django | Flask | FastAPI |
|---|---|---|---|
| Style | Full-stack | Micro | Modern micro-framework |
| Async | Needs extra config | Needs extra config | Native support |
| Documentation | Admin panel | Needs extra config | Auto-generated |
| Performance | Low | Medium | Very high |
| Like | Luxury car | Bicycle | Electric car |
FastAPI’s performance can rival Node.js and Go, making it one of the fastest frameworks in the Python ecosystem.
Core Features#
1. Async Support: Native async/await#
FastAPI natively supports Python’s async/await syntax:
from fastapi import FastAPI
import asyncio
app = FastAPI()
# Async path operation
@app.get("/async-data")
async def get_async_data():
# Use await for async operations
data = await fetch_data_from_api()
return data
# Sync path operation (also works)
@app.get("/sync-data")
def get_sync_data():
data = fetch_data_sync()
return data
async def fetch_data_from_api():
await asyncio.sleep(1) # Simulate async IO
return {"message": "Data fetched asynchronously"}
def fetch_data_sync():
time.sleep(1) # Simulate sync IO
return {"message": "Data fetched synchronously"}2. Type Hints: Modern Python#
FastAPI is fully based on Python type hints:
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional, List
app = FastAPI()
# Define data model
class User(BaseModel):
name: str
email: str
age: Optional[int] = None
tags: List[str] = []
# Path parameter with type hints
@app.get("/users/{user_id}")
async def get_user(user_id: int) -> User:
return User(
name="John",
email="john@example.com",
age=25,
tags=["developer", "python"]
)
# Request body
@app.post("/users")
async def create_user(user: User) -> User:
# Automatically validates data types
return user3. Auto-Generated API Documentation#
FastAPI automatically generates interactive API documentation:
- Swagger UI:
/docs - ReDoc:
/redoc
from fastapi import FastAPI
app = FastAPI(
title="My API",
description="This is a sample API",
version="1.0.0"
)
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str | None = None):
"""
Read an item
- **item_id**: Item ID
- **q**: Optional query parameter
"""
if q:
return {"item_id": item_id, "q": q}
return {"item_id": item_id}Visit http://localhost:8000/docs to see the auto-generated interactive documentation.
4. Data Validation: Pydantic#
FastAPI uses Pydantic for data validation:
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr, Field, validator
app = FastAPI()
class UserCreate(BaseModel):
username: str = Field(..., min_length=3, max_length=50)
email: EmailStr # Automatically validates email format
password: str = Field(..., min_length=8)
age: int = Field(ge=0, le=150) # Age range validation
@validator('password')
def password_strength(cls, v):
if not any(c.isupper() for c in v):
raise ValueError('Password must contain uppercase letters')
if not any(c.isdigit() for c in v):
raise ValueError('Password must contain numbers')
return v
@app.post("/users/")
async def create_user(user: UserCreate):
return {"username": user.username, "email": user.email}5. Dependency Injection: Powerful DI System#
FastAPI provides a powerful dependency injection system:
from fastapi import FastAPI, Depends, HTTPException
from typing import Annotated
app = FastAPI()
# Simulated database
fake_db = {"alice": {"email": "alice@example.com"}}
# Define dependency
async def get_current_user(token: str = Depends(lambda: "current_user")):
if token != "valid_token":
raise HTTPException(status_code=401, detail="Unauthorized")
return {"username": "alice", "email": "alice@example.com"}
# Use dependency
@app.get("/profile")
async def get_profile(user: dict = Depends(get_current_user)):
return user
# Class as dependency
class QueryParams:
def __init__(self, q: str = "default", skip: int = 0, limit: int = 10):
self.q = q
self.skip = skip
self.limit = limit
@app.get("/items")
async def read_items(params: QueryParams = Depends(QueryParams)):
return {"q": params.q, "skip": params.skip, "limit": params.limit}6. Middleware Support#
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.middleware("http")
async def add_header(request, call_next):
response = await call_next(request)
response.headers["X-Custom-Header"] = "FastAPI"
return responseWhy is FastAPI So Popular?#
1. Extremely High Performance#
FastAPI is built on Starlette (web framework) and Pydantic (data validation), with performance close to Node.js and Go:
| Framework | Requests per Second |
|---|---|
| FastAPI | 35,000+ |
| Flask | 6,000+ |
| Django | 3,000+ |
| Node.js | 30,000+ |
| Go | 50,000+ |
2. Great Developer Experience#
- Type hints: More accurate code suggestions
- Auto documentation: Save time on writing API docs
- Clear error messages: Easy to debug
3. Modern Python#
Fully based on modern Python 3.7+ features:
- Type hints
- async/await
- dataclasses
4. Perfect for Microservices#
FastAPI is perfect for building microservices:
- Lightweight
- Fast startup
- Easy to deploy
- Native async support
Use Cases#
| Scenario | Suitability | Notes |
|---|---|---|
| REST API | ⭐⭐⭐⭐⭐ | Core use case |
| Microservices | ⭐⭐⭐⭐⭐ | Lightweight and fast |
| ML/AI services | ⭐⭐⭐⭐⭐ | Python native |
| Real-time apps | ⭐⭐⭐⭐ | WebSocket support |
| Simple web apps | ⭐⭐⭐ | Can use, but Flask is simpler |
| Large full-stack apps | ⭐⭐⭐ | Can use, Django is more suitable |
Learning Path#
Beginner (1 week)#
- Master Python basics and type hints
- Understand FastAPI basics
- Learn to define path operations
- Master Pydantic models
Intermediate (1-2 weeks)#
- Deep dive into dependency injection
- Master async database operations
- Learn to use SQLModel
- Understand middleware
Advanced (continuous learning)#
- Performance optimization
- Deployment (Docker, Uvicorn)
- Testing
- Integration with other services
Comparison with Other Python Frameworks#
| Feature | FastAPI | Flask | Django |
|---|---|---|---|
| Performance | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
| Ease of use | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| Feature completeness | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ |
| Auto documentation | ⭐⭐⭐⭐⭐ | ⭐ | ⭐⭐⭐ |
| Async support | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐ |
| Best for | API, microservices | Small apps | Large full-stack |
Simply put:
- FastAPI: Best for API development, high performance, modern
- Flask: Lightweight and flexible, good for small projects
- Django: Full-stack framework, good for large projects
Common Extensions#
# Database
pip install sqlalchemy
pip install databases
pip install sqlmodel
# Authentication
pip install python-jose[cryptography]
pip install passlib[bcrypt]
# Validation
pip install email-validator
# Async
pip install uvicorn[standard]
pip install httpxSummary#
FastAPI provides Python developers with a modern, efficient API development choice:
- High performance—Close to Node.js and Go
- Native async—Fully utilize Python async/await
- Auto documentation—Save time on writing API docs
- Type hints—Better developer experience and code suggestions
- Pydantic validation—Powerful data validation capabilities
If you need to build Python APIs, especially microservices or ML/AI-related services, FastAPI is the best choice.
Next up: FastAPI uses Python, while NestJS uses TypeScript—it brings Angular’s architectural thinking to backend development. Let’s dive into this “Node.js version of Spring Boot” in the next article.
