botoを使ってS3にファイルをアップロードする

何度もやったことあるのに、ブログに書いてなかったっぽいので書く。
Pythonからbotoを使ってAWSのS3にファイルをアップロードする方法。
試したPythonのバージョンは2.6。botoは2.0rc1

botoのインストール

pipやeasy_installで入れればよい。

$ pip install boto

S3へのバケットの用意

アップロード先のバケットを用意する。
botoのAPIで作成することもできるが、今回はAWSのコンソールから作成しておく。
S3のタブのBucketsから"Create Bucket"でバケット名を入力して作成。

今回は test-boto.nullpobug.com とした。(別にドメイン名になってなくてもよいが、CNAME割り当てでのアクセスを使うならドメイン名にする必要がある)

アクセスキーの確認

AWSAPIを利用するにはアクセスキーとシークレットアクセスキーの2つが必要。
セキュリティ証明書のページから確認、取得しておく。

botoのコネクション

S3を使う場合は、botoのS3Connectionオブジェクトを作っておく必要がある。
2つのキーは引数として与えるか、環境変数で設定しておく。

>>> from boto.s3.connection import S3Connection
>>> conn = S3Connection('アクセスキーの文字列', 'シークレットアクセスキーの文字列')

このconnオブジェクトのメソッドからゴニョゴニョ開始する。
中身の通信はHTTPSXML投げっこ。

フォルダの作成

バケットは作成済みなので、コネクションからバケットのオブジェクトを得る。

>>> bucket = conn.get_bucket('test-boto.nullpobug.com')
>>> bucket
<Bucket: test-boto.nullpobug.com>

バケットにはKeyオブジェクトとしてファイルを保存できる。
フォルダもファイル。というかフォルダという概念がないので、S3用のツール類などからフォルダとして見えるのは、keyの最後がセパレータのスラッシュ(/)になってるものだったり、拡張子が "_$folder$" となってるものみたい。
バケットの中身をとりあえず確認するには、list関数で見ればよい。

>>> list(bucket)
[]

中身が多いと処理が戻ってこないので注意。__iter__でアクセスできるのーよ。
作ったばっかりなので空になってる。
フォルダを作ってみる。
コンテンツは空でよいので空文字列を指定。set_contents_from_stringを呼び出したタイミングでリクエストを投げてるみたいです。

>>> from boto.s3.key import Key
>>> k = Key(bucket)
>>> k.key = 'test_folder/'
>>> k.set_contents_from_string('')

これでtest_folderという名前のフォルダが作られる。
Management Consoleから見るとこんな感じ。

ファイルをアップロードする

ファイルも同様にKeyオブジェクトを作成すればアップロードできます。

>>> f = Key(bucket)
>>> f.key = 'test.txt'
>>> f.set_contents_from_filename('test.txt')

これでカレントフォルダにあるtest.txtという名前のファイルをアップロードできました。
らくちん。