はじめに
YAPC::Kyoto 2023のチケットを買ってくれ!1(本日1/31(火)まで) nikkieです。
直近でLocalStackという技術を触る機会がありました。
LocalStackはAWSのサービス(に相当するAPI群)をローカル開発環境で動かせます。
環境構築からPythonスクリプトでローカルのS3を操作するまでをログとして残します。
目次
LocalStack
フューチャーさんのブログで存在を知りました。
フューチャーさんの記事は、AWS Lambdaの開発環境をLocalStackで動かす例を示しています。
LocalStack自体はPythonで実装されていて2、PyPIにパッケージも登録されています。
DockerでLocalStackを動かす
今回はDockerで動かすことにしました(pip install localstack
は今後の素振り材料です)。
https://docs.localstack.cloud/getting-started/installation/#docker
$ docker run --rm -it \ -p 4566:4566 \ -p 4510-4559:4510-4559 \ localstack/localstack
起動中のログより、以下のバージョンを動かしていました。
LocalStack version: 1.3.2.dev LocalStack build date: 2023-01-28 LocalStack build git hash: 63e357fb
「Ready.」と出たら準備完了です。
curl -s http://localhost:4566/health | jq .
で各種サービスがavailableになったことが確認できます。
ローカルのS3でboto3を素振り!
AWSのサービスの操作を提供するライブラリboto3
、LocalStackに向けても使えます。
pip install boto3
でインストールできます。
以下のバージョンで動かしています。
$ python -V Python 3.10.2 $ pip list | grep boto boto3 1.26.59 botocore 1.29.59
試しにS3にバケットを作り、ファイルを置いてみます(s3://awesome/foo/bar.txt
が置かれます)。
import boto3 s3 = boto3.client( "s3", endpoint_url="http://localhost:4566", aws_access_key_id="dummy", aws_secret_access_key="dummy", ) BUCKET_NAME = "awesome" s3.create_bucket(Bucket=BUCKET_NAME) FILE_PATH = "foo/bar.txt" s3.put_object(Bucket=BUCKET_NAME, Key=FILE_PATH, Body=b"LocalStack!")
client
3はLocalStackのエンドポイントを指定し、aws_access_key_id
とaws_secret_access_key
にはダミーの文字列を指定します。
boto3でS3のバケット操作
バケットの作成はcreate_bucket
メソッドです。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.create_bucket
Parametersのうち、Bucket
(バケット名を指定)のみが必須です。
パケットにファイルを置くのはput_object
メソッドです。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.put_object
必須のパラメータはBucket
とKey
(S3に置くオブジェクトのキー)です。
オブジェクトのデータはBody
にbytes
オブジェクト、またはfile-likeオブジェクト4として渡せます。
LocalStackのS3バケットに置いたファイルを確認
上で示したスクリプト(s3_practice.py
)を-i
オプションを付けて実行します。
スクリプト実行後に立ち上がるPythonの対話モードで、s3://awesome/foo/bar.txt
の内容を確認します。
>>> response = s3.get_object(Bucket=BUCKET_NAME, Key=FILE_PATH) >>> response["Body"].read() b'LocalStack!'
get_object
メソッドでオブジェクトを取得します。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.get_object
Parametersのうち、Bucket
とKey
が必須です。
Responseの辞書では、キー"Body"
がデータを指しています。
read
メソッドで読み込みます5。
書き込んだバイト列と同じですね!🙌
終わりに
ローカル環境にAWSのサービスを立てられるLocalStackを触りました。
Dockerで動かし、boto3
を使ってS3を操作しています。
バケットを作り、オブジェクトを置き、その内容を読み出しました。
ローカル環境に簡単にAWSを用意できるのは開発が捗りそうな印象です。
AWS Lambdaで動かしているBot6がありますが、他のAWSサービスと連携させる開発はまずサービスの用意が必要ですし、一発で正しく構築できないことが多いので数回作り直すイメージがあります。
ですが、LocalStackでローカル環境に用意すれば、試行錯誤に必要な準備が劇的に簡単になります!
素振り中も、例えばバケットができたあとに実装ミスでエラーが送出されたら、LocalStackを止めて再度docker run
して操作をリセット。
修正したスクリプトを最初から流し直しました。
ブログにまとめるにあたって、boto3
のドキュメントの読み方もなんとなく分かりました。
すごく文字がありますが、ParametersのREQUIREDさえ確認すれば使い出せます。
ResponseやExampleも参考になりますね。
参考記事
P.S. boto3のClient API
ここで示したスクリプトはboto3.client
とClient APIを使うものです。
boto3にはもう1つResource APIがあります(boto3.resource
)。
Resource APIが廃止という情報を見かけ、今回のスクリプトはClient APIを使って実装しています。
2023/01/19 追記:「Resource API」廃止についての情報
- ↩
- ログを見るとASGIやhypercornの文字が!実装も気になりますね↩
- https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/session.html#boto3.session.Session.client↩
- https://docs.python.org/ja/3/glossary.html#term-file-like-object↩
- 例も参考になりました:https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#uploading-downloading-files-using-sse-kms↩
- #アイの歌声を聴かせて 非公式Twitter Bot、これまでの開発録(ソースコード公開しました!) - nikkie-ftnextの日記↩