I need to upload a a user submitted photo to an s3 bucket. However I keep getting the following error:
TypeError: expected str, bytes or os.PathLike object, not FileStorage
How am I able to store the file as string/bytes instead of FileStorage? The relevent code is as follows:
@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)
To upload folders and files to an S3 bucketSign in to the AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3/ . In the Buckets list, choose the name of the bucket that you want to upload your folders or files to. Choose Upload.
Updated: September 13, 2022. Amazon S3 Direct Upload for Web UI is an addon that allows Web UI to make use of S3 Direct Upload to directly upload files to a transient bucket, which will then be moved by the Nuxeo server to a final bucket once the upload is finished.
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_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(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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With