| marp | true | ||
|---|---|---|---|
| theme | gaia | ||
| class |
|
||
| author | Margit ANTAL | ||
| paginate | true |
- FastAPI’s Dependency Injection System
- Reusable Dependencies (DB session, auth)
- Modular App Structure with Routers
| Term | Context | Correct? |
|---|---|---|
| router | When defining modular endpoints using APIRouter |
✅ Yes |
| routes | When referring to individual endpoints or the list of them | ✅ Yes |
routes.py |
Common filename for defining routes (not wrong, but routers.py is clearer in modular design) |
✅ Acceptable |
- A design pattern for managing dependencies
- Promotes separation of concerns and testability
- Based on Python's
Dependsfunction - Automatically resolves dependencies at runtime
from fastapi import Depends
def get_query(q: str = None):
return q
@app.get("/items/")
def read_items(query: str = Depends(get_query)):
return {"q": query}read_items:Depends()tells FastAPI: Before calling this endpoint function, call another function first and use its return value as an argument.get_queryis a dependency ofread_items.
get_query:- Extracts the query parameter
qfrom the request. - Returns the value of
qto be used inread_items.
- Extracts the query parameter
- Decouples components: Makes it easier to change or replace components without affecting others.
- Improves testability: Allows for easier mocking of dependencies in tests.
- Promotes reusability: Common dependencies can be reused across different endpoints.
from fastapi import Depends
from sqlalchemy.orm import Session
from .database import SessionLocal
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/users/")
def read_users(db: Session = Depends(get_db)):
return db.query(User).all()get_dbfunction creates a new database session- Uses
SessionLocal(Session Factory) to create a session - Uses
yieldto provide the session to the endpoint - A function with
yieldpauses at theyieldstatement and can resume later. - Ensures the session is closed after use
Depends(get_db)injects the session into the endpoint function
from fastapi import Depends, HTTPException
def get_current_user(token: str = Depends(oauth2_scheme)):
user = verify_token(token)
if not user:
raise HTTPException(status_code=401)
return user- Scalable codebase
- Easier to maintain
- Logical grouping of features
# routers/users.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/")
def get_users():
return [{"name": "Alice"}, {"name": "Bob"}]# main.py
from fastapi import FastAPI
from routers.users import router as users_router
app = FastAPI()
app.include_router(users_router, prefix="/users")app/
├── routers/
│ ├── users.py
│ └── items.py
├── dependencies/
│ └── auth.py
├── models/
│ └── user.py
├── database.py
├── main.py
- Create a FastAPI application with:
- A dependency function
get_query_paramthat extracts a query parameterq(string) from the request. - A search endpoint
/searchthat returns{"query": q}using the dependency.
- A dependency function
-
Simulate a fake database by:
-
Creating a dependency
get_fake_db()that yields a dictionary{"users": ["alice", "bob"]}. -
Creating an endpoint
/usersthat returns the list of users using that dependency.
-
-
Write a dependency
get_current_userthat checks if a query parametertokenequals "secret". -
If the
tokenis valid, return "authenticated_user", otherwise, raise anHTTPException(401). -
Create an endpoint
/profilethat requires this dependency and returns the current user.
https://donnypeeters.com/blog/fastapi-sqlalchemy/
Link to homework Section: Practical exercises
-
FastAPI uses
Dependsfor DI -
Dependencies improve reusability and testability
-
Modular structure with APIRouter