≡ Menu

REST API Jumpstart Guide with Python REST web-service Example

[REST API Python]REST stands for Representational State Transfer.

It is an architectural style, set of rules to standardize the web, to maintain uniformity across web applications worldwide. It intends to enhance maintainability, scalability, reliability and portability of web applications.

Main idea behind REST is resources. Everything you want to access in a web application is a resource, whether it is a media or documents you want to download, update, delete. REST defines a way to access, transfer, and modify these resources.

This tutorial covers the following three high-level concepts:

  • REST Basic Concepts – This section explains the 6 key rest architectural constraints
  • Key elements of RESTFul implementation – This section the 6 different elements of a RESTful implementation
  • Create a Python REST web-service – This sections gives a step-by-step instruction on creating a basic REST web-service in python

REST Basic Concepts

The following are few architectural constraints that will make any web service RESTful, as discussed by Roy Fielding, inventor of REST in his research paper.

1. Client Server

This constraint states that client and server implementation should be independent, both should be able to scale, evolve independently of each other. Client should only know URI of resource on server nothing else. Server should return the appropriate response based on received request from the client.

2. Stateless

Client-server interaction should be stateless in nature. Server should not store state data and response should totally depend upon the information present in the request from client. Client can however store keep session state data. This enhances scalability, reliability of interactions.

3. Cache

Cache comes into the picture to solve the issue of stateless nature of REST. This cache is implemented on client end, and cacheable response is cached. If in future client request some data for which it had already sent a request, instead of sending the request to server again, cache can reuse the cached response.

4. Uniform Interface

This states the need of uniform interface between components, every resource in server should have only one logical URI and should expose methods to access this resource, and it should follow standard naming conventions. All resource should be accessed using common approach. This enhances visibility of web interfaces.

5. Layered System

Layered system approach states that web service should follow layered approach, i.e. we should divide our web service in different layers that cannot see beyond their immediate layer, e.g. authentication layer, data access layer, message processor layer. This reduces system complexity and improves scalability.

6. Code on demand

This states that occasionally client can download executable code instead of static data, i.e. JSON/XML. It increases system extensibility.

Key Elements of RESTFul implementation

1. Resource

The basic idea behind REST is resource, everything stored in REST web service data store is a resource. In current context articles stored in TGS data store is a resource. We can access this resource using URI https://www.thegeekstuff.com/category/python/

2. Request Verbs

These defines the way to access the resources, what client wants to do with them is specified with the request verbs, these are basic methods

  1. GET: This will be used to get articles from data store of TGS web application.
  2. POST: This will be used to create a new article in TGS web application.
  3. PUT: This will be used to update any existing article or create a new if it does not exist in TGS data store.
  4. DELETE: This will be used to delete an article from TGS data store.

3. Request Headers

Extra request sent to server to specify type of response, encoding, and content type and customized parameters. Etc.

4. Request Body

When trying to create a resource, the resource data is sent in body of put request.

5. Response Body

Web server returns data in body of the response. Suppose client sent a GET to query data for python category, web server will return data in response body.

6 Response Codes

These coded returned with the response, and signifies the status of the request sent to the server. These similar to HTTP response code. E.g. 200 OK denotes request succeeded, 404 NOT FOUND denotes resource not found on server.

Create a Python REST web-service

Let’s create a simple REST web service using flask in python, we could consume this web service using Postman tool or Curl command line utility.

If you are new to Python, refer to this: 5 Examples to Jumpstart Object Oriented Programming in Python

Our resource in this service will be articles, it will store all the articles published on TGS, in following format

  • Category
  • Views
  • Title

We will expose REST endpoints to add, modify, delete, and update the articles. CRUD functionality over REST.

Let’s start step by step:

1. Import Flask Module

First, import flask module inside the code and name our web service as shown below.

from flask import Flask
from flask_restful import Resource, reqparse , api

TGS = Flask(__name__)
api = Api(TGS)

2. Create Resource Articles

Next, create resource articles, it will be a simple List of articles , we can also use a database to store out resource.

articles = [
{
"category": "python",
"views": 100,
"title": "Dictionary"
},
{
"category": "java",
"views": 200,
"title": "java10"
},
{
"category": "elastic",
"views": 300,
"title": "elasticsearch"
}
]

3. Create API End Points and REST Methods

Next, we need to create the api endpoints and the required REST methods as show below.

GET method will search requested category in list of articles, and will return the data if found along with response code 200 OK. Otherwise 404 not found

class Article(Resource):
def get(self, category):

POST method will insert new article data in list of articles and returns inserted data with response code 201 created. If record already exists it returns error code 400 bad request.

def post(self,category):

PUT method will overwrite the record and return the data along with response code 200 OK. If record does not exist, it creates the data and returns it with response code 201 created.

def put(self,category):

DELETE method deleted the record if exist and returns the data with response code 200 OK. Otherwise 404 not found.

