【flask】boto3でS3へのコマンドまとめ【アップロード・ダウンロード・削除】

この記事では、flaskのboto3を使って、AWSのS3へのファイルのコマンドを解説します。

これから、flask でS3への接続を考えている人がコマンドを試せるように、使ったものをAPIやモジュールとして使えるようまとめました。

自分の環境では問題なく動作可能だったので、参考にしていただければと思います。

解説の流れ

今回は、主に以下の二つをテーマに解説します。

  1. AWSのアクセスキーの管理の仕方
  2. アップロード、ダウンロード、削除のコード解説

はじめに説明する「AWSのアクセスキーの管理の仕方」は重要ですので、アップロードなどをする前に知っておくことをおススメします。

では、行きましょう。

AWSのアクセスキーの管理の仕方

S3へファイルをアップロードしたり、ファイルをやりくりするには、アクセスキーが必要になります。

ただ、アクセスキーを同じファイルにべた張りをするのは、セキュリティの観点でよろしくありません。

なので、ここでは.envファイルを用いたアクセスキーの管理を紹介します。

.envファイルを作成

まず、pythonファイル(ここではapp.pyを用います)と同階層に「.env」ファイルを作成します。

あべべ

ファイル名は記載せず、ただ、「.env」という名前のファイルを作成してください。

VScodeやコードエディタで作成できます。

作成できたら、「AWS_ACCESS_KEY_ID」と「AWS_SECRET_ACCESS_KEY」と「AWS_DEFAULT_REGION」を次のように記載します。

AWS_ACCESS_KEY_ID='<ここに記載>'
AWS_SECRET_ACCESS_KEY='<ここに記載>'
AWS_DEFAULT_REGION='ap-northeast-1'
あべべ

ここで、注意なのが、空白や「,」を変なところで入れないことです。

入れてるとうまく読み取れなく、エラーが出ます。(詳しくは以下)

記載したら、app.pyを書きます。

Pythonファイル(app.py)の記載

.envファイルを読み取るには、dotenvモジュールを用います。

以下のように記載しましょう。

import boto3
from dotenv import load_dotenv
from flask import Flask
import os

#インスタンスの作成
app = Flask(__name__)
app.secret_key = os.urandom(21)

#ここ↓
load_dotenv()
client = boto3.client('s3')

if __name__ == '__main__':
    app.run(debug=True)

このようにすることで、同ファイル内にベタ貼りすることなく、誤って公開してしまう心配もありません。

このアクセスキーは入手してしまうと、誰でも自分のアカウントにアクセスできてしまいます。

中には高額請求が来たユーザーもいるので、アクセスキーの管理には気を付けましょう。

アップロード、ダウンロード、削除のコード解説

では、S3へのファイルのやり取りを行います。

私は、今回画像ファイルをやりくりするのに用いましたが、他のファイルでも使えるはずです。

アップロード

@app.route('/upload', methods=['GET'])
def upload():
    Filename = '<ファイルの相対パス>'
    Bucket = '<バケット名>'
    Key = '<バケットの中のアップロード先パス>'
    client.upload_file(Filename, Bucket, Key)
    return 'upload ok'

.upload_fileでアップロードが可能になります。

今回は、client.upload_file()のレスポンス値は見ていません。

エラーになった場合などの挙動を変えたい場合は、レスポンス値に応じてif文を書くようにしましょう。

ダウンロード

@app.route('/download', methods=['GET'])
def download():
    Filename = '<ファイルの相対パス>'
    Bucket = '<バケット名>'
    Key = '<バケットの中のアップロード先パス>'
    client.download_file(Bucket, Key, Filename)
    return 'download ok'

コマンド以外は全てアップロードと同じです。

削除


@app.route('/delete', methods=['GET'])
def delete():
    Bucket = '<バケット名>'
    Key = '<バケット名>/<バケットの中のアップロード先パス>'
    client.delete_object(Bucket=Bucket,Key=Key)
    return 'delete ok'

削除は、delete_object()で削除することができます。

Access Deniedの沼

ちなみに、今回画像をアップロードしていますので、画像をwebに表示させたいと思います。

なので、AWSのファイルの中のパスをそのまま貼り付けると、、、

Access Denied のような文字が。アクセスを拒否されます。

これを解除するには、以下の二つが必要です。

  1. ブロックパブリックアクセスの設定
  2. バケットポリシー

これらどちらが欠けても、Access Denied の沼に誘われるので、web表示をしたい人は設定を忘れずにしましょう。

以下の記事が参考になります。
AWS S3で「Access Denied」を解決する - Qiita
S3にアップした画像が表示されない - Qiita

全コード

import boto3
from dotenv import load_dotenv
from flask import Flask
import os

#インスタンスの作成
app = Flask(__name__)
app.secret_key = os.urandom(21)

load_dotenv()
client = boto3.client('s3')

@app.route('/upload', methods=['GET'])
def upload():
    Filename = '<ファイルの相対パス>'
    Bucket = '<バケット名>'
    Key = '<バケットの中のアップロード先パス>'
    client.upload_file(Filename, Bucket, Key)
    return 'upload ok'

@app.route('/download', methods=['GET'])
def download():
    Filename = '<ファイルの相対パス>'
    Bucket = '<バケット名>'
    Key = '<バケットの中のアップロード先パス>'
    client.download_file(Bucket, Key, Filename)
    return 'download ok'

@app.route('/delete', methods=['GET'])
def delete():
    Bucket = '<バケット名>'
    Key = '<バケット名>/<バケットの中のアップロード先パス>'
    client.delete_object(Bucket=Bucket,Key=Key)
    return 'delete ok'

if __name__ == '__main__':
    app.run(debug=True)

まとめ

今回は、flaskのboto3を使って、S3へファイルをやりくりする方法を解説しました。

誰かのお役に立てれば幸いです。

(Visited 39 times, 1 visits today)