Earthquake API Tutorial. Using Flask

James Lewis
8 min readJun 5, 2021

Hey there! Welcome to my blog where I post about my journey as a self-taught developer. You can find my GitHub by clicking HERE.

Photo by Jarrett Mills on Unsplash

Welcome to my first tutorial! I am very excited about this one since I love working with API’s. Especially free API’s that do not require any credit card information! What are we building in this tutorial? Check out the video below!

We pull filtered data from a government site that tracks earthquakes. We list and export real natural disaster data to a CSV file. Pretty cool right? Heck ya it is! Let’s get to it. You will be using the following stack in this tutorial.

  1. Python & Flask
  2. Additional modules in Python — nothing pip can’t solve.

Let’s make our file tree. Open your terminal. I am using git bash on windows. These commands may not work for every platform.

mkdir app
cd app
mkdir static templates blueprints csv
touch app.py __init__.py
cd blueprints
touch user.py api.py
cd ..cd templates
mkdir includes
touch index.html layout.html
cd includes
touch _footer.html
cd ..
cd ..
ls

Alright! The file tree is made. Well done. You should now see the directories we’ve created running ls.

If you’re not familiar with the command line, cd means change directory. The two ‘..’ (periods) will take you one directory up. And touch will create a file, based off of the extension provided. Then, mkdir is for make directory. Last, the ls command will show you all files and folders in your current directory. This is a very easy and fast way to create a file tree for a new codebase. We can’t right click New File forever!

Let’s install Flask!

pip install flask

Now, in your app.py and blueprint files we need to scaffold a bit. This is generally considered boilerplate code. We are setting up our project so it can talk and communicate correctly on your localhost in the browser.

This type of pattern is referred to as the Application Factory Pattern. It is common, well thought out and you will come across this convention often. Especially in the wild with production codebases where a web app has a tremendous amount of web pages!

Flask is an extremely flexible Python framework. It gives developers ultimate freedom in deciding how to structure their code. Blueprints are a way developers can package their code based off of features, business hierarchy, admin roles, and really anyway they want.

At the moment, we have an api blueprint and a user blueprint. Why is this significant? This means we can put all of our routes for api related logic into blueprints/api.py! And the same goes for blueprints/user.py. We achieve cleaner code by preparing our codebase early on. Dividing our routes based off of business hierarchy / roles help us and it is possible via blueprints in Flask. Let’s set them up now.

User Blueprint:

Api Blueprint:

Notice our routes are now decorated with the name of the Blueprint and are no longer decorated with ‘@app’.

Let’s dive into the user Blueprint and the template html files it renders.

templates
|________/index.html
|________/layout.html
|________/includes
|________/_header.html
|________/_footer.html

The above files are the files we will be looking at next. Let’s start from top to bottom so our html has the Bootstrap4 CDN for easy responsive styles.

index.html

layout.html

_footer.html

What about the header? Well, we could have implemented the Bootstrap 4 CSS CDN in a _header.html file, but as you can see, it is in the layout.html. Just a matter of preference in this case.

Now one last piece of code to add and we can render the index.html page on our localhost! Let’s do this now.

In your user.py file, locate the home function. Add the following code.

Screenshot by Author — James Lewis

Let’s fire up our app!

Windows 10 — Git Bash (These are the commands I am able to run)

export FLASK_APP=app.py
export FLASK_DEBUG=1
Flask Run

If export does not work to set your environment variables, please see below:

PowerShell — Stackoverflow

  • Try $env:FLASK_APP=app.py

Windows CMD — Stackoverflow

  • Try set FLASK_APP=app.py

Whichever environment you have, please make “run” lowercase. I’ve noticed I get an error if I use capitalization of any kind for the run command.

Flask run

Flask has a default port of 5000. So open a new window in your browser and type the following.

localhost:5000

You should see the following page, our index.html

Screenshot by Author — James Lewis

Well done! You have made it this far. In the next portion of this tutorial, we will be focusing on the USGS Earthquake API, implementing that in flask and exporting data to a CSV.

Quick Note! The API we are using is courtesy of:

The U.S. Geological Survey. Department of the Interior/USGS. Visit them HERE for additional documentation on their API! They do require to be cited if you are using this in production. FYI.

Okay, let’s tackle the api blueprint. Here is the code below.

Screenshot by Author — James Lewis

WOW! Okay, lots of code and a decent amount to go through. Let’s go over the imports, response object and iteration. You already know what a blueprint is now!

