2020/10/12
[Python3]boto3を使ってS3にファイルをアップロード/ダウンロードする
概要
Python3 + boto3を使って、クライアントからアップロードしたファイルをS3にアップロードし
表示のためにS3からダウンロードする必要があったため実装を行いました。
この記事ではS3にアップロード&S3からダウンロードの部分を重点的にメモしています。
実施内容
bucketの作成
アプリケーションが扱うS3バケットを作成します。
(仮に以下の名前で作成したとします)
your-app
ポリシーの作成
以下の名前と内容で、IAMポリシーを作成します。このポリシーは作成したS3バケットのフルアクセスのみを持つIAMです。
s3-your-app-full-access
{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::your-app",
"arn:aws:s3:::your-app/*"
]
}
]
}
グループの作成
アプリケーションのIAMユーザーが所属するIAMグループを作成します
(仮に以下の名前で作成したとします)
your-app
このグループに先ほど作った、s3-your-app-full-access
のポリシーを付与しておきます。
ユーザーの作成
アプリケーションのIAMユーザーを作成します
(仮に以下の名前で作成したとします)
your-app
このユーザーを先ほど作ったグループに所属させます。
アクセスの種類 プログラムによるアクセス
を選択してユーザーを作成し、アクセスキーIDやシークレットアクセスキーをメモしておきます。
Pythonの実装
install
poetry add boto3
[tool.poetry.dependencies]
boto3 = "^1.15.16"
Upload
import boto3
# 環境変数や、aws cliなどで設定している場合は、aws_access_key_id / aws_secret_access_key / region_nameなどの引数は不要です。
client = boto3.client(
"s3",
aws_access_key_id=settings.AWS_ACCESS_KEY_ID, # 作成したIAMユーザーのアクセスキーIDが設定されています
aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY, # 作成したIAMユーザーのシークレットアクセスキーが設定されています
region_name=settings.AWS_REGION, # S3バケットのregionが設定されています
)
client.upload_fileobj(
Fileobj=stream,
Bucket="your-app",
Key="path/to/s3/key"
)
上記の Fileobj=stream
にはHTTP Requestでアップロードされたファイルを一時ファイルに出力し(画像だったので、pillowなどを使って最適化などを行った後、保存しています。)そのfile objectを引き渡しています。
デフォルメすると以下のような感じになります。
import tempfile
with tempfile.NamedTemporaryFile() as temp_image_file:
# ここで、pillowなどを使って、temp_image_fileにデータを保存します。
stream = temp_image_file
client.upload_fileobj(
Fileobj=stream,
Bucket="your-app",
Key="path/to/s3/key"
)
Download
import boto3
# 環境変数や、aws cliなどで設定している場合は、aws_access_key_id / aws_secret_access_key / region_nameなどの引数は不要です。
client = boto3.client(
"s3",
aws_access_key_id=settings.AWS_ACCESS_KEY_ID, # 作成したIAMユーザーのアクセスキーIDが設定されています
aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY, # 作成したIAMユーザーのシークレットアクセスキーが設定されています
region_name=settings.AWS_REGION, # S3バケットのregionが設定されています
)
client.download_fileobj(
Bucket="your-app",
Key="path/to/s3/key",
Fileobj=stream,
)
上記の Fileobj=stream
には一時ファイルを作成し、そのfile objectを引き渡しています。
デフォルメすると以下のような感じになります。
import tempfile
stream = tempfile.TemporaryFile()
client.download_fileobj(
Bucket="your-app",
Key="path/to/s3/key",
Fileobj=stream,
)
stream.seek(0) # これをしてカーソルを先頭に戻して、clientへ送信したりします
References
以下が参考になりました。
今回は以上になります。
関連する記事
[Python]ハイフンなし電話番号からハイフン付きに復元
Pythonでハイフンなしの日本の電話番号をハイフン付きのものに変換する
EKSのロードバランサーでIPアドレスのアクセス制限を設定する
EKSで構築しているネットワークロードバランサータイプのServiceにIP Whitelistを設定しました。
EKSのバージョンをアップグレードする
開発に利用しているEKSのバージョンをアップグレードしました
[Python]BeautifulSoup4でhtmlの解析
BeautifulSoup4というPythonのライブラリを使って、特定のURLのコンテンツを取得し、タイトルや説明文を取得できるようにしました。