将文件从 s3 Bucket 下载到 USERS 计算机 [英] Downloading a file from an s3 Bucket to the USERS computer

查看:42
本文介绍了将文件从 s3 Bucket 下载到 USERS 计算机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Download file from s3 Bucket to users computer.

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

I am working on a Python/Flask API for a React app. When the user clicks the Download button on the Front-End, I want to download the appropriate file to their machine.

导入boto3s3 = boto3.resource('s3')s3.Bucket('mybucket').download_file('hello.txt', '/tmp/hello.txt')

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

I am currently using some code that finds the path of the downloads folder and then plugging that path into download_file() as the second parameter, along with the file on the bucket that they are trying to download.

这在本地工作,并且测试运行良好,但在部署后我遇到了问题.代码会找到SERVER的下载路径,并在那里下载文件.

This worked locally, and tests ran fine, but I run into a problem once it is deployed. The code will find the downloads path of the SERVER, and download the file there.

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

What is the best way to approach this? I have researched and cannot find a good solution for being able to download a file from the s3 bucket to the users downloads folder. Any help/advice is greatly appreciated.

推荐答案

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

You should not need to save the file to the server. You can just download the file into memory, and then build a Response object containing the file.

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)

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

This is ok for small files, there won't be any meaningful wait time for the user. However with larger files, this well affect UX. The file will need to be completely downloaded to the server, then download to the user. So to fix this issue, use the Range keyword argument of the get_object method:

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 文件进行了测试.

This will download the file in 1MB chunks and send them to the user as they are downloaded. Both of these have been tested with a 40MB .txt file.

这篇关于将文件从 s3 Bucket 下载到 USERS 计算机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