Session对象在Flask stream_with_context函数内不起作用

时间:2016-04-23 19:27:33

标签: python flask server-sent-events

我正在创建将处理数据的Web应用程序,因此我在Flask中使用Server Sent Event。

我需要在SSE函数中存储会话变量,但是烧瓶在函数外部看不到它。我能以某种方式解决它吗?

MWE:

server.py:

/*
  Based on:
  1. http://stephen.io/mediaqueries
  2. https://css-tricks.com/snippets/css/media-queries-for-standard-devices/
*/

/* iPhone 6 in portrait & landscape */
@media only screen 
and (min-device-width : 375px) 
and (max-device-width : 667px) {
  
}

/* iPhone 6 in landscape */
@media only screen 
and (min-device-width : 375px) 
and (max-device-width : 667px) 
and (orientation : landscape) {
  
}

/* iPhone 6 in portrait */
@media only screen 
and (min-device-width : 375px) 
and (max-device-width : 667px) 
and (orientation : portrait) {
  
}

/* iPhone 6 Plus in portrait & landscape */
@media only screen 
and (min-device-width : 414px) 
and (max-device-width : 736px) {
  
}

/* iPhone 6 Plus in landscape */
@media only screen 
and (min-device-width : 414px) 
and (max-device-width : 736px) 
and (orientation : landscape) {
  
}

/* iPhone 6 Plus in portrait */
@media only screen 
and (min-device-width : 414px) 
and (max-device-width : 736px) 
and (orientation : portrait) {
  
}

/* iPhone 5 & 5S in portrait & landscape */
@media only screen 
and (min-device-width : 320px) 
and (max-device-width : 568px) {
  
}

/* iPhone 5 & 5S in landscape */
@media only screen 
and (min-device-width : 320px) 
and (max-device-width : 568px) 
and (orientation : landscape) {
  
}

/* iPhone 5 & 5S in portrait */
@media only screen 
and (min-device-width : 320px) 
and (max-device-width : 568px) 
and (orientation : portrait) {
  
}

/* 
  iPhone 2G, 3G, 4, 4S Media Queries
  It's noteworthy that these media queries are also the same for iPod Touch generations 1-4.
*/

/* iPhone 2G-4S in portrait & landscape */
@media only screen 
and (min-device-width : 320px) 
and (max-device-width : 480px) {
  
}

/* iPhone 2G-4S in landscape */
@media only screen 
and (min-device-width : 320px) 
and (max-device-width : 480px) 
and (orientation : landscape) {
  
}

/* iPhone 2G-4S in portrait */
@media only screen 
and (min-device-width : 320px) 
and (max-device-width : 480px) 
and (orientation : portrait) {
  
}

/* iPad in portrait & landscape */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px)  {
  
}

/* iPad in landscape */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) 
and (orientation : landscape) {
  
}

/* iPad in portrait */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) 
and (orientation : portrait) {
  
}

/* Galaxy S3 portrait and landscape */
@media screen 
  and (device-width: 320px) 
  and (device-height: 640px) 
  and (-webkit-device-pixel-ratio: 2) {

}

/* Galaxy S3 portrait */
@media screen 
  and (device-width: 320px) 
  and (device-height: 640px) 
  and (-webkit-device-pixel-ratio: 2) 
  and (orientation: portrait) {

}

/* Galaxy S3 landscape */
@media screen 
  and (device-width: 320px) 
  and (device-height: 640px) 
  and (-webkit-device-pixel-ratio: 2) 
  and (orientation: landscape) {

}

/* Galaxy S4 portrait and landscape */
@media screen 
  and (device-width: 320px) 
  and (device-height: 640px) 
  and (-webkit-device-pixel-ratio: 3) {

}

/* Galaxy S4 portrait */
@media screen 
  and (device-width: 320px) 
  and (device-height: 640px) 
  and (-webkit-device-pixel-ratio: 3) 
  and (orientation: portrait) {

}

/* Galaxy S4 landscape */
@media screen 
  and (device-width: 320px) 
  and (device-height: 640px) 
  and (-webkit-device-pixel-ratio: 3) 
  and (orientation: landscape) {

}

/* Galaxy S5 portrait and landscape */
@media screen 
  and (device-width: 360px) 
  and (device-height: 640px) 
  and (-webkit-device-pixel-ratio: 3) {

}

/* Galaxy S5 portrait */
@media screen 
  and (device-width: 360px) 
  and (device-height: 640px) 
  and (-webkit-device-pixel-ratio: 3) 
  and (orientation: portrait) {

}

/* Galaxy S5 landscape */
@media screen 
  and (device-width: 360px) 
  and (device-height: 640px) 
  and (-webkit-device-pixel-ratio: 3) 
  and (orientation: landscape) {

}

/* HTC One portrait and landscape */
@media screen 
  and (device-width: 360px) 
  and (device-height: 640px) 
  and (-webkit-device-pixel-ratio: 3) {

}

/* HTC One portrait */
@media screen 
  and (device-width: 360px) 
  and (device-height: 640px) 
  and (-webkit-device-pixel-ratio: 3) 
  and (orientation: portrait) {

}

/* HTC One landscape */
@media screen 
  and (device-width: 360px) 
  and (device-height: 640px) 
  and (-webkit-device-pixel-ratio: 3) 
  and (orientation: landscape) {

}

