Flask Upload Image to S3 without saving it to local file system
iTo achieve that with a FileStorage
, I use the method put_object()
:
from werkzeug import secure_filename@user_api.route('upload-profile-photo', methods=['PUT'])@Auth.auth_requireddef 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(image_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)
Note the call to secure_filename()
is optional (you can simply pass image_file.filename
), but can be very handy to validate the filename. Otherwise it would be nice to add some exception handlings, but the rough idea is here: no need to open()
the file (that would need to be stored locally).
I encourage to have a look at the documentation here, to understand the difference with upload_fileobj()
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