Writing an API in Python (with Flask and RapidAPI)





If you are reading this article, you are probably already familiar with the possibilities that open up using the API (Application Programming Interface).



By adding one of the many open APIs to your application, you can expand the functionality of this application or supplement it with the necessary data. But what if you developed a unique feature that you want to share with the community?



The answer is simple: you need to create your own API .



Despite the fact that at first it seems a daunting task, in fact, everything is simple. We’ll show you how to do this with Python.



What you need to get started



To develop the API you need:





Installation is performed by the command:



pip install flask-restful
      
      





Recommended free intensive programming for beginners:

Telegram bot development in C # - August 26–28. Free intensive that allows you to understand how the assistant bots work, the features of working with the Telegram API and other nuances. The three best participants will receive 30,000 rubles from Skillbox .

Before you start



We are going to develop a RESTful API with basic CRUID functionality .



To fully understand the problem, let's look at the two terms mentioned above.



What is REST?



The REST API (Representational State Transfer) is an API that uses HTTP requests to exchange data.



REST APIs must meet certain criteria:





What is a CRUD?



CRUD is a programming concept that describes four basic actions (create, read, update, and delete).



In the REST API, request types and request methods are responsible for actions such as post, get, put, delete.



Now that we’ve figured out the basic terms, we can start creating the API.



Development



Let's create a repository of quotes about artificial intelligence. AI is one of the fastest growing technologies today, and Python is a popular tool for working with AI.



With this API, a Python developer can quickly get information about AI and be inspired by new developments. If the developer has valuable thoughts on this topic, he will be able to add them to the repository.



Let's start by importing the necessary modules and configuring Flask:



 from flask import Flask from flask_restful import Api, Resource, reqparse import random app = Flask(__name__) api = Api(app)
      
      





In this snippet, Flask, Api, and Resource are the classes we need.



Reqparse is the Flask-RESTful request parsing interface ... You will also need the random module to display a random quote.



Now we will create an AI quotes repository.



Each repo entry will contain:





Since this is just an example for training, we will save all entries in the Python list. In a real application, instead, we would most likely use a database.



 ai_quotes = [ { "id": 0, "author": "Kevin Kelly", "quote": "The business plans of the next 10,000 startups are easy to forecast: " + "Take X and add AI." }, { "id": 1, "author": "Stephen Hawking", "quote": "The development of full artificial intelligence could " + "spell the end of the human race… " + "It would take off on its own, and re-design " + "itself at an ever increasing rate. " + "Humans, who are limited by slow biological evolution, " + "couldn't compete, and would be superseded." }, { "id": 2, "author": "Claude Shannon", "quote": "I visualize a time when we will be to robots what " + "dogs are to humans, " + "and I'm rooting for the machines." }, { "id": 3, "author": "Elon Musk", "quote": "The pace of progress in artificial intelligence " + "(I'm not referring to narrow AI) " + "is incredibly fast. Unless you have direct " + "exposure to groups like Deepmind, " + "you have no idea how fast — it is growing " + "at a pace close to exponential. " + "The risk of something seriously dangerous " + "happening is in the five-year timeframe." + "10 years at most." }, { "id": 4, "author": "Geoffrey Hinton", "quote": "I have always been convinced that the only way " + "to get artificial intelligence to work " + "is to do the computation in a way similar to the human brain. " + "That is the goal I have been pursuing. We are making progress, " + "though we still have lots to learn about " + "how the brain actually works." }, { "id": 5, "author": "Pedro Domingos", "quote": "People worry that computers will " + "get too smart and take over the world, " + "but the real problem is that they're too stupid " + "and they've already taken over the world." }, { "id": 6, "author": "Alan Turing", "quote": "It seems probable that once the machine thinking " + "method had started, it would not take long " + "to outstrip our feeble powers… " + "They would be able to converse " + "with each other to sharpen their wits. " + "At some stage therefore, we should " + "have to expect the machines to take control." }, { "id": 7, "author": "Ray Kurzweil", "quote": "Artificial intelligence will reach " + "human levels by around 2029. " + "Follow that out further to, say, 2045, " + "we will have multiplied the intelligence, " + "the human biological machine intelligence " + "of our civilization a billion-fold." }, { "id": 8, "author": "Sebastian Thrun", "quote": "Nobody phrases it this way, but I think " + "that artificial intelligence " + "is almost a humanities discipline. It's really an attempt " + "to understand human intelligence and human cognition." }, { "id": 9, "author": "Andrew Ng", "quote": "We're making this analogy that AI is the new electricity." + "Electricity transformed industries: agriculture, " + "transportation, communication, manufacturing." } ]
      
      





Now we need to create a resource class Quote, which will determine the operations of the endpoints of our API. Four methods must be declared inside the class: get, post, put, delete.



Let's start with the GET method.



It makes it possible to get a specific quote by specifying its ID or a random quote if the ID is not specified.



 class Quote(Resource): def get(self, id=0): if id == 0: return random.choice(ai_quotes), 200 for quote in ai_quotes: if(quote["id"] == id): return quote, 200 return "Quote not found", 404
      
      





The GET method returns a random quote if the ID contains a default value, i.e. When calling the method, no ID was set.



If it is set, then the method searches among quotes and finds one that contains the specified ID. If nothing is found, the message “Quote not found, 404” is displayed.



