CherryPy - Web Services



A web service is a set of web-based components that helps in the exchange of data between the application or systems which also includes open protocols and standards. It can be published, used and found on the web.

Web services are of various types like RWS (RESTfUL Web Service), WSDL, SOAP and many more.

REST — Representational State Transfer

A type of remote access protocol, which, transfers state from client to server which can be used to manipulate state instead of calling remote procedures.

  • Does not define any specific encoding or structure and ways of returning useful error messages.

  • Uses HTTP "verbs" to perform state transfer operations.

  • The resources are uniquely identified using URL.

  • It is not an API but instead an API transport layer.

REST maintains the nomenclature of resources on a network and provides unified mechanism to perform operations on these resources. Each resource is identified by at least one identifier. If the REST infrastructure is implemented with the base of HTTP, then these identifiers are termed as Uniform Resource Identifiers (URIs).

The following are the two common subsets of the URI set −

Subset Full form Example
URL Uniform Resource Locator http://www.gmail.com/
URN Uniform Resource Name urn:isbn:0-201-71088-9 urn:uuid:13e8cf26-2a25-11db-8693-000ae4ea7d46

Before understanding the implementation of CherryPy architecture, let’s focus on the architecture of CherryPy.

CherryPy includes the following three components −

  • cherrypy.engine − It controls process startup/teardown and event handling.

  • cherrypy.server − It configures and controls the WSGI or HTTP server.

  • cherrypy.tools − A toolbox of utilities that are orthogonal to processing an HTTP request.

REST Interface through CherryPy

RESTful web service implements each section of CherryPy architecture with the help of the following −

  • Authentication
  • Authorization
  • Structure
  • Encapsulation
  • Error Handling

Authentication

Authentication helps in validating the users with whom we are interacting. CherryPy includes tools to handle each authentication method.

def authenticate():
   if not hasattr(cherrypy.request, 'user') or cherrypy.request.user is None:
      # < Do stuff to look up your users >
		
      cherrypy.request.authorized = False # This only authenticates. 
         Authz must be handled separately.
		
      cherrypy.request.unauthorized_reasons = []
      cherrypy.request.authorization_queries = []
		
cherrypy.tools.authenticate = \
   cherrypy.Tool('before_handler', authenticate, priority=10)

The above function authenticate() will help to validate the existence of the clients or users. The built-in tools help to complete the process in a systematic way.

Authorization

Authorization helps in maintaining the sanity of the process via URI. The process also helps in morphing objects by user token leads.

def authorize_all():
   cherrypy.request.authorized = 'authorize_all'
	
cherrypy.tools.authorize_all = cherrypy.Tool('before_handler', authorize_all, priority=11)

def is_authorized():
   if not cherrypy.request.authorized:
      raise cherrypy.HTTPError("403 Forbidden",
         ','.join(cherrypy.request.unauthorized_reasons))
			
cherrypy.tools.is_authorized = cherrypy.Tool('before_handler', is_authorized, 
priority = 49)

cherrypy.config.update({
   'tools.is_authorized.on': True,
   'tools.authorize_all.on': True
})

The built-in tools of authorization help in handling the routines in a systematic way, as mentioned in the previous example.

Structure

Maintaining a structure of API helps in reducing the work load of mapping the URI of application. It is always necessary to keep API discoverable and clean. The basic structure of API for CherryPy framework should have the following −

  • Accounts and User
  • Autoresponder
  • Contact
  • File
  • Folder
  • List and field
  • Message and Batch

Encapsulation

Encapsulation helps in creating API which is lightweight, human readable and accessible to various clients. The list of items along with Creation, Retrieval, Update and Deletion requires encapsulation of API.

Error Handling

This process manages errors, if any, if API fails to execute at the particular instinct. For example, 400 is for Bad Request and 403 is for unauthorized request.

Example

Consider the following as an example for database, validation, or application errors.

import cherrypy
import json

def error_page_default(status, message, traceback, version):
   ret = {
      'status': status,
      'version': version,
      'message': [message],
      'traceback': traceback
   }
	
   return json.dumps(ret)
	
class Root:
   _cp_config = {'error_page.default': error_page_default}
	
@cherrypy.expose
   def index(self):
      raise cherrypy.HTTPError(500, "Internal Sever Error")
cherrypy.quickstart(Root())

The above code will produce the following output −

Error Handling

Management of API (Application Programming Interface) is easy through CherryPy because of the built-in access tools.

HTTP Methods

The list of HTTP methods which operate on the resources are as follows −

S.No HTTP Method & Operation
1.

HEAD

Retrieves the resource metadata.

2.

GET

Retrieves the resource metadata and content.

3.

POST

Requests the server to create a new resource using the data enclosed in the request body.

4.

PUT

Requests the server to replace an existing resource with the one enclosed in the request body.

5.

DELETE

Requests the server to remove the resource identified by that URI.

6.

OPTIONS

Requests the server to return details about capabilities either globally or specifically towards a resource.

Atom Publishing Protocol (APP)

APP has arisen from the Atom community as an application-level protocol on top of HTTP to allow the publishing and editing of web resources. The unit of messages between an APP server and a client is based on the Atom XML-document format.

The Atom Publishing Protocol defines a set of operations between an APP service and a user-agent using HTTP and its mechanisms and the Atom XML-document format as the unit of messages.

APP first defines a service document, which provides the user agent with the URI of the different collections served by the APP service.

Example

Let us take an example to demonstrate how APP works −

<?xml version = "1.0" encoding = "UTF-8"?>
<service xmlns = "http://purl.org/atom/app#" xmlns:atom = "http://www.w3.org/2005/Atom">
   
   <workspace>
      <collection href = "http://host/service/atompub/album/">
         <atom:title> Albums</atom:title>
         <categories fixed = "yes">
            <atom:category term = "friends" />
         </categories>
      </collection>
      
      <collection href = "http://host/service/atompub/film/">
         <atom:title>Films</atom:title>
         <accept>image/png,image/jpeg</accept>
      </collection>
   </workspace>
	
</service>

APP specifies how to perform the basic CRUD operations against a member of a collection or the collection itself by using HTTP methods as described in the following table −

Operation HTTP Method Status Code Content
Retrieve GET 200 An Atom entry representing the resource
Create POST 201 The URI of the newly created resource via the Location and Content-Location headers
Update PUT 200 An Atom entry representing the resource
Delete DELETE 200 None
Advertisements