Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CherryPy and RESTful web api

What's the best approach of creating a RESTful web api in CherryPy? I've been looking around for a few days now and nothing seems great. For Django it seems that are lots of tools to do this, but not for CherryPy or I am not aware of them.

Later edit: How should I use Cherrypy to transform a request like /getOrders?account=X&type=Y into something like /orders/account/type ?

like image 936
hyperboreean Avatar asked Apr 26 '10 16:04

hyperboreean


People also ask

What is CherryPy used for?

CherryPy is an object-oriented web application framework using the Python programming language. It is designed for rapid development of web applications by wrapping the HTTP protocol but stays at a low level and does not offer much more than what is defined in RFC 7231.

Is CherryPy a Web server?

CherryPy comes with its own web (HTTP) server. That is why CherryPy is self-contained and allows users to run a CherryPy application within minutes of getting the library. The web server acts as the gateway to the application with the help of which all the requests and responses are kept in track.

Is CherryPy an MVC framework?

CherryPy is designed on the concept of multithreading. This gives it the benefit of handling multiple tasks at the same time. It also takes a modular approach, following the Model View Controller (MVC) pattern to build web services; therefore, it's fast and developer-friendly.


2 Answers

I don't know if it's the "best" way, but here's how I do it:

import cherrypy

class RESTResource(object):
   """
   Base class for providing a RESTful interface to a resource.

   To use this class, simply derive a class from it and implement the methods
   you want to support.  The list of possible methods are:
   handle_GET
   handle_PUT
   handle_POST
   handle_DELETE
   """
   @cherrypy.expose
   def default(self, *vpath, **params):
      method = getattr(self, "handle_" + cherrypy.request.method, None)
      if not method:
         methods = [x.replace("handle_", "")
            for x in dir(self) if x.startswith("handle_")]
         cherrypy.response.headers["Allow"] = ",".join(methods)
         raise cherrypy.HTTPError(405, "Method not implemented.")
      return method(*vpath, **params);

class FooResource(RESTResource):
    def handle_GET(self, *vpath, **params):
        retval = "Path Elements:<br/>" + '<br/>'.join(vpath)
        query = ['%s=>%s' % (k,v) for k,v in params.items()]
        retval += "<br/>Query String Elements:<br/>" + \
            '<br/>'.join(query)
        return retval

class Root(object):
    foo = FooResource()

    @cherrypy.expose
    def index(self):
        return "REST example."

cherrypy.quickstart(Root())

You simply derive from the RESTResource class and handle whichever RESTful verbs you desire (GET, PUT, POST, DELETE) with a method of the same name prefixed with handle_. If you do not handle a particular verb (such as POST) the base class will raise a 405 Method Not Implemented error for you.

The path items are passed in vpaths and any query strings are passed in in params. Using the above sample code, if you were to request /foo/bar?woo=hoo, vpath[0] would be bar, and params would be {'woo': 'hoo'}.

like image 109
carpie Avatar answered Oct 20 '22 11:10

carpie


Because HTTP defines these invocation methods, the most direct way to implement REST using CherryPy is to utilize the MethodDispatcher instead of the default dispatcher.

More can be found in CherryPy docs: http://cherrypy.readthedocs.io/en/latest/tutorials.html#tutorial-7-give-us-a-rest

Here is also detailed description on how to send and receive JSON using CherryPy Tools: http://tools.cherrypy.org/wiki/JSON

like image 44
Tomasz Błachowicz Avatar answered Oct 20 '22 11:10

Tomasz Błachowicz