1

I have below flask application that should stream JSON response

Directory structure:

server - 
        api.py
        resources -
                   stream.py

api.py

from flask import Flask
from flask_restful import Api
from resources.stream import Stream
from flask_compress import Compress

compress = Compress()
app = Flask(__name__)
compress.init_app(app)
api = Api(app)
api.add_resource(Stream, '/stream')
if __name__ == '__main__':
    app.run(debug=False,host='0.0.0.0')

stream.py in resources directory

from flask import Response, request, stream_with_context
from flask_restful import Resource

class Stream(Resource):
    def get(self):
        def generator():
            yield '{"data": ['
            #creating large number of entries for data array with yield
            yield ']}'
        resp = Response(stream_with_context(generator()), status=200, content_type='application/json')
        return resp     

I started the flask app with python3.9 api.py

I am able to get response when I hit url http://127.0.0.1:5000/stream but in network tab I can see some issues:

  1. If the response was streamed it should not have content-length
  2. The streamed response should not be in Waiting for server response state, somehow its waiting to finish whole response and then starts downloading.

Content Length Output I am getting

And below is the output that I am trying to achieve. A streamed output which would start Content Downloading and not be stuck in Waiting for server response Expected

3
  • maybe it needs some special header to inform that you stearm data. Commented Aug 8, 2022 at 10:02
  • Tried your code with flask 1.1.2 and werkzeug 1.0.1 (my current stack) worked as expected. Maybe the problem is elsewhere, did you have a look at this : stackoverflow.com/a/23648948/2307934 Commented Aug 9, 2022 at 8:37
  • Thanks for the tip regarding Content-Length, that helped me fix my issue with this. Commented Jun 17, 2023 at 16:09

2 Answers 2

0

I found the solution for the problem I faced. I was using flask_compress which was causing this issue. Removing it would stream the response as expected. Thank you for the help though.

Sign up to request clarification or add additional context in comments.

Comments

0

For me, I had some code in my after_request function that called response.data, essentially:

def after_request(response):
    logging.info(response.data)

Apparently, doing this will convert the stream back into a normal response, for example setting Content-Length and removing the Transfer-Encoding: chunked.

I changed this to the following which removed this issue.

def after_request(response):
    if response.is_streamed:
        logging.info('<STREAMED>')
    else:
        logging.info(response.data)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.