def delete(self,category):

4. Register Resource and Assign URI

Our final step is registering our resource to REST API and assign a URI to it.

api.add_resource(Article, "/category/<string:category>")

TGS.run(debug=True,port=8080)

Full REST Sample Program

Create rest.py file:

vi rest.py

Copy/paste the following to the rest.py file:

from flask import Flask
from flask_restful import Resource, reqparse ,Api

TGS = Flask(__name__)
api = Api(TGS)

articles = [
    {
        "category": "python",
        "views": 100,
        "title": "Dictionary"
    },
    {
        "category": "java",
        "views": 200,
        "title": "java10"
    },
    {
        "category": "elastic",
        "views": 300,
        "title": "elasticsearch"
    }
]

class Article(Resource):
    def get(self, category):
        for article in articles:
            if(category == article["category"]):
                return article, 200
        return "category not found", 404

    def post(self, category):
        parser = reqparse.RequestParser()
        parser.add_argument("views")
        parser.add_argument("title")
        args = parser.parse_args()

        for article in articles:
            if(category == article["category"]):
                return "category  {} already exists".format(category), 400

        article = {
            "category": category,
            "views": args["views"],
            "title": args["title"]
        }
        articles.append(article)
        return article, 201

    def put(self, category):
        parser = reqparse.RequestParser()
        parser.add_argument("views")
        parser.add_argument("title")
        args = parser.parse_args()

        for article in articles:
            if(category == article["category"]):
                article["views"] = args["views"]
                article["title"] = args["title"]
                return article, 200

        article = {
            "category": category,
            "views": args["views"],
            "title": args["title"]
        }
        articles.append(article)
        return article, 201

    def delete(self, category):
        global articles
        articles = [article for article in articles if article["category"] != category]
        return "{} is deleted.".format(category), 200

api.add_resource(Article, "/category/<string:category>")

TGS.run(debug=True,port=8080)

Test the REST Program

Let’s test this using Curl utility, we could use postman utility also it’s a great tool.

Start the python glass REST server

$ python rest.py
* Serving Flask app "rest" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Restarting with stat
* Debugger is active!
* Debugger PIN: 145-292-899
* Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)

1. GET articles from python category of TGS

$ curl -XGET http://127.0.0.1:8080/category/python
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
Dload  Upload   Total   Spent    Left  Speed
100    74  100    74    0     0  74000      0 --:--:-- --:--:-- --:--:-- 74000{
"category": "python",
"views": 100,
"title": "Dictionary"
}

2. POST a new category article to TGS

$ curl -XPOST http://127.0.0.1:8080/category/c++ -H "Content-Type: application/json"  --data '{ "category": "c++", "views": "199", "title": "tuples" }'
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
Dload  Upload   Total   Spent    Left  Speed
100   125  100    69  100    56   1468   1191 --:--:-- --:--:-- --:--:--  2659{
"category": "c++",
"views": "199",
"title": "tuples"

3. PUT an article , modify C++ category article

$ curl -XPUT http://127.0.0.1:8080/category/c++ -H "Content-Type: application/json"  --data '{ "category": "c++", "views": "201", "title": "tuples" }'
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
Dload  Upload   Total   Spent    Left  Speed
100   125  100    69  100    56  69000  56000 --:--:-- --:--:-- --:--:--  122k{
"category": "c++",
"views": "201",
"title": "tuples"
}
$ curl -XGET http://127.0.0.1:8080/category/c++
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
Dload  Upload   Total   Spent    Left  Speed
100    69  100    69    0     0   4312      0 --:--:-- --:--:-- --:--:--  4312{
"category": "c++",
"views": "201",
"title": "tuples"
}

As you can see C++ category record is updated.

4. DELETE an article from C++ category

$ curl -XDELETE http://127.0.0.1:8080/category/c++
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
Dload  Upload   Total   Spent    Left  Speed
100    18  100    18    0     0  18000      0 --:--:-- --:--:-- --:--:-- 18000"c++ is deleted."

$ curl -XGET http://127.0.0.1:8080/category/c++
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
Dload  Upload   Total   Spent    Left  Speed
100    21  100    21    0     0  21000      0 --:--:-- --:--:-- --:--:-- 21000"category not found"

Recommended exercise: Use MySQL or any database to store articles and implement data access layer to provide CRUD functionality over REST.

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

{ 2 comments… add one }

  • Zoran Jovanic April 13, 2019, 4:01 am

    Well, you assume that I fully understand what code belongs to server side and which belongs to client side but I don’t.
    Sorry, I don’t fully understand what part belongs where.

  • Juan April 14, 2019, 2:50 am

    Simple and to the point explanation of REST. Is a resource. Thank you for another great article.
    I would like to request that you make (or recommend me) an article about consuming a REST API with OAuth2 and a Callback URL, in Python. I’m having issue understanding how to implement the concept of the Callback URL in a desktop application.

Leave a Comment