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

[This document is up-to-date as of [2560].

What's new in CherryPy 3.2

This document only describes new features in CherryPy 3.2. A detailed "How To Upgrade" document is at UpgradeTo32.

Python 3 Support

CherryPy 3.2 runs on Python 3! You'll find separate downloadable packages, as well as a separate Subversion branch. Python 2.6 support has been improved, too, by the way.

The biggest change required for Python 3 is the switch from bytes to unicode. CherryPy 3.1 only ran on Python 2, which favored byte strings over unicode strings. But in Python 3, unicode strings are preferred. Most Request attributes are now unicode strings in Python 3.

Deployment

FastCGI/SCGI

The FastCGI support in cherryd is much improved and tested, including socket file support; also, autoreload and the conflicting signal handlers are now off by default. SCGI support is also included via the -s option to cherryd (thanks georgem).

cherryd and sys.path

cherryd now adds the current directory to sys.path, so that modules in it can be more easily imported. There's also a new -P command-line option to prepend additional paths to sys.path.

SSL

We now support Python's builtin ssl module, in addition to the former pyOpenSSL, and there is an established SSLAdapter API for hooking up other SSL libraries.

In CherryPy 3.1, you could tell the wsgiserver to use SSL by setting a couple of configuration entries like so:

server.ssl_certificate = <filename>
server.ssl_private_key = <filename>

If you wish to continue using pyOpenSSL in Python 2 using the syntax above, nothing has changed.

To use Python's builtin ssl module in Python 2 instead, add the line:

    server.ssl_module = 'builtin'

For Python 3, the builtin module is the default.

In addition, the pyOpenSSL adapter sports a new context configuration method, which you can set to an instance of SSL.Context for more advanced settings. See the pyOpenSSL documentation for all the options. It also accepts a certificate_chain argument, the filename of CA's intermediate certificate bundle. This is needed for cheaper "chained root" SSL certificates, and should be left as None if not required.

Open sockets are no longer inherited by child processes (thanks nicolas grilly). See #856 for more details.

Engine/Bus

cherrypy.engine is an instance of cherrypy.process.wspbus.Bus. Beginning in CherryPy 3.2, the "state" argument to Bus.wait(state, interval) may be a list or tuple, instead of a single state, in order to wake up on any of several states.

Dispatch

Dynamic Dispatch by Controllers

To find a handler for the current request, !CherryPy's default dispatcher traverses a tree of objects and methods. Beginning in CherryPy 3.2, when a controller possesses a _cp_dispatch(vpath) method, !CherryPy's default dispatcher will now use its return value as the 'next hop' in the object traversal. Returning None effectively stops traversal; CherryPy will then work backward looking for a default handler as normal. In addition, the _cp_dispatch method is a list of remaining path segments, and the method is allowed to mutate it. For example, to handle the URI /users/123/profile, a Users._cp_dispatch method would receive a vpath argument of ['123', 'profile'], at which point it could write:

def _cp_dispatch(vpath):
    if vpath:
        cherrypy.request.params['user_id'] = vpath.pop(0)
    if vpath:
        return getattr(self, vpath[0], None)

Mismatched Request Params

In previous versions, unexpected URI path segments, or unexpected parameters in the query string or request body, would generally return somewhat unhelpful "500 Server Error" responses. Starting in CherryPy 3.2, when query parameters passed to a handler are incorrect, or when path segments are incorrectly passed to a handler, "404 Not Found" is returned instead. When body params are incorrectly passed to a handler, "400 Bad Request" is returned.

If request.show_mismatched_params is True, a message listing the mismatched params will be output in the 4xx response body. If False, the 4xx response will be empty.

In other parameter news, multipart/* requests that have no Content-Disposition are now passed to the handler as a 'parts' argument. See #890.

MethodDispatcher

This dispatcher now includes any _cp_config attribute on the GET/POST/etc handler method itself.

Request Bodies

CherryPy 3.2 has a new _cpreqbody module which completely replaces its use of the standard library's cgi module (and our safemime and cpcgifs modules, to boot). There are default processors for common content-types (including improved support for multipart/* types), and you can write your own custom processors! See RequestBodies for more details.

Configuration

New config decorator

cherrypy.config can now be used as a page handler decorator. It works just like the _cp_config attribute; in fact, that's all it really does. But it might look better. Instead of

    @cherrypy.expose
    def index(self):
        return "Hello world"
    index._cp_config = {'response.headers.Content-Type': 'text/plain'}

you can now write:

    @cherrypy.config(**{'response.headers.Content-Type': 'text/plain'})
    @cherrypy.expose
    def index(self):
        return "Hello world"

...and it interacts with tools-as-decorators more safely, to boot.

reprconf

Much of the basic approach to config has been isolated in its own re-usable module at cherrypy.lib.reprconf. This includes the unrepr approach to configuration (where values use Python syntax), as well as key namespaces and the ability to use dicts, filenames, or file objects.

engine

All engine attributes may now be changed in config via the "engine.*" config namespace.

Engine plugins, whether builtin or custom, may also now be configured if they are added to the engine object itself. The builtin plugins "autoreload", "thread_manager", "signal_handler", "timeout_monitor", and "console_control_handler" are already added. The "on" config entry subscribes or unsubscribes the plugin, and all other entries are set as attributes on the plugin instance.

cherrypy.engine.my_plugin = MyPlugin(a=3, b='foo')
...
cherrypy.config.update({'engine.my_plugin.on': True,
                        'engine.my_plugin.a': 16})

server

Additional servers may now be turned on and off, and configured, via config entries in the server.<servername>.* namespace. The "servername" portion is arbitrary; it only matters that you use the same name for all settings for the same server. Any new name will add a new server, so that, for example, server.2.socket_port will start a new WSGIServer (on that port); any new server is on by default. To start a different type of server, set server.<servername>.instance to the server (or its class) you wish to use.

request

request.query_string_encoding is now available to declare the expected encoding of querystring paramters.

response

response.headers are now settable in config; just set response.headers.<field-name> = <field-value>. For example: response.headers.Content-Type = "text/plain".

HTTPError

cherrypy.HTTPError now takes full reason phrases in the status argument. See #898.

WSGI

There's a new REQUEST_URI environ entry, which equals the Request-URI in the HTTP spec. Also, the SERVER_NAME entry is no longer settable by the client.

The wsgiserver is no longer hard-coded to emit WSGI 1.0; instead, it has its own internal format (which is much closer to HTTP than CGI). Just before the server calls its WSGI application, it uses a Gateway to convert its internal formats to WSGI. This means that wsgiserver can now support any version of WSGI, blessed by a given standards body or not. There's even a new 'native' gateway which doesn't use WSGI at all! CherryPy 3.2 ships with gateways for WSGI 1.0 (the long-time standard), WSGI 1.1 (see Graham Dumpleton's blog for details), and an experimental version we're calling ('u', 0), which uses full unicode strings for most environ keys and values.

InternalRedirect and exception trapping have been moved out of the WSGI application adapter and into WSGI components, so you can now turn them off to be even leaner and meaner. :)

Tools

Most tools now take a debug configuration option. When True, they emit log entries to help diagnose problems in configuration.

JSON

There's a new pairs of tools for JSON: json_in checks the Content-Type of the request and reads the body, decoding it and placing it into request.json; json_out sets the Content-Type response header and encodes the page handler output to JSON.

Sessions

The session cleanup thread can be completely disabled now by setting tools.sessions.clean_freq to 0 or None. This is required for Google App Engine, which does not allow the creation of new threads.

Until now, all session cookies expired according to tools.sessions.timeout. Starting in 3.2, if tools.sessions.persistent is False, the cookies will expire when the user closes their browser. See #870.

There's a new tools.sessions.pickle_procotol attribute, and the default has been changed to pickle.HIGHEST_PROTOCOL.

Caching

The caching tool now stores separate responses based on varying request header values (as required by the HTTP spec).

It also does antistampeding by default; that is, when one thread begins to calculate a cached response, other competing requests will wait for it to finish and then return its result.

Finally, there's more (as in "some") support for Cache-Control (and Pragma) request header values max-age and no-cache, and response header values no-cache and no-store.

autovary

tools.autovary keeps track of which request headers your application accesses, and auto-populates the Vary response header.

auth

Thanks to visteya, the existing basic_auth and digest_auth tools have been supplemented with tools.auth_basic and tools.auth_digest. See #913 and #914 for all the reasons why you should switch.

trailing_slash

The trailing_slash tool has a new status argument, to allow XmlHttpRequest's to receive 307 redirects. Defaults to 301.

Hosted by WebFaction

Log in as guest/cpguest to create tickets