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.
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.