sweetSTEAM
sweetSTEAM

Reputation: 100

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>

Upvotes: 3

Views: 914

Answers (1)

davidism
davidism

Reputation: 127320

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.

Upvotes: 2

Related Questions