When working API’s in Python, there is a module well suited for requesting API data. It is not dependent on Flask, but built into Python and we can import it like this.

import requests

We also will need to import another built in module, called json.

import json

And one more! CSV.

import csv

Awesome, well done. Because we are using both a GET and POST request for this function to work, we must tell our api route what HTTP requests should be enabled.

methods=['GET', 'POST']

Remember our dropdown in the index.html form? We provided that <select> form field a name of ‘duration’. In order to pull that desired value into our Flask route we can use:

request.form["duration"]

Let’s give this desired form input a variable name of duration. We will also give our API URL a variable name of response. Notice we are using f strings in Python to easily insert variables into the URL. Most API’s will need parameters to specify what criteria the user wants to receive. In this case, it takes one to determine whether we want to return all of the Earthquakes from California within the last hour, or the last day.

Now, we clean the data and make it easier to handle. JSON is a great syntax that is text only. It is easy to read, understand and manipulate with our code.

data = json.loads(response.text)

Helpful definition from Python Native below.

The json.loads() is used to convert the JSON String document into the Python dictionary”

Our variable data is a python dictionary which we can loop through to grab the desired results in our html and csv file. When using this API, data[“features”] is what we are after, if you returned just the data in html there would be things such as FeatureType, and metadata. Information we are not interested in for this tutorial.

Look at the following portion of code below, once more.

Screenshot by Author — James Lewis

Arrays have a built in function called append. This is powerful because you can append strings, integers, and floats. But you can also append objects such as an entire dictionary.

We iterate through the data[“features]”. And we are only interested in the earthquakes that occur in California (common earthquake state…) we are checking to see if the string ‘CA’ appears in each of the recorded earthquakes.

If it does, we append only those California earthquakes to the results array in the form of a dictionary thus making our array an array of dictionaries.

Now, we can return a template and pass our results to a results variable. See below.

Screenshot by Author — James Lewis

Let’s get some results!

In your results.html file, paste the following code.

Alright! When we run our app on the home page (localhost:5000), select either of the two options in the select field and click on “Get Data”. You will see results!

Try it out!

Screenshot by Author — James Lewis

Congratulations, you just pulled data from a real world API with Python and Flask. Well done! So, what’s next?

Let’s export to a CSV. Code below.

Screenshot by Author — James Lewis

This code will eventually go into our api.py, but let’s cover a few things first. The csv module in python has a few functions that help us out. Definitions below are taken directly from the docs!

  1. writer“Return a writer object responsible for converting the user’s data into delimited strings on the given file-like object”
  2. writerow“Write the row parameter to the writer’s file object, formatted according to the current dialect. Return the return value of the call to the write method of the underlying file object.”

Writerow will allow us to provide the column names for our data and regarding our results array, we can loop through it now providing each row of data for the 3 columns we have named.

Full code of api.py below!

Screenshot by Author — James Lewis

Let’s wrap up this tutorial with final thoughts on the Download CSV button. There is one specific import we can use that is dependent on Flask. You’ll notice we have imported…

from flask import send_from_directory

This is a cool technique because HTTP will not work with two return statements in a route. How can we generate the eq.csv file in the csv directory AND render the results.html template in the same route.

This is how we solve this small edge case.

This is the final updated user blueprint. We have created a function called csv.

We have also imported send_from_directory at the top.

We can create a separate function and return send_from_directory by passing in two parameters.

return send_from_directory('DIRECTORY NAME', 'FILE NAME INSIDE', options[])

We created the directory csv at the beginning of this tutorial. And when we ran the csv logic inside our api.py the eq.csv was created and placed in our csv directory. Now, we can just pass the directory and the file inside that directory to send_from_directory! I also added additional parameters, but the first two must be the directory and then the file.

Well done! This was a long tutorial, but by now you should be familiar with the following:

  • Flask Blueprints
  • Modules (request, csv, json)
  • A few techniques for looping in Flask
  • send_from_directory (Also check out send_file — similar)

If there is something missing from the code, preventing a successful page load on your localhost please let me know. I will do my best to update the post quickly. Thanks!

Thanks for reading! I hope you learned something going through the USGS Earthquake API. Until next time.

Final Code on GitHub HERE.

Happy Coding!

--

--

James Lewis

I am an obsessive autodidact, I love coffee, early mornings, guitar, camping, traveling with my wife and of course…software development!