gpt4 book ai didi

python - 使用 Python 和 Flask 流式传输数据

转载 作者:IT老高 更新时间:2023-10-28 21:49:18 26 4
gpt4 key购买 nike

我似乎无法弄清楚如何使用 Flask 的流媒体。这是我的代码:

@app.route('/scans/')
def scans_query():
url_for('static', filename='.*')
def generate():
yield render_template('scans.html')
for i in xrange(50):
sleep(.5)
yield render_template('scans.html', **locals())
return Response(stream_with_context(generate()))

在我的模板中:

<p>{% i %}</p>

我希望在页面上看到每半秒更改一次的计数器。相反,我得到的最接近的是在下一行打印出每个数字的页面。

最佳答案

要替换页面上的现有内容,您可能需要 javascript,即,您可以发送它或让它为您发出请求、使用长轮询、websockets 等。有很多方法可以做到这一点,这里有一个使用 server send events :

#!/usr/bin/env python
import itertools
import time
from flask import Flask, Response, redirect, request, url_for

app = Flask(__name__)

@app.route('/')
def index():
if request.headers.get('accept') == 'text/event-stream':
def events():
for i, c in enumerate(itertools.cycle('\|/-')):
yield "data: %s %d\n\n" % (c, i)
time.sleep(.1) # an artificial delay
return Response(events(), content_type='text/event-stream')
return redirect(url_for('static', filename='index.html'))

if __name__ == "__main__":
app.run(host='localhost', port=23423)

static/index.html:

<!doctype html>
<title>Server Send Events Demo</title>
<style>
#data {
text-align: center;
}
</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
if (!!window.EventSource) {
var source = new EventSource('/');
source.onmessage = function(e) {
$("#data").text(e.data);
}
}
</script>
<div id="data">nothing received yet</div>

如果连接丢失,浏览器默认在 3 秒内重新连接。如果没有更多要发送的内容,服务器可以返回 404 或仅发送 'text/event-stream' 以外的内容类型以响应下一个请求。即使服务器有更多数据,要在客户端停止,您也可以调用 source.close()

注意:如果流不是无限的,则使用其他技术(不是 SSE),例如,发送 javascript 片段来替换文本(无限 <iframe> 技术):

#!/usr/bin/env python
import time
from flask import Flask, Response

app = Flask(__name__)


@app.route('/')
def index():
def g():
yield """<!doctype html>
<title>Send javascript snippets demo</title>
<style>
#data {
text-align: center;
}
</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<div id="data">nothing received yet</div>
"""

for i, c in enumerate("hello"):
yield """
<script>
$("#data").text("{i} {c}")
</script>
""".format(i=i, c=c)
time.sleep(1) # an artificial delay
return Response(g())


if __name__ == "__main__":
app.run(host='localhost', port=23423)

我在此处内联了 html,以表明它没有更多内容(没有魔法)。这里和上面一样,但是使用了模板:

#!/usr/bin/env python
import time
from flask import Flask, Response

app = Flask(__name__)


def stream_template(template_name, **context):
# http://flask.pocoo.org/docs/patterns/streaming/#streaming-from-templates
app.update_template_context(context)
t = app.jinja_env.get_template(template_name)
rv = t.stream(context)
# uncomment if you don't need immediate reaction
##rv.enable_buffering(5)
return rv


@app.route('/')
def index():
def g():
for i, c in enumerate("hello"*10):
time.sleep(.1) # an artificial delay
yield i, c
return Response(stream_template('index.html', data=g()))


if __name__ == "__main__":
app.run(host='localhost', port=23423)

templates/index.html:

<!doctype html>
<title>Send javascript with template demo</title>
<style>
#data {
text-align: center;
}
</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<div id="data">nothing received yet</div>
{% for i, c in data: %}
<script>
$("#data").text("{{ i }} {{ c }}")
</script>
{% endfor %}

关于python - 使用 Python 和 Flask 流式传输数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13386681/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com