Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Extending CherryPy

If you need to perform some work that doesn't fit in a page handler, there are two ways to do it depending on the scope of the task. If your code needs to run on each request, or for only some URL's in your application, use a Tool. If your code needs to run elsewhere, such as process start/stop/restart/exit, or thread start/stop, use a Bus Plugin.

Tools

http://www.cherrypy.org/attachment/wiki/ExtendingCherryPy/hookpoints.gif?format=raw

Tools allow you to run functions at a particular point in the request process. You can run arbitrary code at any of the points by creating a Tool instance and sticking it in the toolbox...

def protect(users):
    if cherrypy.request.login not in users:
        raise cherrypy.HTTPError("401 Unauthorized")
cherrypy.tools.protect = Tool('on_start_resource', protect)

...then, once you've authored your Tool, you turn it on via config:

[/path/to/protected/resource]
tools.protect.on = True
tools.protect.users = ['me', 'myself', 'I']

Low-level: Hooks

Tools package up hooks. When we created a Tool instance above, the Tool class registered our protect function to run at the 'on_start_resource' hookpoint. You can write code that runs at hookpoints without using a Tool to help you, but you probably shouldn't. The Tool system allows your function to be turned on and configured both via the CherryPy config system and via the Tool itself as a decorator. You can also write a Tool that runs code at multiple hook points.

Bus Plugins

http://www.cherrypy.org/attachment/wiki/ExtendingCherryPy/plugins.gif?format=raw

Plugins allow you to run functions at a particular point in the site process. You can run arbitrary code at any of the events by creating a SimplePlugin? object, with one method for each channel...

class ScratchDB(plugins.SimplePlugin):
    
    def start(self):
        self.fname = 'myapp_%d.db' % os.getpid()
        self.db = sqlite.connect(database=self.fname)
    
    def stop(self):
        self.db.close()
        os.remove(self.fname)
cherrypy.engine.scratchdb = ScratchDB(cherrypy.engine)

...then, once you've authored your Plugin, turn it on by calling its subscribe method:

cherrypy.engine.scratchdb.subscribe()

...or, in CherryPy 3.2 and above, in site config:

[global]
engine.scratchdb.on = True

Low-level: Bus Listeners

Plugins package up bus listeners. When we called our Plugin's subscribe method, above, the Plugin class looked for a method matching the name of each known Bus channel and subscribed each one for us. You can manually subscribe bus listeners, but you probably shouldn't. The SimplePlugin? class allows your function to be subscribed and configured both via the CherryPy config system and via the Plugin itself. Plugins also allow you to write a single class that listens on multiple channels.

Attachments

Hosted by WebFaction

Log in as guest/cpguest to create tickets