No time to waste, let’s get started 🏃♂️
1. Dependency Injection:
FastAPI lets you define “dependencies” that get resolved and injected into your path operations. Use this feature for common tasks like database connections or user authentication.
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/users/{user_id}")
def read_user(user_id: int, db: Session = Depends(get_db)):
user = db.query(User).get(user_id)
return user
2. Response Model:
Declare your response structure with Pydantic models. This auto-generates your API documentation and validates the response data.
class User(BaseModel):
id: int
name: str
@app.get("/users/{user_id}", response_model=User)
def read_user(user_id: int): ...
3. HTTPException:
Throw HTTPException with the status code and the detail message to handle different HTTP status codes.
@app.get("/items/{item_id}")
def read_item(item_id: str):
if item_id not in items:
raise HTTPException(status_code=404, detail="Item not found")
return {"item": items[item_id]}
4. Path Parameters and Converters:
Convert path parameters into desired Python data types using converters.
@app.get("/items/{item_id}")
def read_item(item_id: int):
...
5. Background Tasks:
Delegate long running tasks to the background to free up your API response times.
@app.post("/send-notification/{email}")
async def send_notification(email: str, background_tasks: BackgroundTasks):
background_tasks.add_task(send_email, email=email)
return {"message": "Notification sent in the background"}
6. Query Parameters and String Validations:
Use Query for declaring string query parameters and validations.
@app.get("/items/")
async def read_items(q: Optional[str] = Query(None, max_length=50)):
results = {"items": [{"item_id": "Foo"}]}
if q:
results.update({"q": q})
return results
7. OAuth2 with Password (and hashing), Bearer with JWT tokens:
FastAPI comes with OAuth2 password and bearer built-in. It handles all the routes for user registration, login, and token retrieval.
@app.post("/token", response_model=Token)
def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
user = authenticate_user(fake_users_db, form_data.username, form_data.password)
if not user:
raise HTTPException(status_code=400, detail="Incorrect username or password")
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(
data={"sub": user.username}, expires_delta=access_token_expires
)
return {"access_token": access_token, "token_type": "bearer"}
8. Data validation and serialization with Pydantic:
FastAPI uses Pydantic for all its data validation and serialization, providing a simple way to handle errors and complex types.
class Item(BaseModel):
name: str
description: str
@app.post("/items/")
async def create_item(item: Item):
return item
9. Testing with Starlette’s TestClient:
FastAPI is built on Starlette, allowing you to use Starlette’s TestClient for writing concise test cases.
from starlette.testclient import TestClient
def test_read_main():
client = TestClient(app)
response = client.get("/")
assert response.status_code == 200
10. Automatic interactive API documentation:
FastAPI comes with automatic interactive API documentation through Swagger UI and ReDoc. Just visit /docs
or /redoc
routes to access these.