Skip to content
intermediate Phase 9 · Python APIs & Web

FastAPI Modern APIs

Build high-performance APIs with FastAPI, Pydantic, and async support.

1h 30m
0 problems
Topic Progress 0%

FastAPI Basics

Hello World

from fastapi import FastAPI

app = FastAPI()

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

# Run with: uvicorn main:app --reload

Path Parameters

@app.get('/items/{item_id}')
def read_item(item_id: int):
    return {'item_id': item_id}

# With validation
from typing import Optional

@app.get('/items/{item_id}')
def read_item(item_id: int, q: Optional[str] = None):
    if q:
        return {'item_id': item_id, 'q': q}
    return {'item_id': item_id}

Request Body

from pydantic import BaseModel

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

@app.post('/items/')
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.dict()}

Response Models

from pydantic import BaseModel
from typing import List

class User(BaseModel):
    id: int
    name: str
    email: str
    
    class Config:
        orm_mode = True

@app.get('/users/{user_id}', response_model=User)
def get_user(user_id: int):
    return User(id=user_id, name='Alice', email='alice@example.com')

@app.get('/users/', response_model=List[User])
def list_users():
    return [
        User(id=1, name='Alice', email='alice@example.com'),
        User(id=2, name='Bob', email='bob@example.com')
    ]

Advanced Features

Dependency Injection

from fastapi import Depends, HTTPException

# Simple dependency
def get_token(token: str = None):
    if not token:
        raise HTTPException(status_code=401, detail='No token')
    return token

@app.get('/protected/')
def protected(token: str = Depends(get_token)):
    return {'token': token}

# Class-based dependency
class CommonQueryParams:
    def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 100):
        self.q = q
        self.skip = skip
        self.limit = limit

@app.get('/items/')
def list_items(params: CommonQueryParams = Depends()):
    return params

Middleware

from fastapi import Request
import time

@app.middleware('http')
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers['X-Process-Time'] = str(process_time)
    return response

Exception Handling

from fastapi import HTTPException

@app.get('/items/{item_id}')
def read_item(item_id: int):
    if item_id == 0:
        raise HTTPException(status_code=404, detail='Item not found')
    return {'item_id': item_id}

# Custom exception handler
from fastapi.responses import JSONResponse

@app.exception_handler(ValueError)
def value_error_handler(request, exc):
    return JSONResponse(
        status_code=400,
        content={'message': str(exc)}
    )

Async Support

import asyncio

@app.get('/async/')
async def async_endpoint():
    await asyncio.sleep(1)  # Non-blocking
    return {'message': 'Async response'}

# Background tasks
from fastapi import BackgroundTasks

def send_email(email: str, message: str):
    # Send email in background
    pass

@app.post('/send-email/')
def send_email_endpoint(email: str, background_tasks: BackgroundTasks):
    background_tasks.add_task(send_email, email, 'Hello!')
    return {'message': 'Email sending started'}

Security

from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel

class Token(BaseModel):
    access_token: str
    token_type: str

oauth2_scheme = OAuth2PasswordBearer(tokenUrl='token')

@app.get('/users/me/')
def read_users_me(token: str = Depends(oauth2_scheme)):
    return {'token': token}

Project Structure

myapp/
├── main.py
├── routers/
│   ├── __init__.py
│   ├── users.py
│   └── items.py
├── models/
│   ├── __init__.py
│   └── schemas.py
├── services/
│   ├── __init__.py
│   └── user_service.py
└── dependencies.py
# routers/users.py
from fastapi import APIRouter, Depends

router = APIRouter(prefix='/users', tags=['users'])

@router.get('/')
def list_users():
    return [{'name': 'Alice'}]

# main.py
from routers import users, items

app = FastAPI()
app.include_router(users.router)
app.include_router(items.router)