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

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

Ответы

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