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 ?
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.
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.
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.
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'}
.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With