upload and download files using flask

Flask is one of the most popular frameworks for backend development. It is a microframework based on the python programming language. Instead, a micro-framework Flask is very powerful and is highly extensible. Since Python is popular for Machine Learning and Data Science, Flask is hugely used to serve Machine Learning and Data Science related apps. In this tutorial, we will learn how to create a file uploader and file downloader using Flask.

File Uploading and downloading is an important task for a website. For example, assume that we were building a site that takes some images from user uploads and converts them into a single PDF. After converting the images into PDF, the website serves the PDF to the user. We need to learn to upload and download files using server-side frameworks like Flask in such a scenario.

Flask installation

We can install Flask easily with the help of the pip tool. PIP is a command-line tool, and it is the default package manager for managing python packages. To install the Flask framework, we need to run the following command in the terminal.

pip install flask

On running the above command in the terminal, we will have Flask installed in our system. We can check our installation by opening the python shell and importing the Flask library. See the below image for illustration.

checking the installation of flask by importing the library
checking the installation of Flask by importing the library

Now, let us create our file uploader using Flask.

Creating the File Uploader

The first step while creating our file uploader is to build the Html form. To publish the file, we need to set the enctype property of the form to "multipart/form-data". First, create a templates folder in the current directory. After that, create a file with the name upload.html in the templates folder and copy the following HTML code into the upload.html file.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>File uploader</title>
  </head>
  <body>
    <form
      action="http://localhost:5000/upload"
      method="POST"
      enctype="multipart/form-data"
    >
      <input type="file" name="file" />
      <input type="submit" />
    </form>
  </body>
</html>

After creating the HTML template for the file uploader, now, in the main directory, create a file with the name app.py. The app.py file contains the code for our Flask application. We will also use the secure_filename() function of the werkzeug module. The secure_filename() module checks for vulnerability in the uploaded files and protects the server from dangerous files. Copy the following code into the app.py file.

# importing the required libraries
from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
# initialising the flask app
app = Flask(__name__)

# The path for uploading the file
@app.route('/')
def upload_file():
   return render_template('upload.html')

@app.route('/upload', methods = ['GET', 'POST'])
def uploadfile():
   if request.method == 'POST': # check if the method is post
      f = request.files['file'] # get the file from the files object
      f.save(secure_filename(f.filename)) # this will secure the file
      return 'file uploaded successfully' # Display thsi message after uploading
		
if __name__ == '__main__':
   app.run() # running the flask app

In the above code, we first imported the required modules to our code. After importing the required modules, we initialize the Flask app by calling the Flask() constructor. Next, we use python decorators to define the routes for our Flask app and serve the HTML template that we created. Next, we use python decorators to accept the post request for the file and save the file.

You can run the above code by just typing python app.py in the terminal. We will see something as shown in the below image while running the above code.

starting the flask server
starting the Flask server

Now, visit the URL http://127.0.0.1:5000/ where you will see a file uploader as shown in the below image.

a simple upload webpage in flask
a simple upload webpage in Flask

Upload a sample file by choosing a file and clicking the submit button. After submitting the file, we will get a message showing that the file has been successfully uploaded. We can check the file in the server by visiting the root directory.

Configuring the upload folder

We created a file uploader that saves the uploaded file in the root directory. We can also configure the directory for saving the file by configuring the app.config[‘UPLOAD_FOLDER’] variable. At first, the uploaded file is saved into a temporary location, and then it moves to the final location. The following code shows how to configure the upload directory.

# importing the required libraries
import os
from flask import Flask, render_template, request
from werkzeug.utils import secure_filename

# initialising the flask app
app = Flask(__name__)

# Creating the upload folder
upload_folder = "uploads/"
if not os.path.exists(upload_folder):
   os.mkdir(upload_folder)

app.config['UPLOAD_FOLDER'] = upload_folder

# The path for uploading the file
@app.route('/')
def upload_file():
   return render_template('upload.html')

@app.route('/upload', methods = ['GET', 'POST'])
def uploadfile():
   if request.method == 'POST': # check if the method is post
      f = request.files['file'] # get the file from the files object
      # Saving the file in the required destination
      f.save(os.path.join(app.config['UPLOAD_FOLDER'] ,secure_filename(f.filename))) # this will secure the file
      return 'file uploaded successfully' # Display thsi message after uploading
		
if __name__ == '__main__':
   app.run() # running the flask app

In the above code, we use the OS module of python to create a directory and saves every uploaded file to the created directory. If we restart the server and upload a file to the server, the file will be uploaded to the created directory instead of the root directory.

Configuring the maximum file size

We can also configure the maximum upload size of the file. This is important because if the file is too large for the server, then the site may crash. So, we need to always limit the upload size of the file according to our server. To configure the maximum file size, we need to set the app.config[‘MAX_CONTENT_LENGTH’] variable to the maximum size of the file in bytes. For example, if we want to limit the maximum size of the file to 1 Mb, we need to add the following line of code in our program.

app.config['MAX_CONTENT_LENGTH'] = 1 * 1024 * 1024

After setting the maximum file size of the file in our python program, if we upload a file having a size of more than 1 Mb, then we will get the error as shown in the below image.

setting the maximum upload size of a file in flask
setting the maximum upload size of a file in Flask

Configuring the allowed file extensions

While building a file uploader using Flask, we can also configure the file extensions that we want to upload. To configure the allowed file extensions, we need to create a list of allowed extensions and check the uploaded file extension in the list. The below code shows a practical illustration of the method.

