我需要我的 Flask 应用程序能够传输动态生成的文本数据。
为了测试 Flask 的流响应,我使用以下代码:
服务器端路由:
@app.route('/test_streaming')
def test_streaming():
def generate():
for i in range(100):
time.sleep(0.1)
yield str(i)
return app.response_class(generate(), mimetype='text')
客户端测试请求:
url = "http://localhost:5001/test_streaming"
s = requests.Session()
resp = s.get(url, stream=True)
for chunk in resp.iter_content():
print(chunk.decode(), end="")
它也不像我期望的那样工作,即
requests
等待发送整个响应而不是迭代流。
现在,如果我在流的每个块之后添加换行符,因此将服务器端代码更改为:
@app.route('/test_streaming')
def test_streaming():
def generate():
for i in range(100):
time.sleep(0.1)
yield f"{i}\n" # <- line break added here
return app.response_class(generate(), mimetype='text')
然后相同的客户端请求能够传输客户端生成的结果。
为什么没有换行的代码不起作用?有没有一种方法可以通过 Flask 流式传输文本而不添加换行符?
我已阅读Flask关于流式传输的文档
但我认为这不适用于我的问题,因为他们的示例仅涵盖流式传输 CSV 数据(根据定义包含换行符)或流式传输模板(我不想在这里执行此操作)
我正在使用:
我认为这是因为
requests.iter_content()
函数的行为。在文档中它说:
迭代响应数据。当在请求上设置stream=True时,这可以避免立即将内容读入内存以获得大量响应。块大小是应读入内存的字节数。这不一定是解码时返回的每个项目的长度。
所以你的函数可能是在发送数据时读取数据,一次仅读取1个字节。如果您尝试进行更多迭代,您会发现数据实际上到达不同的块(以下服务器代码示例):
@app.route('/test_streaming')
def test_streaming():
def generate():
for i in range(100000):
time.sleep(0.01)
yield str(i)
return app.response_class(generate(), mimetype='text')
至于换行符,可能是
iter_content
将换行符识别为“块终止”字符,但我不确定。