Receive or Return files-Flask API

Serve files or Download files as output using Flask

Bala Murugan N G
Analytics Vidhya
6 min readJul 6, 2020

--

Here we are going to see “How to Return Single File and Multiple Files with Flask using Python”

Why this tutorial ???

Sometimes you want to allow users to download reports or files from your website or application is an often required feature of any website or application. . . ,

Workaround cycle to Download the Files

Flask provides us with some useful function to do so

After seeing people writing blogs about “Flask for Beginners” tutorial. I’ve noticed that, they didn’t cover the “Sending Files and allow users to download files”. So, I took an interest on writing about the “Serving Files”. I am sure this Blog walks you to “Serve Files” and makes you simple. . . ,

In my Previous blog, discussed about “Uploading File(s) to the Server

Why Chosen Flask ???

Though people say Flask is simple and easy to get started with while Django is heavy for building web applications.

Flask is a widely used micro web framework for creating APIs in Python. It is a simple yet powerful web framework which is designed to get started quick and easy, with the ability to scale up to complex applications.

From the documentation,

“Micro” does not mean that your whole web application has to fit into a single Python file (although it certainly can), nor does it mean that Flask is lacking in functionality. The “micro” in micro framework means Flask aims to keep the core simple but extensible.

Requirements and Installation

  1. Of course, We need Python 3.5 or above. But why?? see this
  2. Install Flask
pip install flask

# Simple Send file from Server using Flask

A simple File Send Python Script using Flask API . . ,

# servefile.pyfrom flask import Flask,send_from_directory

app = Flask(__name__)
# Specify directory to download from . . . DOWNLOAD_DIRECTORY = "<your folder directory>"

@app.route('/get-files/<path:path>',methods = ['GET','POST'])
def get_files(path):

"""Download a file."""
try:
return send_from_directory(DOWNLOAD_DIRECTORY, path, as_attachment=True)
except FileNotFoundError:
abort(404)


if __name__ == '__main__':
app.run(host='0.0.0.0', port = 8000, threaded = True, debug = True)

Run the Application by running “python servefile.py”. Go to browser and type “http://localhost:8000/get-files/<filename with extension>”.

If the Specified file that you mentioned in the URL is exists, you can download the file. Otherwise 404 error will occur . . ,

Download Sample file

# Returning Various File based on requests

File Downloading is the process of receiving the binary or normal files from the server. Flask facilitates us to Download the files easily.

Returning Various files based on the Routes

Create a file named “variousfiledownloadflask.py”

1. Importing the Libraries

from flask import Flask,send_file,send_from_directory

2. Create Instance and Specify the File Location

app = Flask(__name__)

# The absolute path of the directory containing images for users to download
app.config["CLIENT_IMAGES"] = "E:/AudiotoText/Flask_File_Downloads/filedownload/files/image"

# The absolute path of the directory containing CSV files for users to download
app.config["CLIENT_CSV"] = "E:/AudiotoText/Flask_File_Downloads/filedownload/files/csv"

# The absolute path of the directory containing PDF files for users to download
app.config["CLIENT_PDF"] = "E:/AudiotoText/Flask_File_Downloads/filedownload/files/pdf"

3. Application Routing

# Get CSV File Routing
@app.route('/get-csv/<csv_filename>',methods = ['GET','POST'])
def get_csv(csv_filename):

try:
return send_from_directory(app.config["CLIENT_CSV"], filename=csv_filename, as_attachment=True)
except FileNotFoundError:
abort(404)

# Get PDF file Routing
@app.route('/get-pdf/<pdf_filename>',methods = ['GET','POST'])
def get_pdf(pdf_filename):

try:
return send_from_directory(app.config["CLIENT_PDF"], filename=pdf_filename, as_attachment=True)
except FileNotFoundError:
abort(404)

# Get Image file Routing
@app.route("/get-image/<path:image_name>",methods = ['GET','POST'])
def get_image(image_name):

try:
return send_from_directory(app.config["CLIENT_IMAGES"], filename=image_name, as_attachment=True)
except FileNotFoundError:
abort(404)



if __name__ == '__main__':
app.run(host='0.0.0.0',port = 8000, threaded = True, debug = True)

Routes can accept the following variable types:

  • string: Accepts any text without a slash (by default).
  • int: Accepts positive integers
  • float: Accepts positive numerical values containing decimal points.
  • path: Similar to a string, but accepts slashes
  • uuid: Accepts UUID strings (Universally unique identifier) (e.g 118bc9c3–1af4–4d46–87a1–266db2e64e7a)

Unlike static routes, routes created with variable rules do accept parameters, with those parameters being the route variables themselves.

For example, if you define a url with <int:some_integer>, Flask will try to convert it into an integer, <path:path_to_some_file> will allow a path like string, including slashes etc..

Here is the Full code for Various File Formats

Run the Application by running “python variousfiledownloadflask.py”. Go to browser and type “http://localhost:8000/get-csv/<filename>”, you can download the specified CSV File . . . ,

Various file get using Routing

# Returning Multiple Files using Flask

Suppose, If we want to send Multiple files to someone, this will help you

You can’t send all files into downloadable one.But if you convert all the files into ZIP and then you can send it as one file(zip file)

Create a file named “multiplefiledownloadflask.py”

  1. Importing the Libraries
import zipfile
import os
from flask import send_file,Flask,send_from_directory

2. Create an Instance and Flask Routing

app = Flask(__name__)

@app.route('/download_files')
def download_all():
# Zip file Initialization
zipfolder = zipfile.ZipFile('Audiofiles.zip','w', compression = zipfile.ZIP_STORED) # Compression type

# zip all the files which are inside in the folder
for root,dirs, files in os.walk('<foldername>'):
for file in files:
zipfolder.write('<foldername>'+file)
zipfolder.close()

return send_file('Audiofiles.zip',
mimetype = 'zip',
attachment_filename= 'Audiofiles.zip',
as_attachment = True)

# Delete the zip file if not needed
os.remove("Audiofiles.zip")

if __name__ == '__main__':
app.run(host = '0.0.0.0', port = 8000 , debug= False, threaded = True)

Here, I am using ZIP_STORED Compression which means “Just Archiving without Compressing the files”

Some of the Compression Types are ZIP_STORED, ZIP_DEFLATED , ZIP_BZIP2, ZIP_LZMA

ZIP_STORED : It’s just archiving the Files and it’s a Lossless Compression one

ZIP_DEFLATED : This is usual ZIP Compression Method

ZIP_BZIP2: This method uses BZIP2 compression technique

ZIP_LZMA: This method uses LZMA compression technique

For Detailed info about Compression types, Here is the link

Complete code for Returning Multiple Files

Run the Application by running “python multiplefiledownloadflask.py”. Go to browser and type “http://localhost:8000/download_files”, you will get a Zip File as downloadable one . . . ,

Sample Output of Multiple File download

Note : Always use Incognito Mode,while downloading files because cache may cause to improper downloads . . .

The complete code is uploaded to the following GitHub repository

For Flask File Uploads, Check this . . ,

Conclusion

The article is a summary of “How to Return Single File and Multiple Files with Flask using Python”

Did you like this post and helpful to you . . .

Give me an Appreciation with Clap as much as you can and share

Thanks,

Bala Murugan N G

--

--

Bala Murugan N G
Analytics Vidhya

Currently Exploring my Life in Researching Data Science. Connect Me at LinkedIn : https://www.linkedin.com/in/ngbala6