如何使用 Flask 将文本流式传输到客户端而不添加换行符?

问题描述 投票:0回答:1

我需要我的 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 数据(根据定义包含换行符)或流式传输模板(我不想在这里执行此操作)

我正在使用:

  • python 3.10.11
  • 烧瓶2.3.2
python flask stream
1个回答
0
投票

我认为这是因为

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
将换行符识别为“块终止”字符,但我不确定。

© www.soinside.com 2019 - 2024. All rights reserved.