/*
  iPad 3 & 4 Media Queries
  If you're looking to target only 3rd and 4th generation Retina iPads 
  (or tablets with similar resolution) to add @2x graphics,
  or other features for the tablet's Retina display, use the following media queries.
*/

/* Retina iPad in portrait & landscape */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px)
and (-webkit-min-device-pixel-ratio: 2) {
  
}

/* Retina iPad in landscape */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) 
and (orientation : landscape)
and (-webkit-min-device-pixel-ratio: 2) {
  
}

/* Retina iPad in portrait */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) 
and (orientation : portrait)
and (-webkit-min-device-pixel-ratio: 2) {
  
}

/*
  iPad 1 & 2 Media Queries
  If you're looking to supply different graphics or choose different typography 
  for the lower resolution iPad display, the media queries below will work 
  like a charm in your responsive design!
*/

/* iPad 1 & 2 in portrait & landscape */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) 
and (-webkit-min-device-pixel-ratio: 1) {
  
}

/* iPad 1 & 2 in landscape */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) 
and (orientation : landscape)
and (-webkit-min-device-pixel-ratio: 1) {
  
}

/* iPad 1 & 2 in portrait */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) 
and (orientation : portrait) 
and (-webkit-min-device-pixel-ratio: 1) {
  
}

/* iPad mini in portrait & landscape */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px)
and (-webkit-min-device-pixel-ratio: 1) {
  
}

/* iPad mini in landscape */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) 
and (orientation : landscape)
and (-webkit-min-device-pixel-ratio: 1) {

}

/* iPad mini in portrait */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) 
and (orientation : portrait)
and (-webkit-min-device-pixel-ratio: 1) {
  
}

/* Galaxy Tab 10.1 portrait and landscape */
@media
  (min-device-width: 800px) 
  and (max-device-width: 1280px) {

}

/* Galaxy Tab 10.1 portrait */
@media 
  (max-device-width: 800px) 
  and (orientation: portrait) { 

}

/* Galaxy Tab 10.1 landscape */
@media 
  (max-device-width: 1280px) 
  and (orientation: landscape) { 

}

/* Asus Nexus 7 portrait and landscape */
@media screen 
  and (device-width: 601px) 
  and (device-height: 906px) 
  and (-webkit-min-device-pixel-ratio: 1.331) 
  and (-webkit-max-device-pixel-ratio: 1.332) {

}

/* Asus Nexus 7 portrait */
@media screen 
  and (device-width: 601px) 
  and (device-height: 906px) 
  and (-webkit-min-device-pixel-ratio: 1.331) 
  and (-webkit-max-device-pixel-ratio: 1.332) 
  and (orientation: portrait) {

}

/* Asus Nexus 7 landscape */
@media screen 
  and (device-width: 601px) 
  and (device-height: 906px) 
  and (-webkit-min-device-pixel-ratio: 1.331) 
  and (-webkit-max-device-pixel-ratio: 1.332) 
  and (orientation: landscape) {

}

/* Kindle Fire HD 7" portrait and landscape */
@media only screen 
  and (min-device-width: 800px) 
  and (max-device-width: 1280px) 
  and (-webkit-min-device-pixel-ratio: 1.5) {

}

/* Kindle Fire HD 7" portrait */
@media only screen 
  and (min-device-width: 800px) 
  and (max-device-width: 1280px) 
  and (-webkit-min-device-pixel-ratio: 1.5) 
  and (orientation: portrait) {
    
}

/* Kindle Fire HD 7" landscape */
@media only screen 
  and (min-device-width: 800px) 
  and (max-device-width: 1280px) 
  and (-webkit-min-device-pixel-ratio: 1.5) 
  and (orientation: landscape) {

}

/* Kindle Fire HD 8.9" portrait and landscape */
@media only screen 
  and (min-device-width: 1200px) 
  and (max-device-width: 1600px) 
  and (-webkit-min-device-pixel-ratio: 1.5) {

}

/* Kindle Fire HD 8.9" portrait */
@media only screen 
  and (min-device-width: 1200px) 
  and (max-device-width: 1600px) 
  and (-webkit-min-device-pixel-ratio: 1.5) 
  and (orientation: portrait) {
    
}

/* Kindle Fire HD 8.9" landscape */
@media only screen 
  and (min-device-width: 1200px) 
  and (max-device-width: 1600px) 
  and (-webkit-min-device-pixel-ratio: 1.5) 
  and (orientation: landscape) {

}

/* Laptops non-retina screens */
@media screen 
  and (min-device-width: 1200px) 
  and (max-device-width: 1600px) 
  and (-webkit-min-device-pixel-ratio: 1) {
    
}

/* Laptops retina screens */
@media screen 
  and (min-device-width: 1200px) 
  and (max-device-width: 1600px) 
  and (-webkit-min-device-pixel-ratio: 2)
  and (min-resolution: 192dpi) {
    
}

/* Apple Watch */
@media
  (max-device-width: 42mm)
  and (min-device-width: 38mm) { 

}

/* Moto 360 Watch */
@media 
  (max-device-width: 218px)
  and (max-device-height: 281px) { 

}

progress.html:

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)

1 个答案:

答案 0 :(得分:1)

会话是一个cookie。 Cookie以标头形式发送。在发送其余流之前,首先在响应中发送标头。开始响应后,您无法修改会话。在流中发送您需要的任何数据,并在接收端处理它。