Python botoでS3を操作してみたログ

S3の操作をPythonから行った練習ログです。
個人的な備忘録で目新しいことは書いていないはずなので、見てもあんまり意味ないかもしれません。
AWSのIDやKEYの取得方法は別の記事を参照してください。

バケットを用意する

バケットはそんなに頻繁に作成するものではないはずなので最初はGUIで作成していきます。

S3の管理トップ画面→「Create Bucket」ボタンを押すとバケット作成画面がモーダルで起動します。
s3_2
ここでは「testbucket-cro」というバケットを作成します。リージョンは東京にしました(適当。

S3へコンテンツを登録する

基本となるコンテンツ登録から。

>>> import os
>>> from boto.s3 import connection, key
 
>>> ACCESS_KEY_ID = 'XXXXXXXXXXXXXXX'
>>> SECRET_ACCESS_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
 
>>> BUCKET_NAME = 'testbucket-cro'
>>> # 登録するファイル
>>> filename = 'a/test.txt'
>>> # コネクションの作成
>>> conn = connection.S3Connection(ACCESS_KEY_ID, SECRET_ACCESS_KEY)
>>> # バケットの取得
>>> bucket = conn.get_bucket(BUCKET_NAME)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user/Tests/s3/local/lib/python2.7/site-packages/boto/s3/connection.py", line 502, in get_bucket
    return self.head_bucket(bucket_name, headers=headers)
  File "/home/user/Tests/s3/local/lib/python2.7/site-packages/boto/s3/connection.py", line 535, in head_bucket
    raise err
boto.exception.S3ResponseError: S3ResponseError: 403 Forbidden

どうやら権限がないようです。管理コンソールから権限を追加します。

権限の設定手順

IAM → User → ユーザ名を選択します。(IAMのリンクが切れている場合はServicesからIAMを選択してください)

「Set Permissions」に遷移

Permissionsメニューの「Attach User Policy」を選択します。
s3policy

S3アクセス権設定項目の選択

S3は下の方にあります。今回は「Full Access」とします。
s3policy2

アクセス権追加確認

問題なければ「Apply Policy」を選択。
s3policy3

アクセス権追加完了

Permissionsメニューにアクセス権が追加されています。
s3policy4

>>> # 今度はうまくいった
>>> bucket = conn.get_bucket(BUCKET_NAME)
>>> # 第2引数にファイル名を指定しなければ自動的にファイル名が生成されてしまう
>>> k = key.Key(bucket, filename)
>>> # ファイル名を指定してアップロードする
>>> size = k.set_contents_from_filename(filename)
>>> # ファイルサイズが返却される
>>> print(size)
5

参考リンク
管理コンソールで確認してみます。

s3_uploaded

指定したバケットにファイルが登録されていることがわかりました。
パスに「/」を含めるとディレクトリが自動的に作成されるのは個人的に大きなポイントだと思っています。

空のディレクトリを作成する

ディレクトリだけ作成する関数はbotoの機能として提供されていません。(よね?)
「/」を含めるとディレクトリが作られるという特性を利用することで、空のディレクトリを作成できます。

>>> k = key.Key(bucket, 'dir/')
>>> k.set_contents_from_string('')
0

s3_dir

重要なのはKey名の最後を「/」とすることです。
set_contents_from_stringは指定したバイト文字列からコンテンツを作成する機能ですが、ここでどのような文字列を入力したところでディレクトリと判断されるため、意味はありません。

コンテンツを列挙する

S3に登録されているコンテンツを確認するには、バケットを起点としてKeyオブジェクトを列挙する方法が考えられます。

>>> bucket.get_all_keys()
[<Key: testbucket-cro,a/test.txt>, <Key: testbucket-cro,dir/>]

この方法は、上記を見て分かるとおりKeyとして登録された単位で表示されます。「a/test.txt」と「dir/」はどちらも1つのKeyとして扱われるということです。
「a」ディレクトリ、「a/test.txt」ファイル、「dir」ディレクトリの3つとはなりません。

コンテンツを削除する

コンテンツの削除はKey単位で行います。方法は単純にdeleteメソッドを呼び出すだけです。

>>> k = bucket.get_key('a/test.txt')
>>> k.delete()
<Key: testbucket-cro,a/test.txt>

管理コンソールで確認してみます。

s3_delete

「a」ディレクトリごとなくなっています。
Keyはディレクトリを含めたパスで指定されているので、他に「a」ディレクトリに該当するファイルがなければ見えなくなります。

バケットを作成する

だいぶ順番が前後しましたが、実装内でバケットを作成したいこともあるはずです。単純に以下のようにcreate_bucketメソッドを呼ぶだけです。

>>> conn.create_bucket('testbucket-cro2')
<Bucket: testbucket-cro2>

s3_newbucket
バケットが作成されていることが確認できました。

応用

少し応用したものをGistにあげてみました。