Thursday, March 06, 2008

CherryPy, Mako, and Py2exe

So I wanted to make a windows service out of CherryPy. CherryPy as the webserver, Mako as my template engine, and Py2exe to turn it into a windows service.

Easy enough I thought, great reference about CherryPy and Windows Services on CherryPy's website. Unfortunately their tutorial didn't work with CherryPy 3.0. Instead I got a "cherrypy No HTTP servers have been created" error. Easy enough to fix though change the cherrypy.server.start() to be cherrypy.server.quickstart().

My next hurdle was wanting the config to be within the code and not in an external file. From Cherry py's example on windows services, cherrypy.tree.mount(HelloWorld(), '/'). There is an optional third parameter, the config object. cherrypy.tree.mount(HelloWorld(), '/', config ).

My config looks like this:
config = {
'/': {
'tools.staticdir.root': path,
},
'/static': {
'tools.staticdir.on': True,
'tools.staticdir.dir': "static",
}
}
Finally a working windows service. Then off to integrating Mako. That was the easy part.

In my controllers code:

from mako.template import Template
from mako.lookup import TemplateLookup

DEBUG_MODE=False
lookup = TemplateLookup( directories=['template'], module_directory="cache",
output_encoding="utf-8", encoding_errors="replace",
filesystem_checks=DEBUG_MODE)

...

class HelloWorld(object):
def index(self):
# index.html is in the template dir
tmp = lookup.get_template("index.html")
# title used as ${title} in index.html template file
return tmp.render(**dict(title="Welcome"))
index.exposed = True
The last hurdle was Py2Exe. Did I mention I was using simplejson and YUI? Simplejson's egg needed to be unzipped. Simplejson made it easy to send python data to YUI as something YUI could understand; json.

mako.cache and simplejson needed to be included in my packages list, so my py2exe options looked like this:

OPTIONS = {
"py2exe": {
"compressed": 1,
"optimize": 2,
"bundle_files": 2,
"packages": [
"elementtree",
"simplejson",
"mako.cache"
],
"excludes": [
"Tkinter"
]
}
}
My mako template directory needed to be copied to the py2exe dist directory:

DATA_FILES = [
("template", glob.glob("template/*.html"))
]

End result is a Windows HTTP Service that works quite nice.

2 comments:

Jorge said...

Could you post a sample project?
It would be nice.

If you don't want to post your real app, could you make a simple "Hello World" app?

Thank you in advance.

koobmeej said...

Your welcome. You might take a look at http://www.barsult.com/open-source/demo-cherry-server.zip. It uses Py2Exe, Mako and CherryPy to create a windows service.