boto3를 사용하여 S3 객체에 파일 또는 데이터를 쓰는 방법


답변:


212

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'))

botocore.exceptions.NoCredentialsError :이 문제를 해결하는 방법을 자격 증명을 찾을 수 없습니까?
디팍 머시

2
@deepakmurthy 왜 그 오류가 발생하는지 잘 모르겠습니다 ... 새로운 Stack Overflow 질문을 하고 문제에 대한 자세한 내용을 제공해야합니다.
jkdev

1
내가 시도하면 s3.Object().put()0 인 객체로 끝납니다 content-length. 나에게는 put()문자열 데이터 만 허용하지만 put(str(binarydata)) 일종의 인코딩 문제가있는 것 같습니다. 원래 데이터의 약 3 배 크기의 객체로 끝나므로 쓸모가 없습니다.
user1129682

@ user1129682 왜 그런지 잘 모르겠습니다. 당신은 시겠어요 새로운 질문을 더 많은 정보를 제공?
jkdev

당신이 할 수 있다면 @jkdev 좋을 것 좀 봐 .
user1129682


37

더 이상 S3의 파일에 쓰기 전에 콘텐츠를 바이너리로 변환 할 필요가 없습니다. 다음 예제는 문자열 콘텐츠가있는 S3 버킷에 새 텍스트 파일 (newfile.txt라고 함)을 생성합니다.

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)

내 'put'작업에 액세스 권한이 없다는 사실을 몰라요. 이 버킷을 만들고 액세스 목록 아래에 정식 ID를 넣었습니다.
Chen Lin

당신은 어떻게 제공합니까 prefix이 경우? 의미, 파일을 저장하려면 어떻게해야 my-bucket-name/subfolder/합니까?
kev

3
@kev 당신과 함께 그를 지정할 수있는 파일 이름 '하위 폴더 / NEWFILE.TXT'대신 'NEWFILE.TXT'의
Madhava 카리

"S3의 파일에 쓰기 전에 더 이상 내용을 바이너리로 변환 할 필요가 없습니다."이 문서가 어딘가에 있습니까? boto3.amazonaws.com/v1/documentation/api/latest/reference/…를 보고 있었고 바이트 만 허용한다고 생각했습니다. 정확히 "검색 가능한 파일과 같은 객체"를 구성하는 것이 무엇인지 모르겠지만 여기에 문자열이 포함되어 있다고 생각하지 않았습니다.
Emma

나는 이것을 대용량 멀티 파트 파일 업로드를위한 download_fileobj ()와 비교할 수 있습니다. 업로드 메서드에는 검색 가능한 파일 객체가 필요 하지만 put ()을 사용하면 버킷의 파일에 직접 문자열을 쓸 수 있으므로 람다 함수가 S3 버킷에 파일을 동적으로 생성하고 쓰는 데 편리합니다.
Franke

28

다음은 s3에서 JSON을 읽는 좋은 방법입니다.

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_s3json.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

2
우수한. 작동하도록하기 위해이 추가 비트를 추가했습니다 ...["Body"].read().decode('utf-8')..
sedeh

좋은 생각입니다. 어쨌든 이름 지정 개선을위한 약간의 공간을 제공합니다.
Jan Vlcinsky

이 좋은 아이디어의 재 작성 제안 : gist.github.com/vlcinsky/bbeda4321208aa98745afc29b58e90ac
Jan Vlcinsky

14

주어진 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_idaws_secret_access_key)을 별도의 파일에 넣어야합니다 . 예 :~/.aws/credentials


Windows가 지원하지 않기 때문에 AWS 자격 증명 파일의 Windows 동등한 위치는 어디입니까?~
Hamman Samuel

1
@HammanSamuel 당신은 그것을 저장할 수 있습니다C:\Users\username\.aws\credentials
kev

1

사용 하는 스마트 오픈 을 언급 할 가치 가 있습니다.boto3백엔드로 있습니다.

smart-open드롭 인 교체 파이썬의 대한 인 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 자격 증명은 일반적으로 dir 또는 환경 변수 의 파일 인 boto3 credentials 를 통해로드됩니다 ~/.aws/.


1
이 응답은 정보를 제공하지만 원래 질문에 대한 답을 고수하지 않습니다. 즉, 특정 boto 메서드의 boto3에 해당하는 것은 무엇입니까?
robinhood91

1
스마트 개방 용도는 boto3
열린 우리당 고렌에게

1

아래 코드를 사용하여 예를 들어 2019 년 S3에 이미지를 작성할 수 있습니다. S3에 연결하려면 command를 사용하여 AWS CLI를 설치 pip install awscli한 다음 command를 사용하여 몇 가지 자격 증명을 입력해야합니다 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.