gpt4 book ai didi

python - 将文件从 s3 Bucket 下载到 USERS 计算机

转载 作者:行者123 更新时间:2023-12-04 17:31:35 27 4
gpt4 key购买 nike

目标

将文件从 s3 Bucket 下载到用户计算机。

语境

我正在为 React 应用程序开发 Python/Flask API。当用户单击前端上的下载按钮时,我想将适当的文件下载到他们的机器上。

我试过的
import boto3
s3 = boto3.resource('s3')
s3.Bucket('mybucket').download_file('hello.txt', '/tmp/hello.txt')

我目前正在使用一些代码来查找下载文件夹的路径,然后将该路径插入 download_file() 作为第二个参数,以及他们尝试下载的存储桶上的文件。

这在本地工作,并且测试运行良好,但是一旦部署就遇到了问题。该代码将找到 SERVER 的下载路径,并在那里下载文件。

问题

解决这个问题的最佳方法是什么?我已经研究过但找不到能够将文件从 s3 存储桶下载到用户下载文件夹的好的解决方案。非常感谢任何帮助/建议。

最佳答案

您不需要将文件保存到服务器。您可以将文件下载到内存中,然后构建一个 Response包含文件的对象。

from flask import Flask, Response
from boto3 import client

app = Flask(__name__)


def get_client():
return client(
's3',
'us-east-1',
aws_access_key_id='id',
aws_secret_access_key='key'
)


@app.route('/blah', methods=['GET'])
def index():
s3 = get_client()
file = s3.get_object(Bucket='blah-test1', Key='blah.txt')
return Response(
file['Body'].read(),
mimetype='text/plain',
headers={"Content-Disposition": "attachment;filename=test.txt"}
)


app.run(debug=True, port=8800)

这对于小文件来说没问题,用户不会有任何有意义的等待时间。然而,对于较大的文件,这会影响用户体验。该文件需要完全下载到服务器,然后下载给用户。因此,要解决此问题,请使用 Range get_object 的关键字参数方法:
from flask import Flask, Response
from boto3 import client

app = Flask(__name__)


def get_client():
return client(
's3',
'us-east-1',
aws_access_key_id='id',
aws_secret_access_key='key'
)


def get_total_bytes(s3):
result = s3.list_objects(Bucket='blah-test1')
for item in result['Contents']:
if item['Key'] == 'blah.txt':
return item['Size']


def get_object(s3, total_bytes):
if total_bytes > 1000000:
return get_object_range(s3, total_bytes)
return s3.get_object(Bucket='blah-test1', Key='blah.txt')['Body'].read()


def get_object_range(s3, total_bytes):
offset = 0
while total_bytes > 0:
end = offset + 999999 if total_bytes > 1000000 else ""
total_bytes -= 1000000
byte_range = 'bytes={offset}-{end}'.format(offset=offset, end=end)
offset = end + 1 if not isinstance(end, str) else None
yield s3.get_object(Bucket='blah-test1', Key='blah.txt', Range=byte_range)['Body'].read()


@app.route('/blah', methods=['GET'])
def index():
s3 = get_client()
total_bytes = get_total_bytes(s3)

return Response(
get_object(s3, total_bytes),
mimetype='text/plain',
headers={"Content-Disposition": "attachment;filename=test.txt"}
)


app.run(debug=True, port=8800)

这将以 1MB 的块下载文件,并在下载时将它们发送给用户。这两个都已经过 40MB 的测试 .txt文件。

关于python - 将文件从 s3 Bucket 下载到 USERS 计算机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43215889/

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