boto 2では、次のメソッドを使用してS3オブジェクトに書き込むことができます。
- Key.set_contents_from_string()
- Key.set_contents_from_file()
- Key.set_contents_from_filename()
- Key.set_contents_from_stream()
boto 3に相当するものはありますか?S3に格納されているオブジェクトにデータを保存するboto3メソッドとは何ですか?
boto 2では、次のメソッドを使用してS3オブジェクトに書き込むことができます。
boto 3に相当するものはありますか?S3に格納されているオブジェクトにデータを保存するboto3メソッドとは何ですか?
回答:
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'))
s3.Object().put()
と、ゼロのオブジェクトになってしまいますcontent-length
。私にとってput()
は文字列データのみを受け入れますput(str(binarydata))
が、なんらかのエンコードの問題があるようです。元のデータの約3倍のサイズのオブジェクトができてしまい、役に立たなくなります。
boto3には、ファイルを直接アップロードする方法もあります。
s3.Bucket('bucketname').upload_file('/local/file/here.txt','folder/sub/path/to/s3key')
http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Bucket.upload_file
s3.Bucket(...).upload_fileobj()
代わりにメソッドを使用できます。
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)
prefix
この場合、どのようにを与えますか?つまり、ファイルを保存したい場合はどうなりますmy-bucket-name/subfolder/
か?
以下は、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_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
...["Body"].read().decode('utf-8')
。
特定の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
)は、必ず別のファイルに入れてください。たとえば、~/.aws/credentials
~
C:\Users\username\.aws\credentials
バックエンドとして使用する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/
dir 内のファイルまたは環境変数を介してロードされます。
以下のコードを使用して、たとえば2019年にS3にイメージを書き込むことができます。S3に接続できるようにするにはpip install awscli
、コマンドを使用してAWS CLIをインストールし、コマンドを使用していくつかの認証情報を入力する必要があります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