Forums

How to get streaming working on PythonAnywhere?

Hi - I've been trying to get some performance improvements working on my site, one of which involves send back my HTML for one of my pages in chunks, so the browser can start processing it while the server does more work. The changes work locally, but seem not to work on PythonAnywhere.

Simple test case:

@app.route('/slow_test')
def slow_test():
    def generate():
        for i in range(10):
            yield f"<b>The value is {i}<b><br>"
            sleep(0.5)
    return Response(stream_with_context(generate()))

This should show the numbers appearing one at a time in the browser, and indeed this is what I see locally. Is there a reason why this would behave differently on the server?

Streaming should work. How does it not work for you? Do you see any errors in your browser dev tools?

Hi - I get a wait of just over 5s, and then all the numbers appear at once.
e.g. in chrome dev tools, hitting that endpoint on my site (https://www.spypartydebrief.com/slow_test) results in Chrome network tab showing 5.42s of waiting for the endpoint, and then 1.93ms of download.

I would expect the wait for the endpoint to be a bit over 0.5s, and then to receive the numbers one by one over about 4.5s of download time.

No errors show up in browser dev tools - the problem is just that I receive all the data together at the end, rather than receiving it as soon as possible.

You need to set headers to prevent our infrastructure from buffering. See https://www.pythonanywhere.com/forums/topic/28503/ for some discussion.

Thanks! Will read through that

It works :D :D :D Thanks a lot for that. Are there any downsides to me using that header in my responses?

It disables buffering, so if you set it on views that are not specifically streaming views, the worker will be busy for longer, because it will have to send the complete response all the way to the client, instead of sending the response to our load balancer, which is closer.