Apr 9, 2013

CherryPy 101

CherryPy is one of the oldest frameworks for web development in the python world, most famously knows as http framework , and still there are a bunch of people who thinks that cherrypy is only a production grade webserver in python, but there is more to see in this wise framework that has been evolving in the last years.

This example demonstrate only the default dispatcher that is an object dispatcher, it looks for properties in the root object to find the handler for an specify URL, there are also a couple more of choices, a routes dispatcher which basically is a wrapper around routes and a method dispatcher, that I will cover on detail later on a different post.

import cherrypy class WebApp ( object ): def __init__ ( self ): self . user = User () @cherrypy.expose def about ( self ): return ( 'Hi!, this is the about page ' 'go back to the <a href="/">Index page</a>.' ) @cherrypy.expose def section ( self , name ): return ( 'Hi!, this is the section <b> %s </b> ' 'go back to the <a href="/">Index page</a>.' % name ) @cherrypy.expose def index ( self ): """This is an special method which gets called when the url has no arguments, e.g.: mysite.com/ or mysite.com/page/ """ urls = [( "/" , "WebApp.index" ), ( "/about" , "WebApp.about" ), ( "/section/a" , "WebApp.section" ), ( "/section/b" , "WebApp.section" ), ( "/section/c" , "WebApp.section" ), ( "/a/b/c/d/e/f/g?one=1&two=2&three=3" , "WebApp.default" ), ( "/user/" , "User.index" ), ( "/user/list" , "User.index" ), ( "/user/new" , "User.new" ), ( "/user/edit/1" , "User.edit" ), ( "/user/add" , "User.add <POST> -> Method Not Allowed" ), ( "/user/delete" , "User.delete <POST> -> Method Not Allowed" )] pagecnt = [ "<h1>CherryPy 101 Default dispatcher</h1>" , ] pagecnt . append ( "<p>This are some (default can handle a lot more) " " of the available pages: </p>" ) pagecnt . append ( '<ul>' ) for url , method in urls : pagecnt . append ( '<li><a href="{0}">{0} -> {1}</a></li>' \ . format ( url , method )) pagecnt . append ( '</ul>' ) for action in [ 'add' , 'delete' ]: pagecnt . append ( '<form method="post" action="/user/ %s ">' 'User id: <input type="text" name="userid" value="1"/>' '<input type="submit" value=" %s user">' '</form>' % ( action , action . capitalize ())) return '' . join ( pagecnt ) @cherrypy.expose def default ( self , * args , ** kwargs ): return ( "This is a catch all page, it can handle any URL that you throw. " "If there is no match in any other previous handler this " "is going to be executed: <br/>" "<pre>args: %s

kwargs: %s </pre>" % ( args , kwargs )) class User ( object ): def new ( self ): return "New user" new . exposed = True # this is the real requirement to expose the method, # needs to have an attribute called "exposed" which need to be `True`. @cherrypy.expose ( alias = 'list' ) def index ( self ): return "List all the users " # but also the `expose` decorator had some tricks # the index method can be called also in /user/list/ @cherrypy.expose def edit ( self , userid ): return "Edit the user with id %s " % userid @cherrypy.expose @cherrypy.tools.allow ( methods = ( 'POST' )) def add ( self , ** params ): return "Adding new user with params %s " % params @cherrypy.expose @cherrypy.tools.allow ( methods = ( 'POST' )) def delete ( self , userid ): return "The user with id: %s , has been removed." % userid if __name__ == '__main__' : cherrypy . quickstart ( WebApp ())

The cherrypy.quickstart function by default will start a webserver in the localhost listening to the port 8080, you can now go to you browser at the url http://localhost:8080 and see the results for yourself.

UPDATE : the post for the method dispatcher is here.