Section 17.3. CherryPy Filters

17.3. CherryPy Filters

CherryPy also has hooks for running special functions called filters at several different points in the request cycle, before and after the published object is executed.

Filters allow for a lot of flexibility in the way requests are handled. CherryPy comes with several built-in filters to do caching, session management, compression, XML Remote Procedure Call (RPC) request processing, and to otherwise slice and dice the request object in interesting ways. But wait, that's not all. CherryPy also provides an easy-to-use mechanism for you to create your own custom filters, which are applied to whichever sections of your object hierarchy you choose.

But it's likely that future versions of TurboGears will use a somewhat different implementation of filters, so if you're using something more recent than 1.0 you may want to check the online documents.

17.3.1. Input Filters

The most logical place to start seeing what filters can do for you in CherryPy is to take a look at some of the built-in input filters. In Table 17-3 you will find a list of the built-in CherryPy input filters.

Table 17-3. CherryPy Input Filters




Used for caching request responses to short-circuit the need for further evaluation.


The CherryPy filter that lists the request time.


Automatically transform the base_url on the way in. We'll see this in use when we mount CherryPy behind Apache.


This filter makes it easy to have independent sites that also appear as subdirectories of one main site.


Sets a default character encoding.


Maintains session state for you. It sets a cookie, and turns that cookie into a link to session data that you can use while processing the request.


This is a built-in CherryPyAuthentication filter, but Identity or TurboPeakSecurity are generally better choices for TurboGears projects.


TurboGears uses this one by default to serve up static files for your application from the /static directory.


Process nsgml-formatted input.


Validates HTML.


Handles XML requests for you by converting the posted data to a method name and parameters. See CherryPy's online documents for more detail.

These filters are contained in the cherrypy.filter.input_order list in the above order. You should be able to open that list and add your own filters; filters will be applied in the order they appear in the input_order list. Each item in this list should be a fully qualified package location. (This is already true for the built-in filters, but you want to follow the same convention for any filters you add!)

17.3.2. Output Filters

Just like the input filters, each of these output filters is contained in the cherrypy.filters.output_filters list, which defines the order of the filters that are run. You can configure any of these built-in filters by turning them on in the configuration app.cfg (which can be found in your project's config folder).

Here's a sample of how we turn on the static file filter for the /static directory:

[/static] static_filter.on = True static_filter.dir = "%(top_level_dir)s/static"

You can use the Output Filters described in Table 17-4 to compress the response before sending it back to the user, or even create XML-RPC output.

Table 17-4. Output Filters




Creates custom headers.


Creates XML RPC on the way out.


Forces a particular encoding on the resultant response object.


Validates/cleans outgoing HTML.


This filter provides XHTML validation using NSGMLS, which must also be installed.


Maintains session state for you.


Compresses output using Gzip. If you are mounting TurboGears behind Apache, you will get better performance by doing this at the Apache layer.


Injects the cookie necessary to maintain session state into the outgoing request.


Provides access to update the CherryPy cache on the way out.

We talk more about CherryPy configuration in the next section. For now, all you need to know is that turning on the static_filter for the /static directory means that any files that you put in your TurboGears application's static folder will be returned without any further processing.

17.3.3. Creating Your Own Filters

If you want to create your own filters, all you have to do is to subclass BaseFilter from the cherrypy.filters.basefilter module:

class PrintMessageFilter(BaseFilter):     def before_main(self):         print "This happens before the main page handler is called"

If you define a new method with the name of one of CherryPy's predefined filter hook locations, that method will be called at that time in the request cycle.

But, it's probably not enough to define a new filteryou probably want to actually have it run on some set of your controller objects, too. Fortunately that's easy: You can just define a _cp_filters list containing all the custom filter classes that you want to run on objects in that controller class. So, if you want to run our PrintMessageFilter on every object in your whole hierarchy, you could write something like this:

class Root(controllers.RootController):     _cp_filters = [PrintMessageFilter(),]

As mentioned earlier, there are several predefined hooks in CherrPy where filters can be run. Whenever the request/response cycle hooks occur, CherryPy runs any filters that are in _cp_filters, and which define a method with the name of the current hook. Not only that, but the filters are applied in the order they are found in the _cp_filters list as seen in Table 17-5.

Table 17-5. CherryPy Filter Hooks

Standard Request/Response Hooks


This occurs right at the beginning of the request cycle.


This occurs before CherryPy parses the request body.


This occurs before the controller method is called.


This occurs when the response object is about to be finalized and returned to the user.


This occurs right at the end of the cycle, before the request object is recycled.


Filter Hooks for Errors


This only occurs when there is an error, right before the error response is processed.


This only occurs when there is an error, right after the error is processed.

On the other hand, if you want to create a new filter and have it inserted into the CherryPy input or output filter lists, you can add your function to the call_on_startup list to register it to be run at startup, as follows:

from turbogears.startup import call_on_startup def do_your_thing():    call_on_startup.append(do_your_thing)

You can do_your_thing and insert filters into the CherryPy request phase or set up variables as needed.

Rapid Web Applications with TurboGears(c) Using Python to Create Ajax-Powered Sites
Rapid Web Applications with TurboGears: Using Python to Create Ajax-Powered Sites
ISBN: 0132433885
EAN: 2147483647
Year: 2006
Pages: 202

Similar book on Amazon © 2008-2017.
If you may any questions please contact us: