boto3を使ってAWS S3のファイルを操作する方法をあれこれまとめておきます。
公式ドキュメントはこちらです。
S3 — Boto3 Docs 1.17.84 documentation
この記事ではリソースAPIの方を使います。
準備
とりあえず、この記事のために次の名前でS3にバケットを作っておきました。
– blog-work-sample1
– blog-work-sample2
さらに、 blog-work-sample1 の方には、
– sample-folder1
というフォルダーを掘っておきます。
また、サンプルとしてアップロードするファイルが必要なのでローカルに作っておきます。
!echo Hello S3! > samplefile.txt
ファイルのアップロード
まずはファイルのアップロードです。
アップロードしたいバケットを、 s3.Bucket(“バケット名”) で取得し、
upload_file(“アップロードしたいファイルのパス”, “アップロード先のファイルのパス”)でアップロードできます。
次のサンプルコードではアップロード時にファイル名を変更していいますがもちろんローカルのファイルと同じままのファイル名でも大丈夫です。
import boto3
s3 = boto3.resource("s3")
bucket = s3.Bucket("blog-work-sample1")
# バケットの直下に samplefile1.txt という名前でアップロードする場合
bucket.upload_file("samplefile.txt", "samplefile1.txt")
# フォルダ配下にアップロードする場合
bucket.upload_file("samplefile.txt", "sample-folder1/samplefile2.txt")
S3内でのファイルのコピー
ファイルのコピーには、 copy()というメソッドを使うのですが少しクセのある使い方をします。
どういうことかというと
{コピー先のバケットオブジェクト}.copy({コピー元の情報を辞書型で指定}, “コピー先のパス”)
という使い方をするのです。
まず、同じバケット内でコピーしてみます。
bucket = s3.Bucket("blog-work-sample1") # コピー先のバケット
# 元のファイルを辞書型で指定
copy_source = {
'Bucket': 'blog-work-sample1',
'Key': 'samplefile1.txt'
}
bucket.copy(copy_source, "samplefile3.txt")
そして、別のバケットにコピーする時はこうです。copyメソッドの引数ではなく、元のバケットオブジェクトの取得が変わっているのがポイントです。
bucket = s3.Bucket("blog-work-sample2") # コピー先のバケット
# 元のファイルを辞書型で指定
copy_source = {
'Bucket': 'blog-work-sample1',
'Key': 'samplefile1.txt'
}
bucket.copy(copy_source, "samplefile4.txt")
バケット内のオブジェクトの一覧を取得
バケット内のオブジェクトの一覧を取得するには、
bucketが持っている、objectsというプロパティの、all()メソッドでイテレーターとして取得します。
取得したオブジェクトのkey(S3において、ファイルパスやフォルダパスに相当する概念)を表示するコードが次です。
bucket = s3.Bucket("blog-work-sample1")
for obj in bucket.objects.all():
print(obj.key)
"""
sample-folder1/
sample-folder1/samplefile2.txt
samplefile1.txt
samplefile3.txt
"""
フォルダとファイルを分けて表示したい場合は、Keyの末尾が/で終わっているかどうかで区別するしかないようです。
そもそもS3においてはフォルダという概念が存在せず、全てKey(パスのような概念)と値(ファイルの中身に相当する概念)で管理されているためこうなっているようです。
ただし、AWSの管理コンソールでは気を利かせてくれて、フォルダっぽく表示してくれています。
ファイルのダウンロード
ファイルのダウンロードには、 download_file(“ダウンロードしたいファイルのキー”, “ローカルに保存するパス”)
というメソッドを使います。
したのコードで、 blog-work-sample1/samplefile3.txt がダウンロードされ、
ローカルに、samplefile5.txt という名前で保存されます。
bucket = s3.Bucket("blog-work-sample1")
bucket.download_file("samplefile3.txt", "samplefile5.txt")
ファイルの削除
最後にファイルの削除です。
これには、delete_objectsというメソッドを使います。
一見、{バケットオブジェクト}.delete_objects{“消したいファイルのキー”} で消せそうな気がしますが、なぜかこれはかなり特殊な形の引数で渡す必要があります。
blog-work-sample1/samplefile1.txt
を消したい場合の使い方は以下の通りです。
必ず名前付き引数(Delete=)で、サンプルのような辞書を渡す必要があります。
bucket = s3.Bucket("blog-work-sample1")
bucket.delete_objects(Delete={"Objects": [{"Key": "samplefile1.txt"}]})
以上で、S3へのファイルのアップロード、コピー、リストアップ、ダウンロード、削除ができるようになりました。