Python FlaskでS3に直接アップロードする

概要

Flaskでローカル保存せずにS3に直接アップロードする。

ソース

ポイント

  • Bodyに Body=io.BufferedReader(uploaded_file).read(), を入れるとZIPファイルが壊れて保存されていたので、s3.put_objectのBodyにリクエストされたファイルをそのまま渡す。
  • tryを入れて例外処理するようにする
  • Requestは filesパラメータで送信すること
python

import boto3
from flask import Flask, jsonify, request

app = Flask(__name__)

@app.route('/api/upload', methods=["POST"])
def upload():
    try:
        if request.method == 'POST':
            # アップロードファイルを取得
            if not request.files or request.files['file'].filename == '':
                return jsonify(status=1, message='ファイルを指定してください'), 200

            uploaded_file = request.files['file']

            # S3アップロード処理
            s3 = boto3.client('s3',
                              region_name='ap-northeast-1',
                              aws_access_key_id='***aws_access_key_id***',
                              aws_secret_access_key='***aws_secret_access_key***'
                              )
            response = s3.put_object(
                Body=uploaded_file,
                Bucket=s3_bucket,
                Key=f's3/upload_path/' + uploaded_file.filename
            )
            if response['ResponseMetadata']['HTTPStatusCode'] != 200:
                return jsonify(status=1, message='S3へのアップロードでエラーが発生しました'), 200

            return jsonify(status=0, message=''), 200
    except Exception as e:
        logger.error(e)
        return jsonify(status=1, message=str(e)), 200