Web development with python #7 : File upload configuration and Validate file upload

in #utopian-io5 years ago (edited)

Repository

https://github.com/python

What Will I Learn?

  • File upload configuration
  • Validate and Save the file

Requirements

  • Basic Python
  • Install Python 3
  • Install Flask

Resources

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 need action.

  • 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:

Screenshot_3.png


  • 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 this ALLOWED_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.

Screenshot_4.png

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 parameter filename.

  • 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 validation allowed_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 on file = request.files['file']. So you can use file.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 functions os.path.join(app.config['UPLOAD_FOLDER'], filename). The first parameter is app.config['UPLOAD_FOLDER'] and the second parameter is filename.

After all the rarities have been completed, we can run our application and the results will be as shown below:

ezgif.com-video-to-gif.gif

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

Proof of work done

https://github.com/milleaduski/python-web-app

Sort:  

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!

Coin Marketplace

STEEM 0.31
TRX 0.11
JST 0.034
BTC 65139.82
ETH 3206.69
USDT 1.00
SBD 4.16