rest api python

Contributed by: Akash Mishra

Rest (Representational State Transfer) API Python framework is a set of utilities based on werkzeug to easily build Restful API. It is easy to configure and extends with ease. It does not decide how the data can be rendered, nor any other decision. Instead, it’s an easily extensible architecture to build one’s API.

Python REST API Framework has not been created for the usual case but hooks on to special resource providers with special view management, and special way of displaying data. Python REST API is fully rest compliant with the implementation as below.

  • GET
  • POST
  • UPDATE
  • DELETE
  • HEAD

Along with implementation of below:

  • PAGINATION
  • AUTHENTICATION
  • RATE-LIMIT
  • DATA VALIDATION
  • PARTIAL RESPONSE

Architecture

Python REST API Framework is based on the MVC pattern where we define some endpoints explaining a Resource, a Controller and a View which are configurable.

Controller

It manages the way a request is handled. It creates URL endpoints and also, List, Unique and Auto-documented endpoints. It manages pagination, formators, authentication, authorization, rate-limit and allowed method.

Data Store

Each method of a Controller, calls the Data Store to interact with the data. Data Store is used to retrieve data from the resource. Each data store acts on a particular type of resource (database backend, API backend, CSV backend etc.) which validates data, creates new resources, updates existing resources, manages filters and pagination. 

View

It defines how the data must be sent to the client. It passes a Response object and sets the needed headers, mime-type and other presentation options like formators.

How To use Rest API in Python

Rest API can be used by creating as many endpoints and for each endpoint defining a resource, a controller and a view. These are then added to the rest_api_framework.controllers.WSGIDispatcher

A Sample API

For this sample, we will use a python list.

resources = [
    {"name": "Akash",
    "age": a,
    "id": a
    } for a in range(100)
    ]

Then we describe this resource by creating a Model class inheriting from base Model class:

from rest_api_framework import models
class ApiModel(models.Model):
    fields = [models.IntegerField(name="age", required=True),
              models.StringField(name="name", required=True),
              models.PkField(name="id")
              ]

There are validators for each field so that when these are reused, we get free validators.

There is already an existing datastore to handle it: PythonListDataStore.

We can reuse this store: from rest_api_framework.datastore import PythonListDataStore

Then Controller class is called to handle API: from rest_api_framework.controllers import Controller and a view to render our data: from rest_api_framework.views import JsonResponse

class ApiApp(Controller):
    resource = {
        "resource_name": "address",
        "resource": resources,
        "model": ApiModel,
        "datastore": PythonListDataStore
        }
    controller = {
        "list_verbs": ["GET", "POST"],
        "unique_verbs": ["GET", "PUT", "DELETE"],
        }
    view = {"response_class": JsonResponse}
A controller is build with 3 dicts:

Resource

Resources define your data.

  • resource_name: This argument is used to build the URL endpoint
  • resource: This argument guides datastore as to how they can be accessed. It can be the database name and the database table for a SQL datastore or the URL endpoint to a distant API
  • model: This argument describes the visual of the data i.e. which field to show, how to validate and so on.
  • datastore: This argument gives the type of data. There is a datastore for a simple Python list of dict and SQLite datastore. 

Controller

The controller defines how data should be accessed.

  • list_verbs: This argument defines the verbs that can be used on the main end point of your resource. If “POST” is not used, a user cannot create new resources on the datastore.
  • unique_verbs:  This argument defines the verbs that can be used on the unique identifier of the resource. Actions depending on the verbs follows the REST implementation: PUT to modify an existing resource, DELETE to delete a resource.

View

View is defined to render the resources to the user through either Json format, XML, or any other. It can also render pagination tokens, first page, last page, number of objects and other useful information for users.

  • response_class: this is used to render data.

To test the application locally, we need to add: if __name__ == ‘__main__’: from werkzeug.serving import run_simple

  from rest_api_framework.controllers import WSGIDispatcher
    app = WSGIDispatcher([ApiApp])
    run_simple('127.0.0.1', 5000, app, use_debugger=True, use_reloader=True)

then type “python app.py” and your API is up and running.

Options

Each of these dicts can take an optional parameter: “option”. This parameter contains the options to use with either the datastore, the view or the controller.

Using Database

We can save the data in a database. To do so, we need to change the datastore and define your resources in SQL datastore.

SQLiteDataStore uses sqlite3 as a database backend. ‘resources’ will be dict with database name and table name. The rest remains the same as with PythonListDataStore.

REST API framework creates the database for us, if the sqlite3 database does not exist.

from rest_api_framework.datastore import SQLiteDataStore
from rest_api_framework.controllers import Controller
from rest_api_framework.views import JsonResponse
from rest_api_framework import models
from rest_api_framework.pagination import Pagination
 
class ApiModel(models.Model):
    fields = [models.StringField(name="message", required=True),
              models.StringField(name="user", required=True),
              models.PkField(name="id", required=True),
              ]
 
class ApiApp(Controller):
    resource = {
       "ressource_name": "tweets",
       "ressource": {"name": "twitter.db", "table": "tweets"},
       "datastore": SQLiteDataStore,
       "model": ApiModel
    }
    controller = {
       "list_verbs": ["GET", "POST"],
       "unique_verbs": ["GET", "PUT", "DELETE"]
       "options": {"pagination": Pagination(20)}
    }
    view = {"response_class": JsonResponse}
 
if __name__ == '__main__':
    from werkzeug.serving import run_simple
    from rest_api_framework.controllers import WSGIDispatcher
    app = WSGIDispatcher([ApiApp])
    run_simple('127.0.0.1', 5000, app, use_debugger=True, use_reloader=True

This brings us to the end of the blog on Rest API Python. We hope you enjoyed this and are able to understand the concept more clearly. If you want to learn more such concepts, you can enrol with Great Learning Academy’s free online courses and unlock your dream career.

0

LEAVE A REPLY

Please enter your comment!
Please enter your name here

five × 4 =