【问题标题】:Prefered way of using Flask and S3 for large files将 Flask 和 S3 用于大文件的首选方式
【发布时间】:2016-05-20 08:37:12
【问题描述】:

我知道这有点开放,但我对申请使用 Flask 和 boto3 开发的大文件上传服务的策略/方法感到困惑。对于较小的文件,一切都很好。但是当大小超过 100 MB 时,看看你们的想法真是太好了

我的想法如下 -

a) 使用某种 AJAX 上传器将文件流式传输到 Flask 应用程序(我正在尝试构建的只是使用 Flask-Restful 的 REST 接口。使用这些组件的任何示例,例如 Flask-Restful、boto3 和流式传输文件是受欢迎的。)。上传应用程序将(我相信)成为我们正在构建的微服务平台的一部分。我不知道烧瓶应用程序前面是否会有 Nginx 代理,或者它会直接从 Kubernetes pod/service 提供。如果它是直接提供的,我是否需要在 kubernetes 和/或 Flask 层中更改大文件上传?

b) 使用直接 JS 上传器(如 http://www.plupload.com/)并将文件直接流式传输到 s3 存储桶中,完成后获取 URL 并将其传递给 Flask API 应用程序并将其存储在 DB 中。这样做的问题是,凭证需要在 JS 中的某个地方存在,这意味着安全威胁。 (不确定是否还有其他问题)

您认为其中哪些(或我根本没有考虑过的不同)是最好的方法,我在哪里可以找到一些代码示例?

提前致谢。

[编辑]

我发现了这个 - http://blog.pelicandd.com/article/80/streaming-input-and-output-in-flask,作者正在处理像我这样的类似情况,他提出了一个解决方案。但他正在打开一个已经存在于磁盘中的文件。如果我想直接上传作为 s3 存储桶中的单个对象的文件怎么办?我觉得这可以作为解决方案的基础,但不是解决方案本身。

【问题讨论】:

    标签: python rest amazon-s3 flask flask-restful


    【解决方案1】:

    您也可以使用Minio-py 客户端库,它是开源的并且与 S3 API 兼容。它为您本地处理分段上传。

    一个简单的put_object.py例子:

    import os
    
    from minio import Minio
    from minio.error import ResponseError
    
    client = Minio('s3.amazonaws.com',
                   access_key='YOUR-ACCESSKEYID',
                   secret_key='YOUR-SECRETACCESSKEY')
    
    # Put a file with default content-type.
    try:
        file_stat = os.stat('my-testfile')
        file_data = open('my-testfile', 'rb')
        client.put_object('my-bucketname', 'my-objectname', file_data, file_stat.st_size)
    except ResponseError as err:
        print(err)
    
    # Put a file with 'application/csv'
    try:
        file_stat = os.stat('my-testfile.csv')
        file_data = open('my-testfile.csv', 'rb')
        client.put_object('my-bucketname', 'my-objectname', file_data,
                          file_stat.st_size, content_type='application/csv')
    except ResponseError as err:
        print(err)
    

    您可以通过示例找到完整的 API 操作列表here

    安装 Minio-Py 库

    $ pip install minio
    

    希望对你有帮助。

    免责声明:我为Minio工作

    【讨论】:

    • minio 看起来很有希望。感谢您的指点。喜欢它是用 Go 编写的。我爱围棋。
    • 谢谢。欢迎您加入我们的社区并帮助我们。 :)
    【解决方案2】:
    1. Flask只能使用内存来保存所有的http请求体,所以据我所知没有磁盘缓冲之类的功能。
    2. Nginx 上传模块是一种非常好的大文件上传方式。该文件是here
    3. 也可以使用html5、flash发送集群文件数据,在Flask中处理数据,但是比较复杂。
    4. 尝试查找 s3 是否提供一次性令牌。

    【讨论】:

    • 你觉得我下面提出的解决方案怎么样?
    【解决方案3】:

    使用我上面发布的链接,我最终完成了以下操作。如果您认为这是一个好的解决方案,请告诉我

    import boto3
    from flask import Flask, request
    
    .
    .
    .
    
    @app.route('/upload', methods=['POST'])
    def upload():
        s3 = boto3.resource('s3', aws_access_key_id="key", aws_secret_access_key='secret', region_name='us-east-1')
        s3.Object('bucket-name','filename').put(Body=request.stream.read(CHUNK_SIZE))
    .
    .
    .
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-19
      • 1970-01-01
      • 2013-01-05
      相关资源
      最近更新 更多