Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork8.3k
Caching dependency result in APIRouter (avoid double validation on nested routers deps)#14324
-
First Check
Commit to Help
Example CodefromfastapiimportRequest,HTTPException,Depends,APIRouterfromjoseimportjwt,JWTErrorSECRET="..."ALGO="HS256"defverify_token(request:Request):ifhasattr(request.state,"user"):returnrequest.state.usertoken=request.cookies.get("access_token")ifnottoken:raiseHTTPException(status_code=401)try:payload=jwt.decode(token,SECRET,algorithms=[ALGO])exceptJWTError:raiseHTTPException(status_code=401)request.state.user=payloadreturnpayloaddefis_admin(request:Request=Depends(verify_token)):user=request.state.userifnotuser.get("is_admin"):raiseHTTPException(status_code=403)returnuserroot_router=APIRouter(prefix="",dependencies=[Depends(verify_token)])admin_router=APIRouter(prefix="/admin",dependencies=[Depends(is_admin)])root_router.include_router(admin_router) DescriptionHi! I’ve got a question regarding how dependencies are executed when using nested APIRouters. If I attach a dependency like Depends(verify_token) to the root router, I don’t have to repeat token validation in every route — which is great. This works correctly but feels redundant, since is_admin depends on verify_token anyway. The main step is in The caching workaround with request.state may work fine, but I’m wondering if this approach is recommended at all — or if there’s (or planned) a more native way to reuse the dependency results across routers without re-executing them. Operating SystemWindows Operating System Details11 FastAPI Version0.120.4 Pydantic Versionv2.11 Python Version3.11 Additional ContextNo response |
BetaWas this translation helpful?Give feedback.
All reactions
...def is_admin(request: Request = Depends(verify_token)): ...
This will not work. If you annotate parameter withRequest it's treated as special dependency and you can't useDepends with it.
Instead of storing user inrequest.state, you can just return it.
FastAPI hasinternal caching mechanism for dependencies:
fromfastapiimportFastAPI,Request,Depends,APIRouterdefverify_token(request:Request):print("verify_token called")return"payload"defis_admin(token:str=Depends(verify_token)):print("is_admin is called")return"user"root_router=APIRouter(prefix="",dependencies=[Depends(verify_token)])admin_router=APIRouter(prefix="/admin",dependen…
Replies: 1 comment 1 reply
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
This will not work. If you annotate parameter with Instead of storing user in fromfastapiimportFastAPI,Request,Depends,APIRouterdefverify_token(request:Request):print("verify_token called")return"payload"defis_admin(token:str=Depends(verify_token)):print("is_admin is called")return"user"root_router=APIRouter(prefix="",dependencies=[Depends(verify_token)])admin_router=APIRouter(prefix="/admin",dependencies=[Depends(is_admin)])@admin_router.get("/me")defread_admin_me(user:str=Depends(is_admin)):return {"admin_user":user}root_router.include_router(admin_router)app=FastAPI()app.include_router(router=root_router) Run this and you will see that despite having |
BetaWas this translation helpful?Give feedback.
All reactions
👍 1
-
Many thanks. |
BetaWas this translation helpful?Give feedback.