Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork8.3k
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
First Check
Commit to Help
Example Codefrom __future__importannotationsfromtypingimportAnnotatedfromfastapiimportDepends,FastAPI,Requestapp=FastAPI()defget_dependency()->str:return"injected_value"# FAILS: Callable instanceclassCallableAuth:def__init__(self,privileges:list[str]):self.privileges=privilegesasyncdef__call__(self,request:Request,dep:Annotated[str,Depends(get_dependency)]):# ...do auth workreturn {"dep":dep}# WORKS: Plain functionasyncdeffunction_auth(request:Request,dep:Annotated[str,Depends(get_dependency)]):return {"dep":dep}@app.get("/class")asyncdefwith_class(auth:Annotated[dict,Depends(CallableAuth(["SUPER_ADMIN","ADMIN"]))]):returnauth# Fails: Field required for 'dep' (treated as query param)@app.get("/function")asyncdefwith_function(auth:Annotated[dict,Depends(function_auth)]):returnauth# Works correctly Description
Submit a cURL to test the endpoint, Response: {"detail": [ {"type":"missing","loc": ["query","request" ],"msg":"Field required","input":null }, {"type":"missing","loc": ["query","dep" ],"msg":"Field required","input":null } ]}Operating SystemWindows Operating System DetailsNo response FastAPI Version0.118.0 Pydantic Version2.11.10 Python VersionPython 3.13.3 Additional ContextContextI discovered a bug in FastAPI's dependency injection system that affects callable instances when using The IssueWhen passing a callable instance (an object with Root CauseIn defget_typed_signature(call:Callable[...,Any])->inspect.Signature:signature=inspect.signature(call)globalns=getattr(call,"__globals__", {})# Returns {} for instances! The problem:
Proposed Fixdefget_typed_signature(call:Callable[...,Any])->inspect.Signature:signature=inspect.signature(call)globalns=getattr(call,"__globals__", {})# For callable instances, get __globals__ from the __call__ methodifnotglobalnsandhasattr(call,"__call__"):globalns=getattr(call.__call__,"__globals__", {})typed_params= [inspect.Parameter(name=param.name,kind=param.kind,default=param.default,annotation=get_typed_annotation(param.annotation,globalns), )forparaminsignature.parameters.values() ]typed_signature=inspect.Signature(typed_params)returntyped_signature This fix:
Why This Matters
TestingI've verified the fix resolves the issue. I'm happy to submit a PR with test cases if you'd like. |
BetaWas this translation helpful?Give feedback.
All reactions
Replies: 2 comments
-
Hey@aliikamel , Your explanation regarding Since you already have the fix and the test case identified,please do submit that PR! 🚀 It is a very valid fix, especially given that In the meantime, for anyone else facing this issue who needs an immediate workaround without modifying FastAPI source code, you can manually assign auth_instance=CallableAuth(["SUPER_ADMIN"])# Hack: Inject globals so FastAPI can find themauth_instance.__globals__=globals()@app.get("/class")asyncdefwith_class(auth:Annotated[dict,Depends(auth_instance)]):pass But your proposed fix to |
BetaWas this translation helpful?Give feedback.
