Support streaming response in asgi transport with asyncio #994
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I haven't written full tests for this yet and have mainly done manual testing, but I want to submit this to discussion first in order not to do unnecessary work, because there are some uncertainties in this approach.
Basically I have started to use the httpx client to be able to do HTTP requests and direct ASGI requests using the same API and it works great for that! However, when I started doing streaming requests I found out that the ASGI transport needs to read the full response before returning it, which naturally doesn't work for streaming at all.
I wrote an implementation using
asyncio
and tasks, but the problem is that this is nottrio
compatible at all. Bigger problem is that I can't figure out how to make ittrio
compatible without refactoring the wholeAsyncHTTPTransport
interface.Basically what we need to do for the streaming to work for the ASGI interface is that we first need to run the ASGI application in the background up to (but not any further than) receiving all the headers before the body is received. Then we need to construct a stream out of the following messages that contain the body and return that with the header information.
The way this needs to be done in
trio
is that we should have a higher level nursery that would create two background tasks, one for running the app and another one for waiting for the response headers to be finished. Once the response headers are fetched we would start reading the body inside the same nursery context, without closing the stream. To be honest I'm not quite sure how to do this, so I simply gave up and write onlyasyncio
support.Let me know what you think and if any of this makes any sense to you?