Class based callable dependencies (https://fastapi.tiangolo.com/advanced/advanced-dependencies/) don't work when used as generators with yield keyword.
class SessionScope:
def __init__(self, uri):
self.engine = create_engine(uri)
self.session_maker = scoped_session(sessionmaker(bind=self.engine))
def __call__(self):
session = self.session_maker()
try:
yield session
except:
session.rollback()
raise
finally:
self.session_maker.remove()
get_db = SessionScope('postgresql://postgres:[email protected]:5432/my_db')
@router.get('/', response_model=List[User])
def read_users(
db: Session = Depends(get_db),
skip: int = 0,
limit: int = 100,
):
"""
Retrieve users.
"""
users = crud.user.get_multi(db, skip=skip, limit=limit)
return users
Dependency must return yielded session, but now it returns __call__ generator instance
The problem lies in /fastapi/dependencies/utils.py file on line 498:
elif inspect.isgeneratorfunction(call) or inspect.isasyncgenfunction(call):
stack = request.scope.get("fastapi_astack")
if stack is None:
raise RuntimeError(
async_contextmanager_dependencies_error
) # pragma: no cover
solved = await solve_generator(
call=call, stack=stack, sub_values=sub_values
)
Paramter _call_ passed to _inspect.isgeneratorfunction_ is instance of a class instead of it's __call__ method and this function always returns False.
Maybe you will find a better solution, but replacing all calls to _inspect.isgeneratorfunction_ and inspect.isasyncgenfunction_ to:
def is_generator_callable(call: Callable) -> bool:
if inspect.ismethod(call.__call__):
call = call.__call__
return inspect.isgeneratorfunction(call)
def is_async_generator_callable(call: Callable) -> bool:
if inspect.ismethod(call.__call__):
call = call.__call__
return inspect.isasyncgenfunction(call)
returns correct results.
Got bitten by this one as well, @neriusmika would you mind making a PR with suggested changes?
This one got me too..
Thanks for the discussion here everyone! :coffee:
This was solved in https://github.com/tiangolo/fastapi/pull/1365 by @mrosales :heavy_check_mark: :tada:
It will be available in version 0.56.1 (in a couple of hours).
Assuming the original issue was solved, it will be automatically closed now. But feel free to add more comments or create new issues.
Most helpful comment
Thanks for the discussion here everyone! :coffee:
This was solved in https://github.com/tiangolo/fastapi/pull/1365 by @mrosales :heavy_check_mark: :tada:
It will be available in version
0.56.1(in a couple of hours).