Flask将图像上传到S3而不保存到本地文件系统

时间:2019-03-22 04:35:12

标签: flask boto3

我需要将用户提交的照片上传到s3存储桶。但是我一直收到以下错误:

TypeError: expected str, bytes or os.PathLike object, not FileStorage

如何将文件存储为字符串/字节而不是文件存储?相关代码如下:

@user_api.route('upload-profile-photo', methods=['PUT'])
@Auth.auth_required
def upload_profile_photo():
  """
  Upload User Profile Photo
  """
  key = Auth.auth_user()
  bucket = 'profile-photos'
  content_type = request.mimetype
  image_file = request.files['file']
  client = boto3.client('s3',
                        region_name='sfo2',
                        endpoint_url='https://example.xxx.amazonaws.com',
                        aws_access_key_id=os.environ['ACCESS_KEY'],
                        aws_secret_access_key=os.environ['SECRET_KEY'])
  with open(image_file, "rb") as f:
    client.upload_fileobj(
        bucket,
        f,
        key,
        ExtraArgs={'ACL': 'public-read', 'ContentType': content_type}
    )

  return custom_response({'message': 'image uploaded'}, 200)

2 个答案:

答案 0 :(得分:2)

i为了通过FileStorage实现这一目标,我使用方法put_object()

from werkzeug import secure_filename

@user_api.route('upload-profile-photo', methods=['PUT'])
@Auth.auth_required
def upload_profile_photo():
    """
    Upload User Profile Photo
    """
    key = Auth.auth_user()
    bucket = 'profile-photos'
    content_type = request.mimetype
    image_file = request.files['file']

    client = boto3.client('s3',
                          region_name='sfo2',
                          endpoint_url='https://example.xxx.amazonaws.com',
                          aws_access_key_id=os.environ['ACCESS_KEY'],
                          aws_secret_access_key=os.environ['SECRET_KEY'])

    filename = secure_filename(file.filename)  # This is convenient to validate your filename, otherwise just use file.filename

    client.put_object(Body=image_file,
                      Bucket=bucket,
                      Key=filename,
                      ContentType=content_type)

    return custom_response({'message': 'image uploaded'}, 200)

请注意,对secure_filename()的调用是可选的(您可以简单地传递image_file.filename),但是可以很方便地验证文件名。  否则,最好添加一些异常处理,但是粗略的想法就在这里:无需open()文件(该文件需要存储在本地)。

我鼓励看看the documentation here,以了解与upload_fileobj()的区别

答案 1 :(得分:0)

  import boto3   
  s3 = boto3.client(
            "s3",
            aws_access_key_id= "*************",
            aws_secret_access_key="**********"
        ) 

  @login_blueprint.route('/uploadfile', methods=['POST'])
         file= request.files['file']
        
         try:
                    filename = secure_filename(file.filename)
                    acl="public-read"
                    s3.upload_fileobj(
                        file,
                        'bucket-name',
                        file.filename,
                        ExtraArgs={
                            "ACL": acl,
                            "ContentType":  file.content_type
                        }
                    )
        
         except Exception as e:
                    resp = jsonify(e)
                    resp.status_code =200
                    return resp