Использование Amazon S3 с Heroku, Python и Flask

Я пытаюсь получить приложение для загрузки изображений, работающее на Heroku, используя Flask. Я следую учебнику здесь: http://flask.pocoo.org/docs/patterns/fileuploads/

Однако я хочу использовать S3 для хранения файла вместо временного каталога, так как Heroku не позволяет вам записывать на диск. Я не могу найти примеров того, как это сделать специально для Heroku и Flask.

Ответ 1

Мне кажется, что в примере кода, который хранит загруженный файл во временном файле, вы просто замените 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.

Ответ 2

Немного старый вопрос, но я думаю, что с тех пор, как Amazon представил поддержку CORS для S3, лучшим подходом является загрузка непосредственно на S3 из браузера пользователя - без битов, когда-либо касавшихся вашего сервера.

Этот - это очень простой проект фляжки, который точно показывает, как это сделать.

Ответ 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!"

Ответ 4

Вместо того, чтобы хранить файл на диске напрямую, вы также можете сохранить его данные в базе данных (например, в кодировке base64).

В любом случае, чтобы взаимодействовать с Amazon S3 с использованием Python, вам следует использовать библиотеку boto (то же самое верно для любой другой Amazon оказание услуг). Чтобы узнать, как его использовать, вы можете посмотреть соответствующую документацию.

Ответ 5

Я работаю над чем-то похожим для веб-сайта, который я сейчас разрабатываю. Пользователи будут загружать очень большие файлы. Я смотрю на использование Plupload для загрузки непосредственно на S3, следуя советам здесь.

Альтернативой является использование загрузчика прямого доступа к S3 в Boto.