Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Class based dependencies with __call__ don't work with yield #1204

@nmrtv

Description

@nmrtv

Describe the bug

Class based callable dependencies (https://fastapi.tiangolo.com/advanced/advanced-dependencies/) don't work when used as generators with yield keyword.

To Reproduce

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

Expected behavior

Dependency must return yielded session, but now it returns __call__ generator instance

Additional context

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions