What's new in CherryPy-2.2
The 2.2 release is backward-compatible. If you find that the upgrade breaks your site please let us know so that this can be fixed.
A more detailed "How To Upgrade" document is at UpgradeTo2.2?.
- Support for multiple applications within one CherryPy process
- The sessionfilter is now more stable, especially the file backend (the use of session.acquire_lock is now better documented in the book. If your site is used in an environment where you have multiple concurrent requests from the same browser then acquire_lock should be called by methods that write to the session).
- New positional parameters
Changes to Filters
New Location for Standard Filters
The standard CherryPy filters have moved from cherrypy.lib.filter to cherrypy.filters. Importing from cherrypy.lib.filter is still supported in 2.2, but it is deprecated. If you are using a custom filter written for 2.1 that inherits from cherrypy.lib.filter.basefilter.BaseFilter, a warning will be raised when you start CP notifying you of the deprecated cherrypy.lib.filter location.
Loading User Defined Filters
CherryPy offers a couple different ways of integrating user defined filters into an application. There have been some slight changes in how this works from 2.1 to 2.2.
Using the _cp_filters Attribute
You can still use _cpFilterList, but it is considered deprecated in 2.2. The new special attribute is _cp_filters.
from cherrypy.filters.basefilter import BaseFilter class MyFilter(BaseFilter): def before_main(self): print "I was called before the page handler!" class Test(object): _cp_filters = [MyFilter(),] @cherrypy.expose def index(self): return "Hello, world!"
Using the Configuration System
The config options server.filtersRoot, server.inputFiltersDict and server.outputFiltersDict are gone. We now have two new config options:
server.input_filters = ['package.module.FilterClass',] server.output_filters = ['package.module.FilterClass',]
The example above assumes the following directory layout:
myapp/
package/
__init__.py
module.py # contains FilterClass
...
You can also do something like the following:
from package.module import FilterClass cherrypy.config.update({'global':{'server.input_filters':[FilterClass,]}})
Custom Servers
CherryPy 2.2 offers support for custom server instances to be passed to cherrypy.server.start(). This opens up some interesting possibilities, including the ability to wrap the CherryPy wsgiApp in WSGI middleware.
Here is an example using the EvalExeption middleware from Paste:
""" This is an example of a way to use WSGI middleware with CherryPy 2.2. This example requires EvalException from Paste. """ import sys import cherrypy from cherrypy._cpwsgi import wsgiApp, CPHTTPRequest from cherrypy._cpwsgiserver import CherryPyWSGIServer from paste.evalexception.middleware import EvalException # we need a WSGI server class that accepts a WSGI application # as a parameter to its constructor - here is an example class SimpleWSGIServer(CherryPyWSGIServer): """A WSGI server that accepts a WSGI application as a parameter.""" RequestHandlerClass = CPHTTPRequest def __init__(self, wsgi_app): conf = cherrypy.config.get bind_addr = (conf("server.socket_host"), conf("server.socket_port")) CherryPyWSGIServer.__init__(self, bind_addr, wsgi_app, conf("server.thread_pool"), conf("server.socket_host"), request_queue_size = conf("server.socket_queue_size"), ) # here is a sample CherryPy root class # we are using exception catching middleware in this example, # so the "problem" page handler purposely generates an error # to demonstrate the middleware class Root(object): @cherrypy.expose def index(self): yield "Get in <a href='/problem'>trouble</a><br>" yield cherrypy.request.browser_url + '<br>' yield cherrypy.request.path + '<br>' yield cherrypy.request.object_path + '<br>' @cherrypy.expose def problem(self): "error on purpose to show off EvalException" assert 0, "Houston, we have a problem." # we need this so that errors trickle down to the middleware cherrypy.config.update({'server.throw_errors':True}) # mount our CherryPy cherrypy.root = Root() # wrap the CP wsgiApp in the middleware app = EvalException(wsgiApp, global_conf={}) # init the custom server with the middleware mw_server = SimpleWSGIServer(app) # start CherryPy with the custom server cherrypy.server.start(server=mw_server)
Attachments
- middleware_demo.py (2.0 kB) - added by fumanchu on 09/03/06 23:26:08.

