Flask发送流作为响应

12

我正在尝试使用另一个服务器(Server#02)“代理”我的Flask服务器(我将其称为Server#01)。 它工作正常,除了一件事:当Server#01使用send_from_directory()时,我不知道如何重新发送此文件。

我的经典“代理”

result = requests.get(my_path_to_server01)
return Response(stream_with_context(result.iter_content()), 
                content_type = result.headers['Content-Type'])

使用文件响应需要花费数小时时间... 因此我尝试了许多方法。 那个有效的方法是:

result = requests.get(my_path_to_server01, stream=True)

with open('img.png', 'wb') as out_file:
    shutil.copyfileobj(result.raw, out_file)

return send_from_directory('./', 'img.png')
我想要“重定向”我的响应(“结果”变量),或者发送/复制我的文件流。无论如何,我不想使用实际的文件,因为在我看来它似乎不是正确的方式,而且我可以想象出所有可能由此引起的问题。
1个回答

27

针对您的“传统”代理,除了需要使用stream=True,并为response.iter_content()指定chunk_size外,不应该存在任何问题。

默认情况下,chunk_size为1字节,因此流式传输将非常低效,因而速度非常慢。尝试较大的块大小,例如10K,应该可以提高传输速度。以下是一些代理的代码。

import requests
from flask import Flask, Response, stream_with_context

app = Flask(__name__)

my_path_to_server01 = 'http://localhost:5000/'

@app.route("/")
def streamed_proxy():
    r = requests.get(my_path_to_server01, stream=True)
    return Response(r.iter_content(chunk_size=10*1024),
                    content_type=r.headers['Content-Type'])

if __name__ == "__main__":
    app.run(port=1234)

在这里,您甚至不需要使用stream_with_context(),因为您不需要在由iter_content()返回的生成器中访问请求上下文。


我正在寻找“chunk_size=10*1024”。没有它,我的客户端需要108秒才能加载小于1mb的图片。现在只需要121毫秒。流不是必需的,我使用它错误了。谢谢你的帮助。 - Benjamin K
1
@BenjaminK:如果你有大文件,流式传输会对你有所帮助。我正在测试一个大于1GB的文件。在1MB文件上不会注意到影响。 - mhawke
非常感谢!这解决了我的流媒体速度慢的问题。 - chiragzq

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接