pythonpython-3.xfastapipython-contextvars

ContextVar set and reset in the same function fails - created in a different context


I have this function:

async_session = contextvars.ContextVar("async_session")

async def get_async_session() -> AsyncGenerator[AsyncSession, None]:
    async with async_session_maker() as session:
        try:
            _token = async_session.set(session)
            yield session
        finally:
            async_session.reset(_token)

This fails with:

ValueError: <Token var=<ContextVar name='async_session' at 0x7e1470e00e00> at 0x7e14706d4680> was created in a different Context

How can this happen? AFAICT the only way for the Context to be changed is for a whole function call. So how can the context change during a yield?

This function is being used as a FastAPI Depends in case that makes a difference - but I can't see how it does. It's running under Python 3.8 and the version of FastAPI is equally ancient - 0.54.


Solution

  • For anyone who comes after me, the actual problem is that my generator function is not async (the example in the question is misleading). FastAPI runs async and sync dependencies in different contexts to avoid the sync dependencies holding up the async loop thread, which is why it is then cleaned up in the wrong context.