related: How to extend the lifespan of an object under asynccontextmanager into a background task in FastAPI?
!!! note There may be some confusing behavior in this example. If you are not aware, please don't use this code directly in your project.
In this simplified app, we have a simplified Chat management system. You can imagine it like a LLM chatbox, and you request get_chat
endpoint to get streaming response from LLM. To achieve some extent of asynchronous characteristics, the client can retrieve the response in several following requests (one sentence per request), not having to wait for the whole response from LLM to finish. In practice, the response from LLM is returned in a async generator, which is iterated later in a background task. So the original request should be finished before the async generator is finished.
Meanwhile, I tried to save/load the chat sessions in a Object-Oriented way. I add save
and load
methods to interact with cache, and add a get_chat_from_cache
async context manager to get the chat session object from cache (asynccontextmanager
=wrapper that converts a async generator into something that can be used with async with
), in order to automatically manage the save/load of cache. Additionally, after the response generator is drained, we need also to save the full response to cache. This part is integrated into the async generator that is processed by the background task.
However, as you can see, the lifespan of the chat session object within asynccontextmanager
is finished before initial response to the get_chat
endpoints. But actually the object is still processed in the later process iteration of async generator, which is out of context. No error is raised, but the later changes is simply not cached.
Now I can think of two possible ways to address this issue:
- Create a new object with
get_chat_from_cache
with the same sess_id in the async generator. - Manually save to cache in the generator. Clearly this is somewhat a hack in my opinion.
# install fastapi, httpx, pytest
# My environment: fastapi==0.115.5
pip install -r requirements.txt
# run the test
# if you uncomment the hack, this would pass
pytest -svv test_app.py