This article was contributed by Filestack, a developer set of tools and APIs that allow applications to upload, transform and deliver content efficiently.

One essential but common feature of web applications is to let the users upload files to the server.  Flask is a favorite web framework, and uploading using the flask upload file is fun. But there is much ambiguity in implementation details that fall outside the formal specification that is not clear to many developers.

Advertisement

Many essential things such as where to store uploaded files, how to use them afterward, or how to keep safe the server against malicious file uploads generate confusion and uncertainty and raise question marks. Here the Filestack comes into play.

The article is for you if you have a basic understanding of HTML and Python and looking for a robust solution for flask upload files.

This guide will walk you through several steps to set up a basic flask app that will allow users to upload files. Finally, we’ll show you how efficiently you can upload files using Filestack without facing the hassles mentioned above. After completing this guide, you will be experts in file uploading using Flask.

The goal is to build a flask app that will enable users to upload files to a server.

Before diving deep, we’ll let you know the basics of Flask. Let’s start!

What is Flask?

Flask is a lightweight web application framework based on the Werkzeug WSGI toolkit and Jinja2 template engine written in Python. It is extensible and doesn’t force a particular structure or require complicated code before getting started. It gives developers flexibility and a user-friendly experience.

What is a Python virtual environment & how do I create and activate a virtual environment?

A virtual environment is a module created by Python called virtualenv. A virtual environment gives a developer a unique environment that enables the installation of all unique packages for a particular project. It doesn’t change the default packages installed in the system.

Creating a virtual environment is different on the operating system installed on the system. In this tutorial, we will adhere to the context of a Windows operating system.

First, on a Windows device, open PowerShell and make a directory using the command below:

mkdir

Using the cd directory name, get into the new directory. Next, install the virtual environment using the command below:

pip install virtualenv

Create the virtual environment using the command:

virtualenv myenv

My virtual environment name is myenv; name it according to your wish.

Now, it’s time to activate the virtual environment using the command:

myenv/Scripts/activate

In case you are using the command-line interface (CMD), your command will be as below:

myenv\Scripts\activate.bat

Step 1 – How do I create the project?

When a virtual environment is activated, the following work is to create our project by doing a new directory.

Use the command below:

mkdir tutorial

Note that here tutorial is our project’s name. You can give yours.

Step 2 – How do I install Flask?

First, we must install Flask to build a flask application by using the command below:

pip install flask

After installation, create a new file with the name app.py, update the file with the code below:

from flask import Flask

app = Flask(__name__)


@app.route('/')
def index():
    return"hello world"

if __name__==('__main__'):
    app.run(debug=True)

We are importing Flask from the flask library installed from the above code.

Explanation :

The @app.route is performing the routine for us.

The index() is the view function that will return our page content to the browser.

Here, the if statement returns the app.run it will enable us to run our app and refresh the page when we save changes.

We run the command given below on our terminal to run our app.

python app.py

Note:  app.py is the name of my app. You can choose yours.

You can also learn more about Flask installation from here.

Step 3 – How do I install Flask-upload libraries?

We have to use the WTforms and the flask-uploads libraries to upload files.

Install with the command:

pip install flask_wtf, WTForms

pip install flask-uploads

Create a file field by updating the code to the one below:

from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import FileField

app = Flask(__name__)

class MyForm(FlaskForm):
    image = FileField('image')

@app.route('/')
def index():
    form = MyForm()
    return render_template('index.html')

if __name__==('__main__'):
    app.run(debug=True)

We will start from the code mentioned above by importing FlaskForm from flask_wtf and FileField from wtforms.

Then, we created a class for our form; here, Myform image is the file field that will save our image files. In our index function, we call our Form class and change our render to render a template.

Step 4 – How do I create the HTML template we are rendering?

It is also a flask library used for rendering HTML templates. We rendered index.html From the code.

By creating  render_template in Flask, we create a folder called templates where we store the HTML files. Next, let’s create the HTML template, render it inside our templates folder, and see what happens.

Now, update the HTML file with the code below:

!doctype html>

<html>

  <head>

    <title>File Upload</title>

  </head>

  <body>




    <form action="/" method="POST" enctype="multipart/form-data">

        {{ form.csrf_token }}

        {{ form.image }}

        <button type="submit">upload</button>

    </form>

  </body>

</html>

Our form takes a method POST from the code above because we will be posting a file. The csrf_token is a built-in function that provides security for us, and then we call our form field we created in our Form Class using form.image.

Now run the app using python app.py. If everything goes accordingly, you will get a runtime error.

This error often occurs whenever you try to use a csrf_token without adding a secret_key to your project file. Let’s add a secret key.

Step 5 – How do I add a secret key?

Update your code to the one below:

from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import FileField

app = Flask(__name__)

app.config['SECRET_KEY'] = 'mysecretkey'

class MyForm(FlaskForm):
    image = FileField('image')


@app.route('/')
def index():
    form = MyForm()
    return render_template('index.html')

if __name__==('__main__'):
    app.run(debug=True)

The secret_key can be anything you wish. Let’s update our code to the one given below:

from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import FileField

app = Flask(__name__)

app.config['SECRET_KEY'] = 'mysecretkey'

