Flask 101: Serve CSV Files

Welcome to part 5 of the the Flask 101 Series. 


  1. Flask 101: Create a Basic Python Web App
  2. Flask 101: Add JSON to your Python Web App
  3. Flask 101: Use HTML templates & send variables 
  4. Flask 101: Serve Images 
  5. Flask 101: Serve CSV Files – This tutorial


For this tutorial, we will  dynamically serve a different csv file – corresponding to the daily weather in Montreal in 2019 – where the month is provided by the user as a parameter in the request. For instance, if the user types the following request

Then our Flask app will serve the file 2019_02_weather.csv which looks like this

As usual, the full code for this project is available on my GitHub repo.


1 – Setup

If you want to use a Python 3 virtual environment, you can follow this post for example. But all you really need is to install Flask

# Install flask
pip install flask

Create the following directory and files, leave them empty for now. We fill fill them later.


For this example, you will need to download the monthly weather csv files that your app will serve, and save them inside the static/ directory. For simplicity you can just download the ones on my GitHub repo here.

Your full project tree should now look like this

├── myapp.py  # to be completed later in this post
├── runapp.sh # to be completed later in this post as well
└── static
    ├── 2019_01_weather.csv
    ├── 2019_02_weather.csv
    ├── 2019_03_weather.csv
    ├── 2019_04_weather.csv
    ├── 2019_05_weather.csv
    ├── 2019_06_weather.csv
    ├── 2019_07_weather.csv
    ├── 2019_08_weather.csv
    ├── 2019_09_weather.csv
    ├── 2019_10_weather.csv
    ├── 2019_11_weather.csv
    └── 2019_12_weather.csv


2 – Create your flask application

Open the file named myapp.py that you have created above, and add the content below.

from flask import Flask, request, send_file
import io
import os
import csv 

app = Flask(__name__)

def get_csv():
    Returns the monthly weather csv file (Montreal, year=2019)
    corresponding to the month passed as parameter.

    # Checking that the month parameter has been supplied
    if not "month" in request.args:
        return "ERROR: value for 'month' is missing"
    # Also make sure that the value provided is numeric
        month = int(request.args["month"])
        return "ERROR: value for 'month' should be between 1 and 12"

    csv_dir  = "./static"
    csv_file = "2019_%02d_weather.csv" % month
    csv_path = os.path.join(csv_dir, csv_file)
    # Also make sure the requested csv file does exist
    if not os.path.isfile(csv_path):
        return "ERROR: file %s was not found on the server" % csv_file
    # Send the file back to the client
    return send_file(csv_path, as_attachment=True, attachment_filename=csv_file)

def myapp():
    message = "To use this app: %s/get_csv?month=value" % request.base_url
    return message


3 – Run your app

In the same directory as myapp.py, create a file named runapp.sh with the following contents.

export FLASK_APP=myapp
export FLASK_ENV=development
flask run

Close the file, then in the command line, run it with

# Execute this in the command line inside the same directory 
bash runapp.sh

You should see the following output

* Serving Flask app "myapp" (lazy loading)
* Environment: development
* Debug mode: on
* Running on (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 319-407-766


5 – Test your app

That’s it! Now you can modify the code to fit your own purposes 🙂