-
-
Notifications
You must be signed in to change notification settings - Fork 980
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes Request.json() Hangs Forever #944
Conversation
is there a reason nobody had a look at this yet? seems fairly straight forward and fixes an issue that we keep stumbling over. |
Any love for this issue? It's been quiet in here for months. |
is this fixed by the anyio port? |
Any updates? |
Would be really nice to see this go in so multiple calls to |
Possible to give this a closer look? @tomchristie This would close the following tickets: |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
Are there any progress or discussions going on around this? |
Required removing request body from NoResultFound handler as Starlette hangs on parsing body multiple times (see issue encode/starlette/issues/847 PR encode/starlette/pull/944).
@nikordaris Are you still interested in helping with this PR? |
I left a comment on Tom's comment. From my perspective I'm not seeing anything else for me to change with this PR. Let me know if there is anything simple I can tweak on this PR to help it get merged. As I'm no longer on this tech stack I won't likely have time to do any major modifications to this PR |
Ok. Where did you want the cache stored in the scope? In extensions? Directly on the scope? If extensions what namespace? starlette? request_cache? @tomchristie I'll do one more pass at this and then I'm done. I'm not on this tech stack anymore and cant invest any more time on this. Someone else will have to fork my PR and resubmit it with any follow-up changes. My approach will be to cache the raw stream only for body and form. If stream is used directly it will use the cache if it exists. If the stream is consumed and there is no cache then it will raise a runtime error. |
Ok, @tomchristie this is ready for review. The |
Just bumping by to mention that this is on my personal backlog at the moment, but I don't want to deal with it until I can give it some proper attention, since it's a bit of a fiddly area. Please do feel free to nudge me next week if I don't already get onto looking at it before then. |
Co-authored-by: Adrian Garcia Badaracco <[email protected]>
…into request-body-cache
Okay, so I'd been pushing back against this approach because it changes the nature of streaming the request. If we cache all the data we get when we stream a request, then we're always going to store the entire body in memory. That's find in cases where you're accessing the body (because you needed it all in memory in that cases), or in cases where you're accessing the request as JSON (because, same). Tho it's not ideal in cases where you're accessing There's an alternate approach that'd essentially be to raise an error there's an attempt to stream the request more than once but that does cache the result of However at this point, I'm kinda thinking that we should possibly just suck it up, and accept the trade-off because it results in a much simpler set of "here's what you can and can't do when repeatedly accessing the request content". Anyone? |
I think I agree with what you say, but I'm not understanding the relationship to this PR. My understanding is that currently in Starlette if you do More generally, I think it would make sense to have an API like |
@tomchristie it looks like this PR should be closed out in favor of #1519 now, correct? |
Thank you @nikordaris for his valiant effort on this!! Looking forward to seeing the resolution to this in #1519 |
This fixes #847 by using the Request scope to store consumed stream data so that new instances of Request can access the Request stream content. Previously
await Request(...).json()
followed by anotherawait Request(...).json()
would hang forever because thereceive
stream was exhausted andawait receive()
doesn't timeout after message{"more_body": False}
is received. This PR is focused only on enablingRequest.body()
,Request.form()
andRequest.json()
to return the cached data as originally intended and does not address the issue ofawait receive()
hanging forever inside ofRequest.stream()