Remember: the method returns an HTTP status of 200 if the request is successful and 404 if the record is not found.



Now let's create a POST method to add a new quote to the repository



It will receive the identifier of each new quote as you type. In addition, POST will use reqparse to parse the parameters that will go in the request body (author and citation text).



 def post(self, id): parser = reqparse.RequestParser() parser.add_argument("author") parser.add_argument("quote") params = parser.parse_args() for quote in ai_quotes: if(id == quote["id"]): return f"Quote with id {id} already exists", 400 quote = { "id": int(id), "author": params["author"], "quote": params["quote"] } ai_quotes.append(quote) return quote, 201
      
      





In the code above, the POST method accepted the quote ID. Then, using reqparse, he got the author and a quote from the query, storing them in the params dictionary.



If a quote with the specified ID already exists, then the method displays the corresponding message and code 400.



If a quote with the specified ID has not yet been created, the method creates a new record with the specified ID and author, as well as other parameters. He then adds an entry to the ai_quotes list and returns an entry with a new quote along with 201.



Now create a PUT method to modify an existing quote in the repository.



 def put(self, id): parser = reqparse.RequestParser() parser.add_argument("author") parser.add_argument("quote") params = parser.parse_args() for quote in ai_quotes: if(id == quote["id"]): quote["author"] = params["author"] quote["quote"] = params["quote"] return quote, 200 quote = { "id": id, "author": params["author"], "quote": params["quote"] } ai_quotes.append(quote) return quote, 201
      
      





The PUT method, similar to the previous example, takes ID and input and parses quote parameters using reqparse.



If a quote with the specified ID exists, the method will update it with new parameters, and then display an updated quote with the code 200. If there is no quote with the specified ID, a new record will be created with the code 201.



Finally, let's create a DELETE method to remove a quote that is no longer inspirational.



 def delete(self, id): global ai_quotes ai_quotes = [qoute for qoute in ai_quotes if qoute["id"] != id] return f"Quote with id {id} is deleted.", 200
      
      





This method gets the quote ID as you type and updates the ai_quotes list using a common list.



Now that we have created all the methods, all we need to do is just add the resource to the API, set the path and run Flask.



 api.add_resource(Quote, "/ai-quotes", "/ai-quotes/", "/ai-quotes/<int:id>") if __name__ == '__main__': app.run(debug=True)
      
      





Our REST API Service is ready!



Next, we can save the code in the app.py file by running it in the console using the command:



 python3 app.py
      
      





If all is well, then we get something like this:



* Debug mode: on

* Running on 127.0.0.1 : 5000 / (Press CTRL + C to quit)

* Restarting with stat

* Debugger is active!

* Debugger PIN: XXXXXXX



Testing API



After the API is created, it needs to be tested.



This can be done using the curl console utility or the Insomnia REST client or by publishing the API to the Rapid API.







Publish our API



RapidAPI is the world's largest marketplace with more than 10,000 APIs (and about 1 million developers).



RapidAPI not only provides a single interface for working with third-party APIs, but also provides the ability to quickly and easily publish your own API.



In order to do this , you first need to publish it on some server on the network. In our case, we will use Heroku . Working with him should not cause any difficulties ( you can learn more about him here ).



How to publish your API on Heroku



1. Install Heroku.



The first step is to register and install the Heroku Command Line Interface (CLI). This works on Ubuntu 16+.



sudo snap install heroku --classic



Then log in:



heroku login



2. Add the necessary files.



Now you need to add the files for publication to the folder in our application:





The requirements.txt file will contain the following lines:





Please note: we added gunicorn (Python WSGI HTTP Server) to the list, since we need to run our application on the server.



Procfile will contain:



web: gunicorn app: app



The content of .gitignore:



 *.pyc __pycache__/
      
      





Now that the files are created, let's initialize the git repo and commit:



 git init git add git commit -m "First API commit"
      
      





3. Create a new Heroku application.



 heroku create
      
      





Send master branch to Heroku remote repo:



 git push heroku master
      
      





Now you can start by opening the API Service using the commands:



 heroku ps:scale web=1 heroku open
      
      





The API will be available at your-random-heroku-name.herokuapp.com/ai-quotes .



How to add your Python API to the RapidAPI marketplace



After the API service is published on Heroku, you can add it to the Rapid API. Here is the detailed documentation on this topic.



1. Create a RapidAPI account.







Register a free account - this can be done using Facebook, Google, GitHub.







2. Add the API to the control panel.







3. Next, enter general information about your API.







4. After clicking “Add API” a new page appears where you can enter information about our API.







5. Now you can either manually enter the API endpoints, or download the swagger-file using OpenAPI.







Well, now we need to set the endpoints of our API on the Endpoints page. In our case, the endpoints correspond to the concept of CRUD (get, post, put, delete).







Next, you need to create the endpoint GET AI Quote, which displays a random quote (in case the ID is default) or a quote for the specified ID.



To create an endpoint, click the “Create Endpoint” button.







Repeat this process for all other API endpoints. That's all! Congratulations, you have published your API!



If all is well, the API page will look something like this:







Conclusion



In this article, we explored the process of creating your own RESTful API Service in Python, along with the process of publishing an API to the Heroku cloud and adding it to the RapidAPI directory.



But in the test case, only the basic principles of API development were shown - such nuances as security, fault tolerance and scalability were not considered.



When developing a real API, all this must be taken into account.



All Articles