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

Как записать файл или данные в объект S3 с помощью boto3

В boto 2 вы можете записать объект S3 с помощью следующих методов:

Есть ли boto 3 эквивалент? Что такое метод boto3 для сохранения данных в объект, хранящийся на S3?

4b9b3361

Ответ 1

В boto 3 методы 'Key.set_contents_from_' были заменены на

Например:

import boto3

some_binary_data = b'Here we have some data'
more_binary_data = b'Here we have some more data'

# Method 1: Object.put()
s3 = boto3.resource('s3')
object = s3.Object('my_bucket_name', 'my/key/including/filename.txt')
object.put(Body=some_binary_data)

# Method 2: Client.put_object()
client = boto3.client('s3')
client.put_object(Body=more_binary_data, Bucket='my_bucket_name', Key='my/key/including/anotherfilename.txt')

Альтернативно, двоичные данные могут поступать от чтения файла, как описано в официальных документах, сравнивающих boto 2 и boto 3:

Хранение данных

Сохранение данных из файла, потока или строки легко:

# Boto 2.x
from boto.s3.key import Key
key = Key('hello.txt')
key.set_contents_from_file('/tmp/hello.txt')

# Boto 3
s3.Object('mybucket', 'hello.txt').put(Body=open('/tmp/hello.txt', 'rb'))

Ответ 3

Вот хороший трюк для чтения JSON из s3:

import json, boto3
s3 = boto3.resource("s3").Bucket("bucket")
json.load_s3 = lambda f: json.load(s3.Object(key=f).get()["Body"])
json.dump_s3 = lambda obj, f: s3.Object(key=f).put(Body=json.dumps(obj))

Теперь вы можете использовать json.load_s3 и json.dump_s3 с тем же API, что и load и dump

data = {"test":0}
json.dump_s3(data, "key") # saves json to s3://bucket/key
data = json.load_s3("key") # read json from s3://bucket/key

Ответ 4

Вам больше не нужно преобразовывать содержимое в двоичный файл перед записью в файл в S3. В следующем примере создается новый текстовый файл (с именем newfile.txt) в сегменте S3 со строковым содержимым:

import boto3

s3 = boto3.resource(
    's3',
    region_name='us-east-1',
    aws_access_key_id=KEY_ID,
    aws_secret_access_key=ACCESS_KEY
)
content="String content to write to a new S3 file"
s3.Object('my-bucket-name', 'newfile.txt').put(Body=content)

Ответ 5

Более чистая и лаконичная версия, которую я использую для загрузки файлов на лету в заданную корзину S3 и подпапку-

import boto3

BUCKET_NAME = 'sample_bucket_name'
PREFIX = 'sub-folder/'

s3 = boto3.resource('s3')

# Creating an empty file called "_DONE" and putting it in the S3 bucket
s3.Object(BUCKET_NAME, PREFIX + '_DONE').put(Body="")

Примечание. ВСЕГДА следует помещать свои учетные данные AWS (aws_access_key_id и aws_secret_access_key) в отдельный файл для example- ~/.aws/credentials

Ответ 6

Вы можете использовать приведенный ниже код для записи, например, изображения в S3 в 2019 году. Чтобы иметь возможность подключиться к S3, вам нужно установить AWS CLI с помощью команды pip install awscli, а затем ввести несколько учетных данных с помощью команды aws configure:

import urllib3
import uuid
from pathlib import Path
from io import BytesIO
from errors import custom_exceptions as cex

BUCKET_NAME = "xxx.yyy.zzz"
POSTERS_BASE_PATH = "assets/wallcontent"
CLOUDFRONT_BASE_URL = "https://xxx.cloudfront.net/"


class S3(object):
    def __init__(self):
        self.client = boto3.client('s3')
        self.bucket_name = BUCKET_NAME
        self.posters_base_path = POSTERS_BASE_PATH

    def __download_image(self, url):
        manager = urllib3.PoolManager()
        try:
            res = manager.request('GET', url)
        except Exception:
            print("Could not download the image from URL: ", url)
            raise cex.ImageDownloadFailed
        return BytesIO(res.data)  # any file-like object that implements read()

    def upload_image(self, url):
        try:
            image_file = self.__download_image(url)
        except cex.ImageDownloadFailed:
            raise cex.ImageUploadFailed

        extension = Path(url).suffix
        id = uuid.uuid1().hex + extension
        final_path = self.posters_base_path + "/" + id
        try:
            self.client.upload_fileobj(image_file,
                                       self.bucket_name,
                                       final_path
                                       )
        except Exception:
            print("Image Upload Error for URL: ", url)
            raise cex.ImageUploadFailed

        return CLOUDFRONT_BASE_URL + id

Ответ 7

стоит упомянуть smart-open, который использует boto3 в качестве бэк-энда.

smart-open представляет собой замену Python open, который может открывать файлы из s3, а также ftp, http и многих других протоколов.

например

from smart_open import open
import json
with open("s3://your_bucket/your_key.json", 'r') as f:
    data = json.load(f)

Учетные данные aws загружаются через учетные данные boto3, обычно это файл в каталоге ~/.aws/ или переменная окружения.