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.

static/
myapp.py
runapp.sh

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__)


@app.route('/get_csv')
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
    try:
        month = int(request.args["month"])
    except:
        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)


@app.route('/')
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 http://127.0.0.1:5000/ (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 🙂