How to Build a REST API with Python | Towards Data Science

How can we set up a way to communicate from one software instance to another? It sounds simple, and — to be completely honest — it is.
All we need is an API.
An API (Application Programming Interface) is a simple interface that defines the types of requests (demands/questions, etc.) that can be made, how they are made, and how they are processed.
In our case, we will be building an API that allows us to send a range of GET/POST/PUT/PATCH/DELETE requests (more on this later), to different endpoints, and return or modify data connected to our API.
We will be using the Flask framework to create our API and Postman to test it. In short, we will cover:
> Setup  - Our Toy Data  - Initialize a Flask API  - Endpoints  - Running a Local Server> Writing Our API  - GET  - POST  - 401 Unauthorized  - PUT  - DELETE  - Users Class (summary)> That's It!
Our API will contain two endpoints, users and locations. The former will allow access to our registered user's details, whereas the latter will include a list of cafe locations.
The hypothetical use-case here is of a multi-million cafe bookmarking app, where users open the app and bookmark their favorite cafe’s — like Google Maps, but not useful.
For the sake of simplicity, we are going to store this data in two local CSV files. In reality, you probably want to take a look at something like MongoDB or Google Firebase.
Our CSV files look like this:
You can download users.csv here, and locations.csv here.
Now to our Python script, we need to import modules and initialize our API, like so:
from flask import Flaskfrom flask_restful import Resource, Api, reqparseimport pandas as pdimport astapp = Flask(__name__)api = Api(app)
As we already touched on, our API will have two endpoints, users and locations.
The result of this is — if our API was located at www.api.com, communication with the Users class would be provided at www.api.com/users and Locations at www.api.com/locations.
To create an endpoint, we define a Python class (with any name you want) and connect it to our desired endpoint with api.add_resource, like this:
Flask needs to know that this class is an endpoint for our API, and so we pass Resource in with the class definition.
Inside the class, we include our HTTP methods (GET, POST, DELETE, etc.).
Finally, we link our Users class with the /users endpoint using api.add_resource.
Because we want two endpoints, we replicate the logic:
Finally, when we write out our API, we need to test it!
To do this, we need to host our API, which we can do locally by adding app.run to the end of our script like this:
if __name__ == '__main__':    app.run()  # run our Flask app
Now, when we run our script, we should see something like this:
Once our server is setup, we can test our API as we build it using Postman, if you haven’t used it before it is the de-facto standard for API testing. And, don’t worry — it’s incredibly simple to use — download Postman from here.
Before going ahead, you can find the full script that we will be building here. If you’re not sure where a code snippet should go, check there!
Inside each of our classes, we keep our HTTP methods, GET, POST, and DELETE.
To create a GET method, we use def get(self). POST and DELETE follow the same pattern.
The GET method is the simplest. We return all data stored in users.csv wrapped inside a dictionary, like so:
We can then run the script to initialize our API, open Postman and send a GET request to our localhost address (typically http://127.0.0.1:5000)— this is our API entry point.
To send a GET request to our API in Postman we:
Select GET from the dropdownType the entry point of our API instance + /users (the endpoint)Hit SendCheck the status code returned by our API (we should see 200 OK)View our API’s response, which is users.csv in JSON (like a dictionary) format
Select GET from the dropdown
Type the entry point of our API instance + /users (the endpoint)
Hit Send
Check the status code returned by our API (we should see 200 OK)
View our API’s response, which is users.csv in JSON (like a dictionary) format
The POST method allows us to add records to our data. In this case, we will take arguments for usedId, name, and city.
These arguments are passed to our API endpoint as URL parameters, which look like this:
http://127.0.0.1:5000/users?userId=abc123&name=The Rock&city=Los Angeles
We can specify the required parameters, and then parse the values provided using reqparse — like this:
Let’s break our parser code down:
We initialize our parser with .RequestParser().
Add our arguments with .add_argument([arg_name], required) — note that required=True means that the argument is required in the request. Alternatively, we can add optional arguments with required=False.
Parse our arguments and their values into a Python dictionary using .parse_args().
We can then access the values passed to each argument like we usually would with key-value pairs in a dictionary.
Let’s put those together to add values to our CSV:
If it’s starting to look a little more confusing — all we’re doing is:
Creating a row of new data new_data from the URL parameters args
Appending it to the pre-existing data
Saving the newly merged data
And, returning data alongside a 200 OK status code.
We can now send a POST request to create a new user, easy!
Our code handles POST requests, allowing us to write new data to users.csv — but what if that user already exists?
For that, we need to add a check. If the userId already exists, we return a 401 Unauthorized code to the user.
Going back to Postman, we can test if our API is functioning by trying to add the same user twice — this time, The Rock received a 401 Unauthorized response.
What if we want to add a cafe to a user? We can’t use POST as this returns a 401 Unauthorized code — instead, we use PUT.
Similar to POST, we need to add if-else logic in the case of the provided userId not existing.
Other than a couple of small tweaks to the code, our PUT method is almost identical to POST.
Back in Postman, our required input parameters have changed. Now, we only need userId and a location to add to the users bookmarked locations.
We can also delete records with the DELETE method.
This method is pretty straightforward, we need to specify a userId to remove, and add some if-else logic in the case of a non-existent userId.
So if Jill decides our app is useless and wants to leave, we would send a DELETE request containing her userId.
We can test this in Postman, and as expected, we return our data without Jill’s record. What if we try and delete a non-existent user?
Again, we receive our 404 Not Found and a brief message explaining that the userId was not found.
That’s all of the parts that make up the Users class, accessed via our /users endpoint. You can find the full script for it here.
After that, we still need to put together the Locations class. This other class should allow us to GET, POST, PATCH (update), and DELETE locations.
Each location is given a unique ID — when a user bookmarks a location, that unique ID is added to their locations list with PUT /users.
The code for this is not that much different from what we wrote in the Users class so that we won't repeat ourselves. However, you can find it alongside the Users class here.
It’s as simple as that. Setting up an API with Flask and Python is incredibly straightforward.
We now have an easy-to-use and standardized method for communicating between different interfaces.
We’ve covered all of the most common request methods — GET, POST, PUT, and DELETE — and a few HTTP status codes too — 200, 401, and 404.
Finally, we’ve learned how to host our API locally and test it with Postman — allowing us to quickly diagnose issues and ensure our API is behaving as intended.
All-in-all, API development is a crucial skill for developers, data scientists, and almost any other tech-inclined role you can imagine.
If you want more, I post programming tutorials on YouTube here. Or, if you have any questions or ideas for improvement, let me know on Twitter or in the comments below.
I hope you enjoyed the article and thank-you for reading!
Looking at taking the next steps in API development and sharing your work with the world? Read about API deployment with Google Cloud Platform here: