Handling file upload in Flask is very easy. It needs an HTML form with its enctype attribute set to ‘multipart/form-data’, posting the file to a URL. The URL handler fetches file from request.files[] object and saves it to the desired location.,Each uploaded file is first saved in a temporary location on the server, before it is actually saved to its ultimate location. Name of destination file can be hard-coded or can be obtained from filename property of request.files[file] object. However, it is recommended to obtain a secure version of it using the secure_filename() function.,It is possible to define the path of default upload folder and maximum size of uploaded file in configuration settings of Flask object.,Click Submit after choosing file. Form’s post method invokes ‘/upload_file’ URL. The underlying function uploader() does the save operation.
‘upload.html’ has a file chooser button and a submit button.
<html>
<body>
<form action="http://localhost:5000/uploader" method="POST" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" />
</form>
</body>
</html>
Following is the Python code of Flask application.
from flask
import Flask, render_template, request
from werkzeug
import secure_filename
app = Flask(__name__)
@app.route('/upload')
def upload_file():
return render_template('upload.html')
@app.route('/uploader', methods = ['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['file']
f.save(secure_filename(f.filename))
return 'file uploaded successfully'
if __name__ == '__main__':
app.run(debug = True)
Once you’re selecting a file, click Submit. The form’s post method calls the ‘/upload_file’ URL. The underlying function uploader() performs a save operation.,The default upload folder path and maximum size of uploaded files can be defined in the configuration settings for the Flask object.,It requires an HTML form whose enctype property is set to "multipart/form-data" to publish the file to the URL.The URL handler extracts the file from the request.files [] object and saves it to the required location.,The following code has a ‘/upload’ URL rule that displays’upload.html’ in the templates folder and the ‘/upload - file’ URL rule to invoke the upload () function to process the upload process.
1
app.config['UPLOAD_FOLDER']
app.config['MAX_CONTENT_PATH']
123456789
<html>
<body>
<form action="http://localhost:5000/uploader" method="POST" enctype="multipart/form-data"> <input type="file" name="file" /> <input type="submit" /> </form>
</body>
</html>
1234567891011121314151617
Let’s start with a very basic application that uploads a file to a specific upload folder and displays a file to the user. Let’s look at the bootstrapping code for our application:,Next the functions that check if an extension is valid and that uploads the file and redirects the user to the URL for the uploaded file:,Because the common pattern for file uploads exists almost unchanged in all applications dealing with uploads, there are also some Flask extensions that implement a full fledged upload mechanism that allows controlling which file extensions are allowed to be uploaded.,So you’re interested in what that secure_filename() function does and what the problem is if you’re not using it? So just imagine someone would send the following information as filename to your application:
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>
'''
filename = "../../../../home/username/.bashrc"
>>> secure_filename('../../../../home/username/.bashrc')
'home_username_.bashrc'
from flask import send_from_directory
@app.route('/uploads/<name>')
def download_file(name):
return send_from_directory(app.config["UPLOAD_FOLDER"], name)
app.add_url_rule(
"/uploads/<name>", endpoint="download_file", build_only=True
)
#15 Dy said 2020-08-19T09:01:57Z , #19 hyunsoojeon said 2020-08-29T15:09:38Z , #17 Mukesh Kumar said 2020-08-24T09:11:09Z , #20 Miguel Grinberg said 2020-08-29T22:52:47Z
Thank you
for this wonderful article
many thanks
Awesome post Miguel, really great work
Excellent.My Flask teacher.
This is an amazing blog post!
A couple of additional thoughts:
It could be a good addition to introduce a check, whether the file already exists - before trying to save it(not necessarily
for the avatar use
case, though: -))
Recently, I started answering Flask questions on StackOverFlow, and I noticed, that seemingly nobody writes tests nor knows how to use a debugger.
This may be related to the fact that both Python and Flask are very beginner friendly.But maybe it is also related that even the very high quality Flask tutorials hardly ever mention those techniques.
What do you think about adding a box "Advanced ...."
which
would sketch how to write a test
for your tutorial ?
Also, lots of these Flask questions on StackOverFlow are like "I followed this tutorial but it does not work for me".Usually, this can be easily resolved with a debugger.
At last weeks "Python Ireland Monthly Meetup"
I delivered a Lightning Talk about debugging a Flask application(https: //www.youtube.com/watch?v=Fxkco-gS4S8 ). While a five minute talk only can give a quick overview, maybe this could be an idea for a future blog post of yours? :-)
All the best, and maybe we see each other at the next "Python Ireland Monthly Meetup" ? It was such a fun evening.
@Jürgen: Adding an "Advanced"
section would scare people off, nobody would read that part of the tutorial.: )
While I agree that testing isn 't covered in most tutorials, in my experience you can'
t just force people to write automated tests.This is something that a beginner will see no need
for, only at some point the idea will "click"
and tests will start to make sense.I have some ideas
for a tutorial on testing Flask apps, so at some point that 's going to appear on this blog.
Saving the uploaded file using a Flask View, The reduce() function in Python,Now add the following code in your Flask application,Form View displays the Form.
<html>
<body>
<form action="http://localhost:5000/endpoint" method="POST" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
f = request.files['file']
f.save(f.filename)
f = request.files['file']
f.save(secure_filename(f.filename))
<html>
<body>
<form action="http://localhost:5000/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="File" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
from flask
import Flask, render_template, request
from werkzeug
import secure_filename
@app.route('/form')
def form():
return render_template('form.html')
@app.route('/upload', methods = ['POST', 'GET'])
def upload():
if request.method == 'POST':
f = request.files['file']
f.save(secure_filename(f.filename))
return "File saved successfully"
app.run(host = 'localhost', port = 5000)