0

I'm struggling in updating the stream response from Flask on a website. Firstly, I referred to the answers from this page: Display data streamed from a Flask view as it updates and I wanted to try the demo on this page. Flask:

    from flask import Response, Flask, render_template
    import time
    
    app = Flask(__name__)
    
    
    @app.route('/')
    def main():
        return render_template('index2.html')

    def generate_text_stream():
        for i in range(10):
            time.sleep(1)
            print(f"Line {i}\n")
            yield f"Line {i}\n"
    
    @app.route('/stream')
    def text_stream():
        return Response(generate_text_stream(), mimetype='text/plain')
    
    app.run(debug=False)

HTML

    <p>This is the latest output: <span id="latest"></span></p>
    <p>This is all the output:</p>
    <ul id="output"></ul>
    <script>
        var latest = document.getElementById('latest');
        var output = document.getElementById('output');
    
        var xhr = new XMLHttpRequest();
        xhr.open('GET', '/stream');
        xhr.send();
        var position = 0;
    
        function handleNewData() {
            // the response text include the entire response so far
            // split the messages, then take the messages that haven't been handled yet
            // position tracks how many messages have been handled
            // messages end with a newline, so split will always show one extra empty message at the end
            console.log(new Date());
            var messages = xhr.responseText.split('\n');
            console.log(messages);
            messages.slice(position, -1).forEach(function(value) {
                latest.textContent = value;  // update the latest value in place
                // build and append a new item to a list to log all output
                var item = document.createElement('li');
                item.textContent = value;
                output.appendChild(item);
            });
            position = messages.length - 1;
        }
    
        var timer;
        timer = setInterval(function() {
            // check the response for new data
            handleNewData();
            // stop checking once the response has ended
            if (xhr.readyState == XMLHttpRequest.DONE) {
                clearInterval(timer);
                latest.textContent = 'Done';
            }
        }, 1000);
    </script>

When I run this demo, I got unexpected behavior. The 'Line X' text print in python console in every second as expected:

enter image description here

However, the handleNewData() function (javascript) got nothing from the server and finally got all text in the last iteration:

enter image description here

I expected the 'Line X' text would be sent to the website every second. Why this behavior arise and how to fix it. A lot of thanks for any help.

Rob
  • 518
  • 1
  • 3
  • 18
Hansen Zhao
  • 27
  • 2
  • 7

1 Answers1

1

You just need to change the mimetype:

return Response(generate_text_stream(), mimetype='multipart/x-mixed-replace')

See multipart/x-mixed-replace

Rob
  • 518
  • 1
  • 3
  • 18