Подтвердить что ты не робот

Как загрузить файл на S3 без создания временного локального файла

Есть ли возможный способ загрузить файл, который динамически генерируется на amazon s3 напрямую без предварительного создания локального файла, а затем загрузить его на сервер s3? Я использую python. Благодаря

4b9b3361

Ответ 1

Вот пример загрузки изображения (с использованием библиотеки запросов) и загрузки его на s3 без записи в локальный файл:

import boto
from boto.s3.key import Key
import requests

#setup the bucket
c = boto.connect_s3(your_s3_key, your_s3_key_secret)
b = c.get_bucket(bucket, validate=False)

#download the file
url = "http://en.wikipedia.org/static/images/project-logos/enwiki.png"
r = requests.get(url)
if r.status_code == 200:
    #upload the file
    k = Key(b)
    k.key = "image1.png"
    k.content_type = r.headers['content-type']
    k.set_contents_from_string(r.content)

Ответ 2

Вы можете использовать BytesIO из стандартной библиотеки Python.

from io import BytesIO
bytesIO = BytesIO()
bytesIO.write('whee')
bytesIO.seek(0)
s3_file.set_contents_from_file(bytesIO)

Ответ 3

В boto библиотеке Key есть несколько способов, которые могут вас заинтересовать:

Пример использования set_contents_from_string см. в разделе Сохранение данных в документации boto, вставленной здесь для полноты:

>>> from boto.s3.key import Key
>>> k = Key(bucket)
>>> k.key = 'foobar'
>>> k.set_contents_from_string('This is a test of S3')

Ответ 4

Я предполагаю, что вы используете boto. boto Bucket.set_contents_from_file() будет принимать объект StringIO, и любой код, который вы написали для записи данных в файл, должен быть легко адаптирован для записи в объект StringIO. Или, если вы создаете строку, вы можете использовать set_contents_from_string().

Ответ 5

def upload_to_s3(url, **kwargs):
    '''
    :param url: url of image which have to upload or resize to upload
    :return: url of image stored on aws s3 bucket
    '''

    r = requests.get(url)
    if r.status_code == 200:
        # credentials stored in settings AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
        conn = boto.connect_s3(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, host=AWS_HOST)

        # Connect to bucket and create key
        b = conn.get_bucket(AWS_Bucket_Name)
        k = b.new_key("{folder_name}/{filename}".format(**kwargs))

        k.set_contents_from_string(r.content, replace=True,
                                   headers={'Content-Type': 'application/%s' % (FILE_FORMAT)},
                                   policy='authenticated-read',
                                   reduced_redundancy=True)

        # TODO Change AWS_EXPIRY
        return k.generate_url(expires_in=AWS_EXPIRY, force_http=True)

Ответ 6

Вы можете попробовать использовать smart_open (https://pypi.org/project/smart_open/). Я использовал это именно для этого: запись файлов непосредственно в S3.

Ответ 7

У меня был объект dict, который я хотел сохранить как файл JSON на S3, не создавая локальный файл. Следующий код работал для меня:

from smart_open import smart_open

with smart_open('s3://access-key:[email protected]/file.json', 'wb') as fout:
    fout.write(json.dumps(dict_object).encode('utf8'))

Ответ 8

Учитывая, что шифрование в состоянии покоя является очень желательным стандартом данных, smart_open не поддерживает этот интерфейс.

Ответ 9

Обновление для boto3:

aws_session = boto3.Session('my_access_key_id', 'my_secret_access_key')
s3 = aws_session.resource('s3')
s3.Bucket('my_bucket').put_object(Key='file_name.txt', Body=my_file)