question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[BUG] Class based dependencies with __call__ don't work with yield

See original GitHub issue

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:mypass@127.0.0.1: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.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:4
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
tiangolocommented, Jun 12, 2020

Thanks for the discussion here everyone! ☕

This was solved in https://github.com/tiangolo/fastapi/pull/1365 by @mrosales ✔️ 🎉

It will be available in version 0.56.1 (in a couple of hours).

1reaction
levchikcommented, Apr 8, 2020

Got bitten by this one as well, @neriusmika would you mind making a PR with suggested changes?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Dependencies with yield - FastAPI
But it won't work. The exit code in dependencies with yield is executed after the response is sent, so Exception Handlers will have...
Read more >
How to fix nasty circular dependency issues once and for all in ...
First, this is ugly and doesn't scale. In a large code base, this will result in moving imports randomly around until stuff just...
Read more >
The Ultimate FastAPI Tutorial Part 11 - Dependency Injection ...
Dependency injection (DI) is a way for your code functions and/or classes to declare things they need to work.
Read more >
c# - Dependency Injection in Model classes (entities)
The simple and clear case would be to just have your model expect the dependencies on the constructor. That way, it is a...
Read more >
Mocking a JavaScript Class with Jest, two ways to make it easier
js. Jest is a feature-rich, batteries included testing framework. Amongst other valuable features, the ability to mock dependencies out of the ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found