はじめに
AWS との連携を Python で試す。Python 用 AWS SDK である Boto3 を用いて Amazon S3 へのファイルアップロードという簡単な操作を試してみる。AWS SDK for Python を参考にした。
Boto3 とは
冒頭にも書いた通り、Python 用 AWS SDK で、Python アプリケーションやライブラリ、スクリプトを AWS の各種サービス(Amazon S3, Amazon EC2, Amazon DynamoDB など)と容易に統合ができる。
Boto3 には、**Client API(低レベル API)**と Resource API(高レベル API) という2つの異なるレベルの API がある。両者の違いは明確に理解できていないが、本記事では Client API で試行してみる。
その他にも、AWS リソースの変化を自動的にポーリングする waiter という機能や Amazon S3 や Amazon DynamoDB といったサービスに固有の高レベル機能ももっている。
Boto3 のインストール
以下コマンドで Boto3 をインストールする。
$ pip install boto3
Boto3 は Python バージョン 2.7, 3.4+ で利用可能。
AWS API キーの準備
AWS サービスを扱うには API キーが必要となるので、S3 のアクセス権限をもたせた IAM ユーザを作成し、その アクセスキー ID とシークレットアクセスキーを準備する。
このキーが流出すると、権限の範囲内でなんでもできてしまい非常に危険であるので、コード上にベタ書きはせず環境変数としてもたせる。(詳細は後述)
上記で述べたように API キーの処理は危険であるので、AWS リソースからアクセスする場合は IAM ロールを付与して扱うのが望ましい。たとえば Lambda から S3 へのアクセスをする場合には、Lambda に対して S3 アクセス権限をもたせたロールを付与する。そうした場合、API キーは扱わなくて済む(はず)。
S3 へアクセス
Boto3 を用いて Amazon S3 にアクセスする。以下は Bucket リストを表示するコードである。
import boto3
client = boto3.client(
's3',
aws_access_key_id='**********',
aws_secret_access_key='**********',
region_name='ap-northeast-1'
)
print(client.list_buckets())
boto3.client('s3')
で S3 へアクセスするオブジェクトを作成する。's3' の代わりに 'ec2' や 'lambda' などを入れれば、対応するサービスを扱うことができる。扱えるサービスは Available services で見ることができる。
その他は準備した API キーやリージョンを指定している。ただし、このようにベタ書きでキー情報を書いてしまうと、GitHub などで誤って公開してしまう恐れがあるので、以下コードのように環境変数として指定するとよい。
まず .env
ファイルを作成して環境変数として値を設定する。.env
ファイルはこの環境変数を読み込みたいプログラムと同じかそれより上位に置く必要があるが、基本的には同階層に置けばよいと思う。
AWS_ACCESS_KEY_ID='**********'
AWS_SECRET_ACCESS_KEY='**********'
AWS_DEFAULT_REGION='ap-northeast-1'
次に、dotenv ライブラリの load_dotenv()
を実行する。これによって、先ほど作成した .env
ファイルの環境変数を勝手に読み取って補完することができ、boto3.cliend('s3')
のみの記述で済む。dotenv は pip install python-dotenv
でインストールできる。
import boto3
from dotenv import load_dotenv
load_dotenv()
client = boto3.client('s3')
print(client.list_buckets())
S3 へファイルをアップロード
上記で S3 へのアクセスは確認できたため、次にファイルをアップロードする。S3.Client.upload_file を参考にした。コードは以下。
from dotenv import load_dotenv
import boto3
load_dotenv()
client = boto3.client('s3')
Filename = './data/test.csv'
Bucket = 'my-bucket'
Key = 'test/test.csv'
client.upload_file(Filename, Bucket, Key)
アップロードしたいファイルへのパス、アップロード先の Bucket、アップロード先のパスをそれぞれ指定してやればよい。
おわりに
Amazon S3 へのファイルアップロードを行った。その他サービスを試しつつ、Resource API や IAM ロールの検討などをして実務で扱えるようにしていきたい。