class MyForm(FlaskForm):
    image = FileField('image')

@app.route('/')
def index():
    form = MyForm()
    return render_template('index.html', form = form)

if __name__==('__main__'):
    app.run(debug=True)

From the code mentioned above, form=form is parsed because we want our form to be displayed on our HTML page. Now, if we’re going to upload an image, we will encounter another error.

This error may often encounter if we don’t specify a method for our route. We will add the code below to our route to solve this problem.

@app.route('/', methods=['GET', 'POST'])

Now our upload will work, but it won’t save it. The cause behind it is that we didn’t give it a path to save. This is where the flask upload file comes into play.

Step 6 – How do I import Flask upload file?

Let’s import flask-uploads using the command:

from flask_uploads import configure_uploads, IMAGES, UploadSet

Now we will update our code by: app.config[‘UPLOADED_IMAGES_DEST’] = ‘uploads/images this will set the file path where the images will be saved, images = UploadSet(‘images’, IMAGES) and configure_uploads(app, images) saves the file extension and configure the uploads.

if form.validate_on_submit():
        filename = images.save(form.image.data)
        return f'Filename: {filename}'
    return render_template('index.html', form = form)

The above snippet will validate and save our image file. This is our final code:

from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import FileField
from flask_uploads import configure_uploads, IMAGES, UploadSet

app = Flask(__name__)

app.config['SECRET_KEY'] = 'thisisasecret'
app.config['UPLOADED_IMAGES_DEST'] = 'uploads/images'

images = UploadSet('images', IMAGES)
configure_uploads(app, images)


class MyForm(FlaskForm):
    image = FileField('image')

@app.route('/', methods=['GET', 'POST'])
def index():
    form = MyForm()
    if form.validate_on_submit():
        filename = images.save(form.image.data)
        return f'Filename: {filename}'
    return render_template('index.html', form = form)

if __name__==('__main__'):
    app.run(debug=True)

 

Now we can upload images. To upload other types of files, you need to import them through flask upload, configure their destination path, and specify their file extension, as mentioned earlier.

You can also learn more about uploading files in the Flask official documentation.

Filestack File Upload Using Flask

You can install Filestack SDK from the source code.  We are running in the following docker environment:

FROM python:3.6.5

RUN pip install Flask==1.0.2 filestack-python==2.3.1

WORKDIR /usr/src/app/

COPY *.py ./
COPY templates/* ./templates/

ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
ENV FLASK_RUN_PORT=5000

CMD flask run

The template file for the rendered page:

<!DOCTYPE html>
<html>

  <head>
    <meta charset="UTF-8">
    <title>Filestack Demo</title>
    <script src="https://static.filestackapi.com/filestack-js/1.x.x/filestack.min.js"></script>
  </head>

  <body>
    <script>
      function openPicker() {
        // Load from the template variables
        const apiKey = "{{ api_key }}";
        const options = { "security": {} };
        options["security"]["policy"] = "{{ policy }}";
        options["security"]["signature"] = "{{ signature }}";

        const client = filestack.init(apiKey, options);
        client.picker().open();
      }
    </script>
    <button onclick="openPicker();">Select File</button>
  </body>

</html>

And here is our actual application: The library needs to be configured with your API key.

import time

from flask import Flask, jsonify, render_template
from filestack import security as create_security

api_key = 'YOUR_API_KEY'
app_secret = 'YOUR_APP_SECRET'
app = Flask(__name__)

# Creates credentials to perform an upload, valid for 15 minutes
def create_upload_creds():
    expiry = int(time.time()) + 15 * 60 # Policy is valid for 15 minutes
    json_policy = { 'call': ['pick'], 'expiry': expiry }
    sec = create_security(json_policy, app_secret)
    sec['policy'] = sec['policy'].decode('ascii')
    creds = { 'api_key': api_key }
    creds['policy'] = sec['policy']
    creds['signature'] = sec['signature']
    return creds

# This endpoint should be behind user auth
# Renders a simple page that contains the web picker
@app.route('/')
def render_picker():
    creds = create_upload_creds()
    return render_template('picker.html', **creds)

# This endpoint should be behind user auth
# Returns credentials as JSON
@app.route('/json')
def get_upload_creds():
    creds = create_upload_creds()
    return jsonify(creds)

Moreover, you can upload using Filestack Webhook Receiver

To receive a webhook from Filestack and validate them, use the following Python example by using Filestack Python SDK and Flask library.

Example Code:

from flask import Flask, request, abort
from filestack import Client

app = Flask(__name__)


@app.route('/webhook', methods=['POST'])
def webhook():
if request.method == 'POST':
resp = Client.verify_webhook_signature('<SECRET>', request.data, dict(request.headers))
if not resp['valid'] and resp['error'] is None:
    print('Webhook signature is invalid')
elif resp['error']:
    print('Please check input params: {}'.format(resp['error']))
else:
    print('Webhook is valid and was generated by Filestack')
return '', 200
else:
abort(400)


if __name__ == '__main__':
app.run()

That’s all.

Ready to Get Started With a Flask Upload File?

I hope you have learned about various file upload capabilities provided by Flask and the larger picture of how file uploads work.

Head over and get your FileStack Python SDK to get started.

Advertisement