[Part-1] Building RESTful API’s for complete beginners.
If you’ve been doing any kind of data analysis or engineering for any length of time, you have probably worked with API’s to get data from. Today I want to explore how API’s are actually built and deployed, and some of the principles behind their design particularly under the REST paradigm.
As you probably know, API stands for Application Programming Interface. The entire purpose of an API is to simplify the use of a software system by creating an easy to use interface. In this way, we can rely on the functionality of the software without having to get into the nuts and bolts of its code and data. API’s can be thought of almost as an end-user product except they are geared more towards developers than consumers. API’s then are high level abstractions of specific software applications and domains, and as such their use is ubiquitous.
Typically, the use pattern of an API is as follows: The user submits some data to the API, the API uses this input data to generate/retrieve some other data, and the resulting data is output back to the user. If you think about it, this is really what most computing comes down to. You feed data into computers, you get a result. You feed data into a function, and it returns some value after executing its code. And if you’ve ever used an API, you can see the same principle: you specify some endpoints and queries and the API delivers you some data.
But you want to make your own API’s! Maybe you developed a machine learning model thats good at making predictions. Now you want to deploy it online so others can submit some data to your model and retrieve predictions. Or maybe you want to share data in a way that makes it easy for people to access, search and filter. These are typical use-cases for building API’s.
API’s run on a client-server model. The client (i.e. the user) sends a request over the internet (HTTP) to a server which is running our API program, which processes the request, generates output and the server sends it back to the user. There are many frameworks used to build web apps, but I will focus on how to use Flask. Flask is a python-based web framework that's relatively lightweight and easy to learn while being powerful and feature rich. We will additionally use the Flask-RESTful library which is a Flask extention designed specifically for building RESTful apps.
To start making your Flask powered API, start a clean repository with a clean virtualenv. Then, run “pip install flask” as well as “pip install flask-RESTful”. Then, create a file in your root folder called app.py. This is where we will write the code for the API itself.
Here is how your code should look like to start with:
First off, we import Flask. In line 3 we have to include the line app = Flask(__name__). This is a standard line that is included in all Flask apps. It instantiates as Flask object, which is what our app actually will be. It then passes the __name__ variable of our module into the Flask object. Recall that the __name__ assigned to our module at runtime can be different depending on whether the module was executed directly from the command line or imported. Its important to specify the module in this manner for Flask to properly templates, static files and so on.
Then from Flask_restful, we import Api and Resource. Api is the central class used by Flask-RESTful to implement API’s. We instantiate this after Flask, and we pass into it the Flask app we instantiate the line before (“app”). In this way, we are adding a kind of layer to our Flask app that allows us to better structure it as an API. While theoretically it would be possible to implement an API using Flask alone, the Flask-RESTful API makes it easier for us while conforming better to best practices under the REST paradigm.
The way we actually build our API then is to define “endpoints” and tell Flask how to route and process requests to those endpoints. This is done primarily by adding “resources” to our API that can then be accessed by going to the endpoints. A resource is a chunk of code that can respond to requests made to our API and deliver new data in response. In order to create these resource we have to subclass the “Resource” class we imported from flask_restful, and define get, post and similar methods corresponding to types of HTTP requests. We then have to add the resource to the API’s collection of resources.
Lets take a look at how to code this out:
First off, we created a dictionary of records which will serve as a testing database for us to just make sure if our API is working. The keys represent animals and the values represent the type of animal it is.
Then we created a new class called Creature, and passed in the Resource class to let python know that our class is to inherit all the methods and attributes of the Resource class. We need to do this in order to allow Flask-RESTful to integrate our logic into its framework and turn our subclass into a resource that can be handled by the server and the library.
Creatures takes in a variable called “name”, and it implements one method. This is the get method. We will talk in depth about the various types of requests in a later post, but for now just know that when you submit a url to the API to retrieve information in your browser, the type of request sent from your browser to the server is a “GET” type request. This is one of a set of standard types of server requests which also includes POST, PUT, DELETE and more. Each resource type class must contain a method corresponding to each type of request that can be forwarded to it. Since our class right now is only taking GET requests we only define the get method.
Integrating our resource class into the running API is achieved by the second-last line. We call the add_resource method on the api object and pass in our Creature class along with a string representation of the endpoint to which it should respond. This is the “‘/creature/<string:name>”. This string tells flask_restful which endpoint leads to the resource we passed in, i.e. the type of URL that the user must pass in to get to that resource. Furthermore, we can tell flask_restful to be on the lookout for variables the user might pass in using the <string:name> syntax as shown. This tells flask_restful that the user can pass in a string of their choosing, and flask is to store this string in the variable called “name”, which is then forwarded to the Creature class.
Now, all you have to do is go to your terminal, make sure you are in the root folder of your repository that has the “app.py” file, and then run the command “python app.py”. You will see output like this:
Go ahead and click that url in the last line. When it opens in the browser, don’t be concerned if you see a “not found” error message.
The reason you are getting this is because we havent really told flask or flask_restful to handle requests to the root url, and when you clicked the link your browser submit a get request to that link but since our server didnt know what to do with it, we got an error. But if you go ahead and add “creature/cat” to the end of the url, you should see:
Voila! We have a working API.
Now we have a basic understanding of how API’s work and how to get started building one. You must have realized however that storing data on in-memory dictionaries like we did here is not a feasible solution at any kind of scale. But you can see where we are heading: Now that we know how to create resources for delivering data and route endpoints to them, the sky is the limit. We can start using JSON files or SQL databases in our resources. But that’s for another day.
Tune in next week and we will dive deeper into the different types of requests and how we can handle them.