Building your first REST API

How to build a REST API using Python and Flask

If, like me, you find the prospect of building your own API exciting but have no idea where to start — look no further. This article serves as a gentle guide towards building your own REST API using Python and the Flask framework.

The purpose of an API is to share data from one application to another.

Before we jump in, let’s get to know the Flask library a little better —

Flask is a Python library for web application development that was created as a beginner friendly “micro” framework that scales up well to more complex applications. Flask accelerates development, while staying as lightweight as possible. (Go check out the official Flask documentation for some more details. There are also some minimum viable product examples to get you started.)

Flask is also very beginner friendly — Coming from a data science background, I was able to create my first basic application after just a few hours of fiddling.

Now that that’s out of the way, let’s jump into actually creating our API.

The code

For this example, we will be building a simple API that will return a basic JSON payload with some mock data. We will also be securing our API using JWT authentication to ensure that no one can access the API without proper authentication.

The basic steps that we will be following when creating and securing our application:

  1. Step 1: Initialise the application
  2. Step 2: Create the routes (endpoints)
  3. Step 3: Secure the application using JWT

If you don’t have Flask installed, go ahead and do so. We will also be using the Flask JWT Extended library. This library will be doing most of the heavy lifting when securing the API using JWT — which means less coding for us.

pip install Flask
pip install flask-jwt-extended

We can now import the libraries that we need — we will be using jsonify to return a JSON payload, make_response to return a response with a valid HTML response status code and request to grab the authentication details that we pass as headers when we login.

# Import the relevant librariesfrom flask import Flask, jsonify, make_response, request
from flask_jwt_extended import jwt_required, create_access_token, JWTManager
import json

Once both libraries are installed and imported, we need to generate some mock data that we will be returning once the API is called, as well as some dummy authentication details. Normally, your authentication details will be stored in a database, but we will keep it simple for now by just hardcoding them.

# Generate the test payload
test_data = {
'test': ['this', 'is', 'a', 'test']
}
# Create the login details
username = 'admin'
password = 'password'

Step 1 — The next step is to create an initialise our application. We can then create our secret key that will be used for authentication. Normally, we would encrypt these using an algorithm (be sure to change your secret key to something more secure before deploying). We also set the validity period for the token as 3600 (1 hour). It’s up to you how long you want to set this validity period for, but it has to be long enough for a user to be able to make some subsequent calls before it expires.

# Initialise the application
app = Flask(__name__)
# Update the secret key
app.config['SECRET_KEY'] = 'my_precious'
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = int(3600)
# Setup the Flask-JWT-Extended extension
app.config["JWT_SECRET_KEY"] = "super-secret"
jwt = JWTManager(app)
JWTManager(app)

Now that we have initialised the application and modified the configuration, we can add routes. Routes are the endpoints that we will be accessing. For our example, we will be creating two routes —

  1. login (POST) — the endpoint that we will be accessing to generate the token
  2. get_data (GET) — the endpoint that we will be accessing to return the mock data

Step 2 — We can add our routes by using the “@app.route()” decorator function. We need to check that the credentials passed in the header matches the credentials that we created — if no credentials are specified, we reject the login and return a message asking the user to login. If the credentials match, we pass a valid token, indicating that the login was successful.

# Create the login route - this is a POST
@app.route('/login', methods=['POST'])
def login():
auth = request.authorization

if not auth or not auth.username or not auth.password:
return make_response('Could not verify your details'.format(auth, auth.username, auth.password),
401,
{'WWW-authenticate': 'Login required'})

user = username

if not user:
return make_response('Could not verify your details', 401,
{'WWW-authenticate': 'Login required'})
# Return a token if the login is successful
if password == auth.password:
token = create_access_token(identity=auth.username)
return jsonify(token=token)

Once we have logged in and received a token, we can call the “get_data” route by passing the token as a header. Let’s create the route.

@app.route('/get_data', methods=['GET'])
@jwt_required
def get():
return jsonify(test_data)

Step 3 — You’ll notice we added the “@jwt_required” decorator this time — this function specifies that this route is only accessible with a valid token. The flask-jwt-extended library handles the complexity for us and all we have to do is specify which routes we want to secure.

The last step is to run the app. We run it in debug mode for now, since this is an example.

# Run the application
if
__name__ == '__main__':
app.run(debug=True)

We now have a working application! Let’s test our API.

Photo by Caspar Camille Rubin on Unsplash

Testing the application using Postman

Now that our API is ready, we can run it by typing python main.py into the terminal.

Once the app is running successfully, you should see a message indicating that it is running on your local host. We can now test our API using Postman.

After configuring Postman with the local host URL — we first need to login to get a token using the “login” route that we created earlier. We can either login using basic authentication, or by passing a JSON object with the username and password. We will be passing the credentials as a JSON object in this example. (We won’t be covering Postman in too much detail, so check out this article if you need some help getting started)

# The authentication details
{
‘user’: ‘admin’,
‘password’: ‘password’
}

This returns a JSON object with a token that is valid for the next hour.

{"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MTM2ODIyMjgsIm5iZiI6MTYxMzY4MjIyOCwianRpIjoiN2E3YzU1NjktYjU1Ni00Zjk5LThhYWQtYjZiNzUxMDk2NWQxIiwiZXhwIjoxNjEzNjg1ODI4LCJpZGVudGl0eSI6ImFkbWluIiwiZnJlc2giOmZhbHNlLCJ0eXBlIjoiYWNjZXNzIn0.B2ukLRkZBfZHvcvoNw3MB6r1a5KlPww8Bnz9E6O2Ovo"}

Now that we have logged in and have a valid token, we can access the “get_data” route by passing this token as an argument. Since our token is valid, we receive the test payload as a response.

# This is the message that we get
{
"test": ["this","is","a","test"]
}

We have just successfully created our first REST API for data extraction!

Conclusion

That’s it for our very brief tutorial on creating our first REST API using Python and the Flask framework. Flask is a beginner friendly micro-framework that will help you build web applications that scale well. Using the steps laid out here, you will be well on your way to creating your own REST API.

An industrial engineer with a passion for data science.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store