Reputation: 100
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
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