在Heroku上使用Amazon S3、Python和Flask

11 投票
5 回答
7603 浏览
提问于 2025-04-17 06:11

我正在尝试在Heroku上用Flask做一个简单的图片上传应用。我正在按照这个教程进行操作:http://flask.pocoo.org/docs/patterns/fileuploads/

不过,我想用S3来存储文件,而不是使用临时目录,因为Heroku不允许你直接写入磁盘。我找不到专门针对Heroku和Flask的相关示例。

5 个回答

3

使用boto库的话,代码大概是这样的:

import boto
from boto.s3.connection import S3Connection
from boto.s3.key import Key


def upload_file():
    if request.method == 'POST':
        file = request.files['file']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            conn = S3Connection('credentials', '')
            bucket = conn.create_bucket('bucketname')
            k = Key(bucket)
            k.key = 'foobar'
            k.set_contents_from_string(file.readlines())
            return "Success!"
8

这是一个有点老的问题,但我觉得自从亚马逊为S3引入了CORS支持之后,最好的方法就是让用户的浏览器直接上传文件到S3——这样文件就不会经过你的服务器

这个是一个非常简单的Flask项目,展示了如何做到这一点。

12

在我看来,在这个示例代码中,上传的文件是存储到一个临时文件里的,你只需要把 file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) 这行代码换成上传文件到 S3 的代码就可以了。

比如,来自链接页面的代码:

def upload_file():
    if request.method == 'POST':
        file = request.files['file']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            s3 = boto.connect_s3()
            bucket = s3.create_bucket('my_bucket')
            key = bucket.new_key(filename)
            key.set_contents_from_file(file, headers=None, replace=True, cb=None, num_cb=10, policy=None, md5=None) 
            return 'successful upload'
    return ..

或者,如果你想要异步上传到 S3,你可以使用 Heroku 提供的任何队列机制。

撰写回答