Ian Bicking: the old part of his blog

Pastifying CherryPy

After some discussion on the TurboGears list about Paste, I started looking more closely into what it will take to get CherryPy to work with Paste. I had written a ticket on the matter some time ago, but progress there was slow, and it wasn't clear any resolution was going to come about anyway.

Ultimately I decided I could do it myself, even if I had to work against the CherryPy code a little bit, using threadlocal storage and some monkeypatching to make every CherryPy application think it was the root, and keep all the applications isolated and relocatable, as Paste wants them to be. I didn't read this discussion until I was well into the project, but that's probably just as well; the CherryPy developer there doesn't think threadlocal will work, but really we're coming at it from different directions; I just want one good API, I don't need for it to be the only API in CherryPy (I understand that they have to provide backward compatibility), and I don't need every CherryPy application to work, just the ones that do the Right Thing (where the Right Thing is still somewhat to be determined).

Anyway, the result is CherryPaste. With it you can write a config file like:

[app:main]
use = egg:CherryPaste
root_object = mypackage.rootobj:root

[server:main]
use = egg:Paste#http

And then serve that up with paster serve config.ini, as well as using that to potentially run multiple instances of the same app under different paths, or behind authentication, or with the Ajax debugger in Paste, or what-have-you. I don't have a lot of concrete experience with CherryPy and haven't tried this on many (well, any) large CherryPy applications, but I welcome feedback and experience reports, and hopefully some of the inevitable kinks can be worked out.

One of the misunderstandings that came up in the IRC discussion is about control. Part of the difficulty of CherryPaste is that CherryPy expects to have control of the process, and expects all CherryPy applications to register themselves centrally. So, why should CherryPy support Paste, isn't that just Paste saying that it should be at the top, that it is the more fundamental or proper abstraction?

No, that's not it at all. To work with Paste, an application or framework has to be well encapsulated. It has to be in its own package, it has to have an identifiable entry point, it has to have a clear concept of configuration. Then Paste can work with it. But Paste does not want to own the application (except perhaps at runtime, if it has been so configured). If the application provides a function supporting the paste.app_factory API, it doesn't have to do so exclusively. The application doesn't have to make Paste a requirement, and probably doesn't have to import anything from Paste.

So no, it's not that Paste wants to wrest control from CherryPy, it just needs CherryPy apps to have a clear boundary and not to demand control.

Next up... I'm not sure... create a similar Paste adaptation of Trac (where I could use it to experiment with installation) or Django (which would be more like CherryPaste, but probably requiring less cleverness)?

Created 12 Jan '06

Comments:

"""Part of the difficulty of CherryPaste is that CherryPy expects to have control of the process, and expects all CherryPy applications to register themselves centrally"""

Yep, and while WSGI doesn't explicitly forbid them doing that, it is a rather problematic design flaw from an interoperability perspective. It prevents a web server from deploying independent CherryPy-based applications in the same process at user-defined locations, on different ports, etc. It also makes applying middleware extremely complex. The only reason WSGI doesn't warn against such bizarre behavior is that it never occurred to me that anybody would make a framework with such a peculiar limitation; had I known that it existed, I'd have included should statements to cover it. (E.g., "a framework or application should support creation of independent application objects for use within a given process, to allow deployers to serve multiple instances from the same process, even if single-threaded. Applications should not use global variables whose state is maintained across requests, since this would interfere with creation of multiple application instances.")

# Phillip J. Eby

I would like to see Django. I am not sure of all of the advantages of Paste yet. Still, maybe I will once I want to use more than one web-framework. Although, for now, it looks though Django will cover my bases.

# Brian Ray

A web framework is simply inappropriate for some kinds of applications, like a WebDAV server, so I think it is pretty reasonable to expect to use more than one framework (or a framework of sorts).

# Ian Bicking

I've attempted to encourage this debate on the CherryPy list, with hopes of some comromise. Please see:

http://groups.google.com/group/cherrypy-users/browse_thread/thread/76fc27588351175a/e98f35193377cf9a#e98f35193377cf9a

And do please join in. Thanks.

# Uche