One of the great aspects of CloudCrowd is that the code base is so small and readable. A big part of that comes by virtue of using the Sinatra Web application framework for the master and slave daemon processes. Sinatra is much closer to the GAE webapp framework than CherryPy (by default), in that you define methods that correspond to the HTTP verbs (GET, PUT, POST, DELETE and HEAD). Sinatra differs in that the method’s first argument is the route that the method services. The GAE webapp framework instead forces you to define a class that the defines the HTTP verbs, and later map those classes to some route. Let’s take a look at “Hello World!” to illustrate the difference. Here is the GAE webapp version

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class HelloWorld(webapp.RequestHandler):
	def get(self):
		self.response.out.write("Hello World!")

app = webapp.WSGIApplication([("/",HellowWorld)])

def main():
	run_wsgi_application(app)

if __name__ == "main":
	main()

Now here is the version in Sinatra:

require "rubygems" # RubyGems is optional, depending on your setup
require "sinatra"
get '/' do
  "Hello World!"
end

Much more readable and concise. Here is a version of HellWorld in CherryPy, using the default MethodDispatcher, for comparison:

import cherrypy

class HelloWorld:
    exposed = True
    def GET(self):
        return "Hello World!"

app = HelloWorld()

d = cherrypy.dispatch.MethodDispatcher()
conf = {'/': {'request.dispatch': d}}
cherrypy.tree.mount(root, "/", conf)

Better, but you are still separating the the mapping of the root URL “/” to the HelloWorld class outside of the class. I started digging around the interwebz for Python frameworks that would work closer to the lightweight Sinatra and found Bottle. Bottle is small, self-contained and uses python decorators to map a function to a route. Brilliant. Here is the example using Bottle:

from bottle import route, run

@route("/") # assumes GET method
def hello():
	return "Hello world!"

run() # This starts the HTTP server

Now that’s what I’m talking about! Deploying a Bottle application to GAE is covered in their documentation. We’ll be using Bottle for cu3w0rx to create the master and slave daemons in later posts.

Advertisement