Issue
I am developing an API in flask, and a feature that supports the API, is uploading an avatar image, in order to do this I read the img as base64 and I send the base64 code of the img to the backend.
Whit this the app.config["MAX_CONTENT_LENGTH"] = 0.1 * 1024 * 1024
is not working and I am sending images too long to the server.
The question is about what best practices can I use in order to enable an endpoint to upload a photo.
Is base64 the right option? should I need to compress the img in the backend?
thanks
Solution
Here's an example from Flask's documenation:
import os
from flask import Flask, flash, request, redirect, url_for
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = '/path/to/the/uploads'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
# If the user does not select a file, the browser submits an
# empty file without a filename.
if file.filename == '':
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('download_file', name=filename))
return '''
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form method=post enctype=multipart/form-data>
<input type=file name=file>
<input type=submit value=Upload>
</form>
'''
It should be quite approachable to modify / improve from this.
Edit after OP's comment
You can limit the upload size with the suggestions included in the Improving Uploads section of the documentation link I have sent.
I also paste the example here for simplicity:
from flask import Flask, Request
app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 16 * 1000 * 1000
In case it doesn't work for you and you want answers on that topic please narrow down the question to it.
In any case I will provide a pointer: did you set app.config['MAX_CONTENT_LENGTH'] right after initializing app (as in the example)?
About not keeping the upload filename you can change it in any way you prefer customizing this section:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('download_file', name=filename))
Reading your comment I assume you point to the fact that an API should never trust user input and for this reason in the documentation it is mentioned also the following:
So what does that secure_filename() function actually do? Now the problem is that there is that principle called “never trust user input”. This is also true for the filename of an uploaded file. All submitted form data can be forged, and filenames can be dangerous. For the moment just remember: always use that function to secure a filename before storing it directly on the filesystem.
Answered By - Pitto
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.