[BUG] Async class method dependency raises a ValueError
See original GitHub issueDescribe the bug
If you use an async class method as a dependency, a ValueError
is thrown. It doesn’t happen for a non-async method.
Complete error: ValueError: [KeyError(<class 'coroutine'>), TypeError("'coroutine' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')]
(at fastapi/encoders.py:106
)
To Reproduce
from fastapi import Depends, FastAPI
from starlette.requests import Request
class DependencyClass:
async def async_dep(self, request: Request):
return True
def sync_dep(self, request: Request):
return True
app = FastAPI()
dependency = DependencyClass()
# Error
@app.get('/async-dep')
def async_dep(r=Depends(dependency.async_dep)):
return r
# Everything is fine
@app.get('/sync-dep')
def sync_dep(r=Depends(dependency.sync_dep)):
return r
Expected behavior The async class method dependency should be called and its return value injected.
Environment:
- OS: macOS
- FastAPI Version: 0.42.0
- Python version: 3.7.2
Additional context I believe the issue comes from here:
Indeed, inspect.isfunction(call)
will return False
in case of a class method. Hence, it is sent to run_in_threadpool
, which never awaits the coroutine, and we end up trying to serialize it instead of its result (hence the ValueError
).
Changing the check by:
if inspect.isfunction(call) or inspect.ismethod(call):
solves the issue. I can make a PR with the fix and unit tests if it helps.
Issue Analytics
- State:
- Created 4 years ago
- Comments:6 (6 by maintainers)
Top GitHub Comments
Thanks for the help here everyone! 👏 🙇
Thanks for reporting back and closing the issue @frankie567 👍 And thanks for the PR/fix! 🎉
This makes sense to me; @frankie567 I think it’s worth a PR.