Photo by Tianyi Ma on Unsplash

Creating Simple REST API Using Flask (Part 2)

Step-by-step tutorial on how to create simple REST API using Python, Flask and Heroku

yosiadityan
7 min readJan 3, 2021

--

Table of Contents

  • (Part 1) Setting Up Heroku Application
  • (Part 1) Adding Data to Heroku PostgreSQL Database Using SQLAlchemy
  • (Part 2) Creating Simple REST API Locally Using Python and Flask
  • (Part 2) Deploying REST API to Heroku

Previously, we have configured our Heroku application and added data to our database using Kaggle data-set. In this second part, we will try to create our REST API application locally in our computer and after that, we will deploy it on Heroku so we can access it globally. Let’s get on to the next step!

Creating Simple REST API Locally Using Python and Flask

In this step, we will try to build our REST API using Flask locally in our computer before deploying on Heroku. As I stated before, we will only create simple REST API that only handle GET request and serve data as requested.

We will create 6 endpoints for this tutorial:

  • / — Endpoint for root/index URL, will give response a list of tables available
  • /hp1/, /hp2/, /hp3/, /spells/, /potions/ — Endpoints for each table available in our database (Harry Potter 1, Harry Potter 2, Harry Potter 3, Spells, and Potions table)

Each endpoint (except root URL) will accept parameter(s) that is columns in each table. So, let’s say I want to get list of spells that has Blue light and type of Charm spells, that means we can pass Blue and Charm as parameter values of Light and Type since those are the name of columns available in Spells table. Using that scenario, our endpoint will look like this:

https://<URL>/spells/?light=blue&type=charm

Which then will give response list of Charm spells that have blue light. The parameters are stated after question mark (?) and each is separated by ampersand (&). The response will be in JSON format (Click here to read more about JSON format)

First, let’s try to code the index/root endpoint. Create new python file and import these modules:

Importing modules

requestwill be used to get the parameter passed in GET request, jsonify is used for creating JSON format of value passed in, and Flask-SQLAlchemy is basically the extension of SQLAlchemy for Flask application. It still has the same functionality as native SQLAlchemy, but it’s built with Flask integrity in mind by providing useful defaults and extra helpers.

Then, we need to create instance of our Flask app and some configurations as below:

Configuring the Flask app instance

In the code above, we load the .env configuration and set the SQLALCHEMY_DATABASE_URI based on that configuration. Configuration JSON_SORT_KEYS is used to return sorted JSON or not, in this case I set False which will return non-sorted JSON. Using Flask-SQLAlchemy, we connect to our database, create engine object and get the metadata values.

For API on index/root endpoint, we can use the code below:

Function for root endpoint

In Flask, each endpoint are defined by a function which wrapped with @app.route decorator. Inside the decorator, we need to pass the parameter of route path(endpoint) and method used to call this function. For root endpoint, we define the route path as ‘/’ and not specify any request method since this endpoint will serve any type of request. In the return statement, we pass the message : OK and list of tables in database. What we pass in return statement is the data that API will give back to requesting client when accessing this endpoint. You can change the return statement as you wish.

Then, we will need to define for other endpoints. These endpoints work in similar way. Each endpoint will responsible for serving data for each table. If there’s any parameter passed, it will check whether the parameter(s) are correct. We define the parameter’s name as the column name, so if client/user passed incorrect parameter’s name, our API will ignore it. Then, API will return list of correct parameters passed and list of data based on the correct parameters. To avoid repeating writing code, we will create one function to handle and apply it to all 5 endpoint. The function is as follow:

get_hp_data function

We name this function get_hp_data that take Table name as input parameter. We, then, create table instance using engine object and metadata created before. We also need to specify that it will only return back data for GET request only using if-else statement. First, we will do filtering for the parameter passed that only parameter’s name is same with column name in table, it will be identified as correct parameters. Next, we will query on database based on correct parameters and save it as Python dictionary called query_result . We will also add list of correct parameters passed in our return statement along with query_result dictionary.

Next, we will apply this function for every endpoint.

Applying get_hp_data function for every endpoint

For every endpoint, we specify the route path needed to access and methods needed. Then, in the return statement, we just need call get_hp_data function with input parameter as the table name in our database.

The last step in this section is create the main function to run all code.

Main function to run Flask app

Use run method on our Flask app instance. Set the debug as True, so you can see the difference when modifying the code without re-running the application again. You can specify other port number available in port parameter. Parameter threaded is used to enable multiple instances for multiple user access support.

Run the Python file, you’ve created before and open your web browser and access this link:

http://localhost:<flask-app-port>/

You will get to see the JSON returned in your web browser.

Accessing index endpoint (‘/’)

Try to access, the Harry Potter 2 data or other and also try to access using parameters.

Accessing Harry Potter 2 data (‘/hp2/’)
Accessing Spells data with parameter (‘/spells/??type=charm&light=blue’)

Looking good! Our REST API are now ready. Just one last part, deploying our REST API to Heroku! 😄

Deploying REST API to Heroku

Before starting deploying to Heroku, you will need to create your project folder as git repository (See this article on how to create git repository on your computer). We also need to install gunicorn package in our environment. gunicorn is WSGI web-server that to put it simply, takes care of everything happens in-between your server and your application.

We will also need two files for Heroku to understand what command to run the project (called Procfile) and what modules/packages needed to run the application (called requirements.txt). Create Procfile file (without extension) and type the command as follows:

web: gunicorn app:app

web means we will use Heroku’s web dyno since it’s a web server application and serving HTTP request. gunicorn app:app means we will using gunicorn module to run our application. The first app represents the Python file we will be running and the second app represent the Flask app instance that you wish to run.

For the requirements.txt you need to list all package needed to run this application. This can easily be done by using pip command:

pip freeze > requirements.txt

But, if you don’t use separate virtual environment, your requirements.txt file could list other packages that not used in this tutorial. Here’s what my requirements.txt looks like:

Great! Now, create git commit on your master branch for all those files (Procfile, requirements.txt, app.py). Next, we will need to login to our Heroku account from Heroku CLI using this command:

heroku login

A browser page will appear and ask you to login to Heroku account. After finished, add remote branch for Heroku by inputting this command:

heroku git:remote -a <your-heroku-app-name>

Then, push your master branch into Heroku’s master branch with this command:

git push heroku master

For the complete command to deploy your application on Heroku using Git, check “Deploy” on your app dashboard.

Deploy using Heroku Git

The command line then will give you message that it’s preparing packages and still in process of building your app.

Process deploying on Heroku

After deploying finish, go check your application as printed on terminal or just type in your browser:

https://<your-app-name>.herokuapp.com/

It will return the data for index/root endpoint.

Accessing index endpoint after deployed on Heroku

Try accessing other endpoints as well and passed in some parameters.

Accessing Harry Potter 3 data endpoint
Accessing Potions data endpoint with some parameters

Congratulation! 🎊 You have successfully create simple REST API using Flask and deploy it on Heroku. You can modify your API further, for example, by providing response for other HTTP request or create simple CRUD application using your API.

You can check the full code using in this tutorial in my repository here. I’m also open for discussion and feedback as well, just give comment below! 🍻

--

--