1. cherrypy
  2. CherryPy

Wiki

Clone wiki

CherryPy / UpgradeTo22

How to upgrade to CherryPy 2.2

This page discusses changes between CherryPy 2.1 (October 2005) and 2.2 (February 2006) which might require you to modify your code when you upgrade. Bugfixes aren't listed here.

CamelCase changed to lowercase_with_underscores

In keeping with [http://www.python.org/dev/peps/pep-0008/ PEP 8], most of CherryPy's API has been changed from CamelCase identifiers to lowercase_with_underscores. See the bottom of this page for a list of the names that have changed. However, every effort has been made to allow you to continue using the CamelCase names (until the next major or minor version). To repeat: both forms of each name should work in 2.2. So change when you can.

There's a new "cherrypy.lowercase_api" flag, so that users can say "I'm using the new lowercase API" and get a (small) speed boost from it.

Positional Parameters

In CherryPy 2.1, you had to use a special class to make your handler methods "Positional Params Aware" (that is, turn "/handler/extra/path/info" into handler("extra", "path", "info")). Starting with [786], any method (except "index") may now receive positional params. Read [http://www.cherrypy.org/trunk/docs/book/chunk/ch03.html#id3226503 3.1 in the book] for a detailed look at mapping and parameters.

Changing which handler gets called

In CherryPy 2.1, if you needed to change which method handles a given URL, you might have changed cherrypy.request.path. In 2.2, you should always change cherrypy.request.object_path instead. See [760] and #373.

Multiple apps and virtual paths

Mounting a CherryPy app at a mount point determined at runtime was very difficult in 2.1. There's a new _cptree.Tree class in 2.2 to make this easier. '''In general, you should stop writing'''

cherrypy.root = Root()

'''and instead write'''

cherrypy.tree.mount(Root(), baseurl="/path/to/app", conf=config)

This new method will mount your app at the appropriate branch on the cherrypy.root tree, and will also auto-prefix the section-paths in the config dict you supply. If you don't supply the baseurl arg, it will look for a "mount_point" config entry in [global] and use that.

The "old way" of writing cherrypy.root = AppRoot() will still work, but restricts your app to being mounted at "/", and may preclude other applications from being mounted on the same server.

server.environment

The behavior of each "server.environment" (such as "development", "staging", and "production") was hard-coded into the core in 2.1. Beginning with [761], these behaviors are encapsulated in cherrypy.config.environments. This allows you to write an application that modifies the builtin environments, or adds new named environments, to give your deployers flexibility that is specific to the needs of your application.

Error handling

CherryPy 2.2 makes the distinction between ''HTTP errors'' (return codes between 400 and 599) and ''unhandled exceptions'' (which will result in a 500 return code) a bit more explicit. You override the response to ''unhandled exceptions'' with _cpOnError. To override the response to ''HTTP errors'', there's a new _cpOnHTTPError(status, message) function. See [771].

There's also a new "server.log_unhandled_tracebacks" config entry (see [805]), which is distinct from "server.log_tracebacks".

The cherrypy.log function grew a new "traceback" argument and made the msg argument optional. It was:

log(msg, context='', severity=0)

and is now:

log(msg='', context='', severity=0, traceback=False)

Response.body

cherrypy.response.body is now a descriptor, which means that '''anytime''' you set .body now it will be coerced to an iterable. There's a new response.collapse_body() function (mostly for use in filters), which collapses the body into a single new_body string, sets response.body to [new_body], and returns new_body.

There's also a new request.execute_main flag (bool), to govern whether the Request.main method is called. This replaces the old behavior, where main would be called "if response.body is None". There may be custom before_main filters which depend on the old behavior, and need to be updated to set request.execute_main = False (instead of just relying on setting body).

Just Plain Gone (or otherwise mangled)

  • [772] removed cherrypyrequest.paramList and cherrypy.request.originalParamList. These were only used by xmlrpcfilter, and it was better to keep that functionality entirely in the filter without stuffing it into the core.
  • [777] changed root._global to root.global_. If you don't define it, there's a new default _cpGlobalHandler in _cputil which will be called.
  • Lots of functionality that isn't CherryPy-specific got moved into a new, improved lib/httptools.py module. If you're looking for something from 2.1 and can't find it, look in httptools first.
  • cherrypy.request.browser_url is now a read-only property, since it is a calculated value. If you want to change its value now, change request.base, path, or query_string, and it will be updated automatically. See [793].
  • cherrypy.request.originalParamMap is deprecated in 2.2, and will be removed in 2.3.
  • [839] removed the custom exceptions !WrongResponseType and !WrongUnreprValue.
  • cptools.serveFile now requires absolute paths. See [909].

Filter changes

  • cherrypy/lib/filter has been moved to cherrypy/filters (but the old location should still work until CP 2.3).
  • New on_end_request filter method, which runs after the entire response has been written out. See [838].
  • xmlrpcfilter no longer allows None as a response value. See [785].
  • If staticfilter didn't find a file, it used to error. Now it proceeds, trying to find a dynamic handler (like any other request). See [878].
  • The before_main filter hook can now raise InternalRedirect. See [879] and #55.
  • The !VirtualHostFilter has been reinstated. See [883] and #344.
  • Staticfilter now requires absolute paths. See [909]. The easiest way to do this is to provide a "static_filter.root" config entry.
  • The internals filter architecture changed. The config options server.filtersRoot, server.inputFiltersDict and server.outputFiltersDict were removed in [807] in favor of a code-bound solution. The attributes filter._input_order and _output_order used to each be a list of class names (like 'CacheFilter'). They are now called filters.input_filters and filters.output_filters, and each is now a list of full dotted-package-class-names (like "cherrypy.filters.cachefilter.CacheFilter"). This means you can now insert your own classes (either classname strings or the filter class itself) in each list; they are invoked in order. See [891] and [903].
  • All on_start_resource and on_end_request filter methods are now guaranteed to run, even if there are failures in other on_start or on_end methods. This is NOT true of the other filter methods. See [911].
  • Having staticfilter on doesn't automatically disable sessionfilter anymore. See [960].
  • The sessionfilter now sets "Expires" instead of "Max-Age" for the session cookie. See [963].
  • sessionauthenticatefilter has new "on_login" and "on_logout" callbacks. See [971].

HTTP Servers

First, [973] removed the deprecated _cphttpserver module. Use _cpwsgiserver instead, which now has AF_UNIX support and respects server.socket_queue_size. It can also mount multiple apps, now, see [965] through [967].

Second, cherrypy.server.start has a new optional "server" argument, so you can pass in an instance of an HTTP server instead of just a class.

Third, if you have a custom HTTP server, the API for submitting requests to the CherryPy core has changed (see [758]). You no longer need to call request.purge__() and response.purge__(); instead, write code like the following:

request = cherrypy.server.request(client_address, remote_host)
request.multithread = True
request.multiprocess = False
response = request.run(raw_requestline, headerlist, rfile)

Note that the arguments which used to all be passed to request() are now split up between the constructor and the run() method. When you're ready to write out the response, use the response object returned from request.run() instead of using cherrypy.response.

In order to facilitate the new on_end_request filter method, you also '''must call request.close()''' once your HTTP server has completely written out the response to the client. See [838] and [851].

Finally, if you patched _cpwsgiserver to handle some socket errors, you should revert those patches (some were fixed) and add any new error codes to _cpwsgiserver.socket_errors_to_ignore instead.

The Request object

The Request class in _cphttptools has changed, as well. It used to create cherrypy.request, now it *is* cherrypy.request.

Test suite changes

The test suite has been reorganized to allow testing with other WSGI servers. Basically, you have to write future tests as if the server-side and client-side run in separate processes. If you wrote tests for your application using the tools in CherryPy's test suite, you may have to rewrite them so that they also obey this separation.

Name changes

''' The old variable names will still work until at least CherryPy-2.3, but they are considered deprecated '''

Variables:

'''Old name''''''New name'''
cherrypy.threadDatacherrypy.thread_data
request.paramMaprequest.params
request.queryStringrequest.query_string
request.headerMaprequest.headers
request.browserUrlrequest.browser_url
request.simpleCookierequest.simple_cookie
request.objectPathrequest.object_path
request.remoteAddrrequest.remote_addr
request.remoteHostrequest.remote_host
request.remotePortrequest.remote_port
response.headersresponse.header_list
response.headerMapresponse.headers
response.simpleCookieresponse.simple_cookie
server.onStartServerListserver.on_start_server_list
server.onStartThreadListserver.on_start_thread_list
server.onStopThreadListserver.on_stop_thread_list
server.onStopServerListserver.on_stop_server_list
cherrypy.config.configMapcherrypy.config.configs
_cpLogAccess_cp_log_access
_cpOnError_cp_on_error
_cpLogMessage_cp_log_message
_cpOnHTTPError_cp_on_http_error
_cpFilterList_cp_filters

Config options:

'''Old name''''''New name'''
server.threadPoolserver.thread_pool
server.socketPortserver.socket_port
server.socketHostserver.socket_host
server.logToScreenserver.log_to_screen
server.logFileserver.log_file
server.logFileNotFoundserver.log_file_not_found
server.showTracebacksserver.show_tracebacks
server.logRequestHeadersserver.log_request_headers
server.socketQueueSizeserver.socket_queue_size
server.logConfigOptionsserver.log_config_options
server.reverseDNSserver.reverse_dns
server.logTracebacksserver.log_tracebacks
server.logUnhandledTracebacksserver.log_unhandled_tracebacks
server.logToScreenserver.log_to_screen
server.logAccessFileserver.log_access_file
server.maxRequestHeaderSizerequest.max_request_header_size
server.protocolVersionserver.protocol_version
errorPageerror_page
server.maxRequestBodySizeserver.max_request_body_size
streamResponsestream_response

Filter config:

'''Old name''''''New name'''
baseUrlFilter.onbase_url_filter.on
baseUrlFilter.baseUrlbase_url_filter.base_url
baseUrlFilter.useXForwardedHostbase_url_filter.use_x_forwarded_host
cacheFilter.oncache_filter.on
cacheFilter.keycache_filter.key
cacheFilter.delaycache_filter.delay
cacheFilter.maxobjsizecache_filter.maxobjsize
cacheFilter.maxsizecache_filter.maxsize
cacheFilter.maxobjectscache_filter.maxobjects
decodingFilter.ondecoding_filter.on
decodingFilter.encodingdecoding_filter.encoding
encodingFilter.onencoding_filter.on
encodingFilter.defaultEncodingencoding_filter.default_encoding
gzipFilter.ongzip_filter.on
gzipFilter.compresslevelgzip_filter.compresslevel
gzipFilter.mimeTypeListgzip_filter.mime_types
logDebugInfoFilter.onlog_debug_info_filter.on
logDebugInfoFilter.mimeTypeListlog_debug_info_filter.mime_types
logDebugInfoFilter.logAsCommentlog_debug_info_filter.log_as_comment
logDebugInfoFilter.logBuildTimelog_debug_info_filter.log_build_time
logDebugInfoFilter.logPageSizelog_debug_info_filter.log_page_size
logDebugInfoFilter.logSessionSizelog_debug_info_filter.log_session_size
nsgmlsFilter.onnsgmls_filter.on
nsgmlsFilter.tmpDirnsgmls_filter.tmp_dir
nsgmlsFilter.nsgmlsPathnsgmls_filter.nsgmls_path
nsgmlsFilter.catalogPathnsgmls_filter.catalog_path
sessionAuthenticateFilter.onsession_authenticate_filter.on
sessionAuthenticateFilter.checkLoginAndPasswordsession_authenticate_filter.check_login_and_password
sessionAuthenticateFilter.loginScreensession_authenticate_filter.login_screen
sessionAuthenticateFilter.notLoggedInsession_authenticate_filter.not_logged_in
sessionAuthenticateFilter.loadUserByUsernamesession_authenticate_filter.load_user_by_username
sessionAuthenticateFilter.sessionKeysession_authenticate_filter.session_key
sessionFilter.onsession_filter.on
sessionFilter.storageTypesession_filter.storage_type
sessionFilter.storagePathsession_filter.storage_path
sessionFilter.timeoutsession_filter.timeout
sessionFilter.lockingsession_filter.locking
sessionFilter.onCreateSessionsession_filter.on_create_session
sessionFilter.onDeleteSessionsession_filter.on_delete_session
sessionFilter.cleanUpDelaysession_filter.clean_up_delay
sessionFilter.cookieNamesession_filter.cookie_name
sessionFilter.deadlockTimeoutsession_filter.deadlock_timeout
sessionFilter.storageClasssession_filter.storage_class
sessionFilter.getDBsession_filter.get_db
xxx.acquireLockxxx.acquire_lock
xxx.releaseLockxxx.release_lock
xxx.cleanUpxxx.clean_up
staticFilter.onstatic_filter.on
staticFilter.matchstatic_filter.match
staticFilter.filestatic_filter.file
staticFilter.dirstatic_filter.dir
staticFilter.rootstatic_filter.root
tidyFilter.ontidy_filter.on
tidyFilter.tmpDirtidy_filter.tmp_dir
tidyFilter.strictXmltidy_filter.strict_xml
tidyFilter.tidyPathtidy_filter.tidy_path
tidyFilter.errorsToIgnoretidy_filter.errorsToIgnore
xmlRpcFilter.onxmlrpc_filter.on
xmlRpcFilterOnxmlrpc_filter_on
isRPCis_rpc

Fitler hooks:

'''Old name''''''New name'''
onStartResourceon_start_resource
beforeRequestBodybefore_request_body
beforeMainbefore_main
beforeFinalizebefore_finalize
beforeErrorResponsebefore_error_response
afterErrorResponseafter_error_response
onEndResourceon_end_resource
onEndRequeston_end_request

Method parameters:

'''Old name''''''New name'''
initOnlyinit_only
serverClassserver_class

Updated