Web development with python #7 : File upload configuration and Validate file upload
Repository
What Will I Learn?
- File upload configuration
- Validate and Save the file
Requirements
- Basic Python
- Install Python 3
- Install Flask
Resources
- Python - https://www.python.org/
- Flask - http://flask.pocoo.org/
- Jinja2 -http://jinja.pocoo.org/docs/2.10/
- Bootstrap -https://getbootstrap.com/docs/3.3/getting-started/
Difficulty
Basic
Tutorial Content
This tutorial is still continued from the previous tutorial about flask. For those of you just following this tutorial, I suggest you look at the previous tutorials in the curriculum section. In this tutorial, we will learn how to upload a file in the flask. Not only that in this tutorial we will also learn how to create an abort page when a user is lost. Well, let's just start this tutorial.
Upload File
- Form Interface
The first step we have to do is prepare the interface first to upload the file. here I will make a simple page. That is upload.html. In this file I will create an interface consisting of forms and other inputs, the following is an example:
upload.html
<!DOCTYPE html>
<html>
<head>
<title>Upload page</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<h1>Upload file</h1>
<form enctype="multipart/form-data" method="post">
<input type="file" name="file">
<input type="submit" name="" value="Upload" class="btn btn-primary">
</form>
</body>
</html>
I will make a simple form to upload the file, to upload files we need to use
enctype = "multipart / form-data"
and the method used is the post method. Because we will upload files on the same page, we don't needaction
.The name we will use in backup is a file, pay attention to this code ```<input type="file" name="file.
Route upload file
After creating the next form interface, I will create a new routing that will be used to access the upload.html page. the following is routing for /upload
:
app.py
@app.route('/upload', methods=["GET", "POST"])
def uploadFile():
return render_template('upload.html')
In this routing, we make get and post methods
We define a new function to route
/upload
, that is uploadFile(). In this function, we will render the upload.html. We can see as the picture below:
- Secure file and allowed extension
Before we upload files, there are some things we have to do, the first is that we have to secure the file, we will use the library from werkzeug.utils
.For more details, we can import it as follows
app.py
from werkzeug.utils import secure_filename
From the library we have imported, we will only use the secure_filename.
Then we can set the extension that is allowed from the file we are uploading, for more details, we can see the following code:
ALLOWED_EXTENSION = set(['png', 'jpeg', 'jpg'])
@app.route('/upload', methods=["GET", "POST"])
def uploadFile():
return render_template('upload.html')
- for extension sets you can use the
set()
function and can be filled with arrays if the extension is more than one type like thisALLOWED_EXTENSION = set(['png', 'jpeg', 'jpg'])
.
- Set Folder target
What will be done next is to create a target folder where the file will be saved. to save in a folder with the correct path, we need to import the os. os is used to set the relative path. we will see its usefulness when we process the file.
from flask import Flask, render_template, request, make_response, session, url_for, redirect, flash
import os
from werkzeug.utils import secure_filename
app = Flask(__name__)
app.secret_key = '34ujeifaj21mkll'
ALLOWED_EXTENSION = set(['png', 'jpeg', 'jpg'])
app.config['UPLOAD_FOLDER'] = 'uploads'
@app.route('/upload', methods=["GET", "POST"])
def uploadFile():
return render_template('upload.html')
to import the os, we can do it like this
import os
.then provide a folder to save the file to be uploaded, We can make a configuration with the name upload folder and the destination folder as follows
app.config['UPLOAD_FOLDER'] = 'uploads'
. The name of the folder is uploads.
Save file to the folder
We have done some configuration in the code above, now it's time to make the file upload function to the destination folder. What will be done first is to check what method the user is using. But before we save the file we will create a function that is useful to check whether the file is valid:
- Validate file
This function aims to check whether the file uploaded by the user is valid. The following is checking the file.
# check file before save
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSION
We create a function called
allowed_file(filename)
and we can pass the file as parameterfilename
.There are some tricks that can be used.
Check whether the upload is a file: we can use '.' in filename
. because the file must have extensions that are separated by .
and
then separate the extension file with the file name and then the extension file with this filename.rsplit('.', 1)
. then we can check whether the extension of the file is allowed on ALLOWED_EXTENSION
. We need to know ALLOWED_EXTENSION is a variable that is used to set file types that are allowed ALLOWED_EXTENSION = set(['png', 'jpeg', 'jpg'])
.
- Save File
After finishing configuring and validating, we are now ready to code upload files,
def allowed_file():
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSION
ALLOWED_EXTENSION = set(['png', 'jpeg', 'jpg'])
app.config['UPLOAD_FOLDER'] = 'uploads'
@app.route('/upload', methods=["GET", "POST"])
def uploadFile():
if request.method == 'POST':
file = request.files['file']
if 'file' not in request.files:
return redirect(request.url)
if file.filename == '':
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 "Your file has been saved.." + filename
return render_template('upload.html')
We will check whether the method used by the user is the POST method. because we will only upload if the file has been POST
if request.method == 'POST':
We will also respond if the file does not exist.
if 'file' not in request.files:
return redirect(request.url)
- We will respond if the file name is empty
if file.filename == '':
return redirect(request.url)
And then if the file exists
if file
and the file passes validationallowed_file(file.filename)
, we will continue the file upload process.After passing validation, the file name must be secured with a function
secure_filename()
to save files, you can use the
save()
function based onfile = request.files['file']
. So you can usefile.save()
.And then we can get the file in the function
request.files['file']
. the'file'
is the name of the element in interface or frontend. so you can match the name. In the function save we will join the path and the name of the file that we uploaded. We can use functionsos.path.join(app.config['UPLOAD_FOLDER'], filename)
. The first parameter isapp.config['UPLOAD_FOLDER']
and the second parameter isfilename
.
After all the rarities have been completed, we can run our application and the results will be as shown below:
We can see in the picture above, we have successfully uploaded a file in the web application that we have created, you can set your own configuration according to your needs. I end this tutorial. hopefully, it will be useful for you. thank you
Curriculum
Web developement with python #1 : Flask initialization and Routing system
Web development with python #2 : Templating jinja2 and Method POST on routing system
Web development with python #3 : Get method, Query parameter and Navigate Routing
Web development with python #4: Store cookie and Get cookie in template
Web development with python #5: Session in flask and Login and Logout system
Web development with python #6 : Use flash message and combine it with framework boostrap
Thank you for your contribution @duski.harahap.
After analyzing your tutorial we suggest the following points listed below:
Improve your language in the tutorial. Your tutorial has some errors and sometimes it gets a bit confusing.
The subject of your tutorial is basic and is easily found online. Try to bring content that is interesting to the open-source community.
In code sections, we suggest posting comments. This will help less experienced users better understand what they are developing.
Nice work on the explanations of your code, although adding a bit more comments to the code can be helpful as well.
Thank you for taking note of these points in your next tutorial.
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]
Thank you for your review, @portugalcoin! Keep up the good work!
Hi @duski.harahap!
Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server
Hey, @duski.harahap!
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!