Phase 18 of 25 · Topic 18.3

FastAPI Dependency Injection System (Depends)

1Concept

FastAPI features a powerful Dependency Injection system using `Depends()`. Dependencies can manage database session lifecycles, enforce JWT authentication, validate user roles, and compose hierarchical sub-dependencies.

2Architecture Diagram

Endpoint ---> Depends(get_current_user) ---> Depends(get_db_session) ---> Injected automatically!

3Code Example

Python 3.12
di_example = '''
from fastapi import FastAPI, Depends, HTTPException, status
from typing import Annotated

async def get_db():
    db = {"connection": "active"}
    try:
        yield db # Injects db session into route
    finally:
        pass # Cleans up db session after request finishes

async def verify_auth_token(token: str = "Bearer valid_token"):
    if not token.startswith("Bearer"):
        raise HTTPException(status_code=401, detail="Invalid auth token")
    return {"user": "admin"}

app = FastAPI()

@app.get("/secure-data")
async def secure_endpoint(
    db: Annotated[dict, Depends(get_db)],
    user: Annotated[dict, Depends(verify_auth_token)]
):
    return {"user": user["user"], "db_status": db["connection"]}
'''
print("=== Dependency Injection System ===")
print(di_example.strip())

4Expected Output

=== Dependency Injection System ===
from fastapi import FastAPI, Depends, HTTPException, status
from typing import Annotated

async def get_db():
    db = {"connection": "active"}
    try:
        yield db # Injects db session into route
    finally:
        pass # Cleans up db session after request finishes

async def verify_auth_token(token: str = "Bearer valid_token"):
    if not token.startswith("Bearer"):
        raise HTTPException(status_code=401, detail="Invalid auth token")
    return {"user": "admin"}

app = FastAPI()

@app.get("/secure-data")
async def secure_endpoint(
    db: Annotated[dict, Depends(get_db)],
    user: Annotated[dict, Depends(verify_auth_token)]
):
    return {"user": user["user"], "db_status": db["connection"]}

5Key Takeaways

  • Yield dependencies (`def get_db(): yield db`) provide automatic teardown after responses are sent.
  • Dependencies can be reused across multiple endpoints and routers.
  • Supports dependency overrides in pytest fixtures (`app.dependency_overrides[get_db] = mock_db`).