10
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Flask】アップロードされたファイルを直接S3にPUTする

Last updated at Posted at 2019-09-19

Flaskにて、アップロードされたファイルをローカル保存せずに扱う方法です。

先駆者さん⇒Flask にアップロードされたCSVファイルを保存せずに読み込む

上記の記事ではCSVファイルとして直接読み込む方法なので、S3転送する方法を書いておきます。
AWS SDKとしてboto3を使用します。

動作環境

いずれも 2019/9 時点の(おおよそ)最新。

  • Python: 3.7.4
  • Flask: 1.1.1
  • boto3: 1.9.230

ファイルアップロードファイルを受け付ける

htmlのフォームタグにenctype="multipart/form-data"属性を指定する必要があります。
詳細は本記事の対象外とします。
参考 - Flaskでmultipart/form-dataのファイルアップロードを実現する方法

S3への転送

boto3 の put_object メソッドでbytesオブジェクトを指定できるため、受け取ったファイルをbytesオブジェクトに変換して渡すことでS3アップロードが行えます。
参考 - S3 - Boto3 Doc

put_object(**kwargs)
Request Syntax
response = client.put_object(
ACL='private'|'public-read'|'public-read-write'|'authenticated-read'|'aws-exec-read'|'bucket-owner-read'|'bucket-owner-full-control',
Body=b'bytes'|file, ←★これ。

※アップロード先のバケット名やパスはconfig.pyで定義しておくのが良いと思います。

s3_upload.py
import io
import boto3
from Flask import jsonify

@app.route('/upload', methods=['POST'])
def workflow_create():
    if request.method == 'POST':
        # アップロードファイルを取得
        uploaded_file = request.files['file']
        # エラーチェック
        if uploaded_file.filename == '':
            return jsonify(message='ファイルを指定してください'), 400
        # S3アップロード処理
        s3_bucket = app.config['S3_BUCKET']
        s3_dir = app.config['S3_DIR']
        s3 = boto3.client('s3', region_name = 'ap-northeast-1')
        response = s3.put_object(
            Body = io.BufferedReader(uploaded_file).read(),
            Bucket = s3_bucket,
            Key = f'{s3_dir}/{uploaded_file.filename}'
        )
        if response['ResponseMetadata']['HTTPStatusCode'] != 200:
            return jsonify(message='S3へのアップロードでエラーが発生しました'), 500
        return redirect(url_for('index'))
response = s3.put_object(
    Body = io.BufferedReader(uploaded_file).read()
    ~~~

上記の部分でアップロードファイルをキャストしています。
これにより以下のコードで得られるファイルオブジェクトと同じ型で扱えます。

file = open('local/path/file.txt', 'rb')
10
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?