Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Session object doesn't work inside Flask stream_with_context function

I am creating the web app, which will process data, so I am using Server Sent Event in Flask.

I need to store session variable in a SSE function, but flask doesn't see it outside the function. Can I fix it somehow?

MWE:

server.py:

from flask import Flask, render_template, session, Response, stream_with_context
import time

app = Flask(__name__)
app.secret_key = b'132d2dcf59f9604c0b48e4e3a1a1cd19a0abf121b48a4777'

@app.route('/')
def get_page():
    return render_template('progress.html')

@app.route('/progress')
def progress():
    def generate():
        x = 0
        while x < 100:
            x = x + 10
            print(x)
            time.sleep(0.2)
            yield "data:" + str(x) + "\n\n"
        session['result'] = x
        print(session['result']) #100
    return Response(stream_with_context(generate()), mimetype= 'text/event-stream')

@app.route('/done')
def done():
    print(session['result']) #KeyError: 'result'
    return session['result']

if __name__ == '__main__':
    app.run(debug=True)

progress.html:

<!DOCTYPE html>
<html>
<head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
    <script>

    var source = new EventSource("/progress");
    source.onmessage = function(event) {
        $('.progress-bar').css('width', event.data+'%').attr('aria-valuenow', event.data);
        if (event.data >=100) {
            source.close();
            window.location = "http://127.0.0.1:5000/done"
        }
    }
    </script>
</head>
<body>
    <div class="progress" style="width: 50%; margin: 50px;">
        <div class="progress-bar progress-bar-striped active"  role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
  </div>
</div>
</body>
</html>
like image 754
sweetSTEAM Avatar asked Mar 07 '26 03:03

sweetSTEAM


1 Answers

The session is a cookie. Cookies are sent as headers. Headers are sent first in a response, before the rest of the stream is sent. You can't modify the session after beginning the response. Send whatever data you need to in the stream, and handle it on the receiving end.

like image 137
davidism Avatar answered Mar 08 '26 17:03

davidism



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!