# importing the required libraries
import os
from flask import Flask, render_template, request
from werkzeug.utils import secure_filename

# initialising the flask app
app = Flask(__name__)

# Creating the upload folder
upload_folder = "uploads/"
if not os.path.exists(upload_folder):
   os.mkdir(upload_folder)

# Max size of the file
app.config['MAX_CONTENT_LENGTH'] = 1 * 1024 * 1024

# Configuring the upload folder
app.config['UPLOAD_FOLDER'] = upload_folder

# configuring the allowed extensions
allowed_extensions = ['jpg', 'png', 'pdf']

def check_file_extension(filename):
    return filename.split('.')[-1] in allowed_extensions

# The path for uploading the file
@app.route('/')
def upload_file():
   return render_template('upload.html')

@app.route('/upload', methods = ['GET', 'POST'])
def uploadfile():
   if request.method == 'POST': # check if the method is post
      f = request.files['file'] # get the file from the files object
      # Saving the file in the required destination
      if check_file_extension(f.filename):
         f.save(os.path.join(app.config['UPLOAD_FOLDER'] ,secure_filename(f.filename))) # this will secure the file
         return 'file uploaded successfully' # Display thsi message after uploading
      else:
         return 'The file extension is not allowed'
		
if __name__ == '__main__':
   app.run() # running the flask app

In the above code, we create a function that will check the uploaded file extension and compare it with the allowed extensions. If we upload a file that does not have the extension of PDF, JPG, PNG, then the server will show the message as shown in the below image.

restricitng the upload of certain file extension in flask
restricting the upload of certain file extensions in Flask

Multiple file uploading using Flask

Till now, we have seen how to upload a single file to our server. But sometimes, we also want to upload multiple files to the server. To upload multiple files to our server first, we need to add multiple=”true” as an attribute to the input element of the Html form. See the below code for illustration.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>File uploader</title>
  </head>
  <body>
    <form
      action="http://localhost:5000/upload"
      method="POST"
      enctype="multipart/form-data"
    >
      <input type="file" name="files", multiple="true" />
      <input type="submit" />
    </form>
  </body>
</html>

After creating the Html form, we need to make some changes to our Flask application file. First, copy the following Python code into your Flask app file.

# importing the required libraries
import os
from flask import Flask, render_template, request
from werkzeug.utils import secure_filename

# initialising the flask app
app = Flask(__name__)

# Creating the upload folder
upload_folder = "uploads/"
if not os.path.exists(upload_folder):
   os.mkdir(upload_folder)

# Configuring the upload folder
app.config['UPLOAD_FOLDER'] = upload_folder

# configuring the allowed extensions
allowed_extensions = ['jpg', 'png', 'pdf']

def check_file_extension(filename):
    return filename.split('.')[-1] in allowed_extensions

# The path for uploading the file
@app.route('/')
def upload_file():
   return render_template('upload.html')

@app.route('/upload', methods = ['GET', 'POST'])
def uploadfile():
   if request.method == 'POST': # check if the method is post
      files = request.files.getlist('files') # get the file from the files object
      print(files)
      for f in files:
         print(f.filename)
         # Saving the file in the required destination
         if check_file_extension(f.filename):
            f.save(os.path.join(app.config['UPLOAD_FOLDER'] ,secure_filename(f.filename))) # this will secure the file

      return 'file uploaded successfully' # Display thsi message after uploading
		
if __name__ == '__main__':
   app.run() # running the flask app

In the above code, we use python for loop to iterate over the list of files and then save each file one by one. We can choose multiple files now and upload them at once to the server.

Serving the files

We have seen how to upload files using Flask, but sometimes we also want to serve a file to the user. To serve a file from our server to the user, we need to use the send_file() function of the Flask. First, create an HTML template in the templates folder, named the file download.html, and add the following code into the Html file.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>File Downloader</title>
  </head>
  <body>
    <a href="/download"><button class='btn btn-default'>Download</button></a>
  </body>
</html>

The above HTML code will create a button with the label Download and add a link to the button that refers to the route /download. Now, we need to create our app.py file. In our app.py, we need to use the send_file() function and pass the file’s path to it. Then, copy and paste the following code in the app.py file.

# importing the required libraries
import os
from flask import Flask, render_template, request, send_file

# initialising the flask app
app = Flask(__name__)

# displaying the HTML template at the home url
@app.route('/')
def index():
   return render_template('download.html')

# Sending the file to the user
@app.route('/download')
def download():
   return send_file('sample.pdf', as_attachment=True)

if __name__ == '__main__':
   app.run() # running the flask app

After copying the above code, run the code by typing the command python app.py. If everything works fine and the server starts without any problem, we have created our file downloader. Now, visit the URL http://127.0.0.1:5000/, you will see something as shown in the below image.

creating a file downloader using flask
creating a file downloader using Flask

If you click the download button present in the URL, then the file will start downloading. For the above code to work properly, we need a file with the name sample.pdf in the app directory.

Conclusion

In this tutorial, we learned to create a file uploader and file downloader using the Flask library. In addition, we have seen how to configure the max size and extension of the file upload. You may also want to see our step-by-step guide on creating a Flask app in python.

Similar Posts

2 Comments

Leave a Reply to Ayoub Cancel reply

Your email address will not be published. Required fields are marked *