gpt4 book ai didi

python - 如何使用 Python 和 Flask 转发 HTTP 范围请求?

转载 作者:行者123 更新时间:2023-12-03 21:52:16 63 4
gpt4 key购买 nike

我有一个 Flask 应用程序,它将提供一个端点来下载一个大文件。但是,不是从文件系统提供它或即时生成文件,而是必须首先通过 HTTP 从另一台服务器下载该文件。
当然,我可以先向外部服务器执行 GET 请求,完整下载文件并将其存储在文件系统或内存中,然后作为第二步提供原始请求的结果。这看起来像这样(还包括一个基本的身份验证,以表明为什么在较低层上的简单代理是不够的):

#!flask/bin/python
from flask import Flask, jsonify
import os
import requests
from requests.auth import HTTPBasicAuth

app = Flask(__name__)

@app.route('/download')
def download():
auth = HTTPBasicAuth("some_user", "some_password")
session = requests.Session()
session.auth = auth
response = session.get("http://example.com")
return response.content

if __name__ == '__main__':
app.run(host='0.0.0.0', port=1234, debug=True)
但是,这会增加应用程序的延迟和存储要求。而且,即使接收方只需要执行文件的部分下载(即执行 HTTP 范围请求),也必须首先从外部服务器完全获取文件。
有没有更优雅的选择来解决这个问题,即为直接转发到外部服务器的 HTTP 范围请求提供支持?

最佳答案

根据 Proxying to another web service with Flask , Download large file in python with requestsFlask large file download我设法在流模式下制作了一个 Flask HTTP 代理。

from flask import Flask, request, Response
import requests

PROXY_URL = 'http://ipv4.download.thinkbroadband.com/'

def download_file(streamable):
with streamable as stream:
stream.raise_for_status()
for chunk in stream.iter_content(chunk_size=8192):
yield chunk


def _proxy(*args, **kwargs):
resp = requests.request(
method=request.method,
url=request.url.replace(request.host_url, PROXY_URL),
headers={key: value for (key, value) in request.headers if key != 'Host'},
data=request.get_data(),
cookies=request.cookies,
allow_redirects=False,
stream=True)

excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
headers = [(name, value) for (name, value) in resp.raw.headers.items()
if name.lower() not in excluded_headers]

return Response(download_file(resp), resp.status_code, headers)


app = Flask(__name__)

@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def download(path):
return _proxy()

if __name__ == '__main__':
app.run(host='0.0.0.0', port=1234, debug=True)
download_file()将以流模式打开请求,并在流传输后立即生成每个块。 _proxy()创建请求,然后创建并返回 Flask Response使用迭代器 download_file()作为内容。
我用 https://www.thinkbroadband.com/download 测试了它几个存档文件可以免费下载用于测试目的。 (小心,文件已损坏,因此您最好使用校验和来确保您获得了预期的文件)。
一些例子:
curl 'http://0.0.0.0:1234/100MB.zip' --output /tmp/100MB.zip
curl 'http://0.0.0.0:1234/20MB.zip' --output /tmp/20MB.zip
我还在随机网站上进行了一些其他测试以获得大图像。到目前为止,我没有遇到任何问题。

关于python - 如何使用 Python 和 Flask 转发 HTTP 范围请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62552660/

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