7 min read

Mastering FastAPI: Dependency Injection & Background Tasks

The Power of Dependencies in FastAPI

One of FastAPI's most powerful features is its built-in Dependency Injection (DI) system. It drastically reduces code duplication, simplifies testing, and makes your endpoints incredibly clean.

What is Dependency Injection?

In FastAPI, a dependency is just a function that returns a value or performs an action. You declare it in your endpoint parameters using the `Depends()` function.

Example: Database Sessions

Managing database connections can be tricky. You want to ensure a session is created per request and properly closed when the request finishes.

from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from .database import SessionLocal
from . import crud, models

app = FastAPI()

# Dependency
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.get("/users/{user_id}", response_model=models.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
    user = crud.get_user(db, user_id=user_id)
    if user is None:
        raise HTTPException(status_code=404, detail="User not found")
    return user

Notice the `yield` statement. FastAPI understands this is a generator. It will run the code before the `yield`, pass the `db` object to the route handler, and execute the `finally` block after the response is sent.

Background Tasks

FastAPI also makes it trivial to fire off background tasks without needing a heavy message broker like Celery for simple operations (e.g., sending an email after registration).

from fastapi import BackgroundTasks, FastAPI

app = FastAPI()

def send_welcome_email(email: str, message: str):
    # Simulate sending an email
    with open("email_log.txt", "a") as log:
        log.write(f"Email sent to {email}: {message}\n")

@app.post("/register/")
async def register_user(email: str, background_tasks: BackgroundTasks):
    # Save user to DB...
    
    # Add task to the background queue
    background_tasks.add_task(send_welcome_email, email, "Welcome to our platform!")
    
    return {"message": "User registered. Welcome email is on the way."}

By combining DI with Background Tasks, you can build modular, testable, and highly responsive APIs in Python with minimal effort.