I am currently looking at the examples of checking incoming request headers provided in the FastAPI docs.
I am wondering if there is a way to implement the header check using a decorator over the routes, instead of repeating the checking code in every endpoint functions? Something like:
def check_header_api_key(func, *args, **kwargs):
@wraps(func)
def wrapper(request: Request):
if request.headers["SECRET"] != SECRET_KEY:
raise HTTPException(status_code=401, detail="Invalid client secret")
return func(request, *args, **kwargs)
return wrapper
@app.post("/course", response_model=schemas.Course, status_code=200)
@check_header_api_key
def create_course(course: schemas.CourseCreate, request: Request, db: Session = Depends(get_db)):
db_course = crud.get_course(db, course=course)
if db_course:
raise HTTPException(status_code=400, detail="This course has already been created.")
return crud.create_course(db=db, course=course)
I am familiar how should I handle the parameters into the decorator, can anyone help?
CodePudding user response:
Instead of referring directly to the app
object, you can create an APIRouter
object, and add the dependency as a dependency for the whole router:
authenticated = APIRouter(dependencies=[Depends(get_authenticated_user)])
You can then add endpoints to this router:
@authenticated.post('/course', ....)
You can compose these router objects as you wish, either directly under your app
- or as subrouters under each other:
app.include_router(authenticated)
# or with several sub routers:
authenticated_router = APIRouter(dependencies=[Depends(get_authenticated_user)])
public_router = APIRouter()
authenticated_router.include_router(courses.authenticated)
authenticated_router.include_router(users.authenticated)
public_router.include_router(users.public)
app.include_router(authenticated_router)
app.include_router(public_router)
This way you can compose and move your routers around as necessary to make them require authentication or not, and you can further expand them into admin/private/etc. routers if necessary.