Ian Bicking: the old part of his blog

Cherrypy and RhubarbTart

I thought I'd... discuss these two frameworks. I don't have any conclusions or summaries or explanations. History?

Anyway, a while back I was working on CherryPaste and I got frustrated with CherryPy. There were problems with CherryPy's WSGI support, and some design changes that just seemed obvious to me -- mostly internal refactorings I wanted to see happen so that CherryPaste could call functions that were a bit more explicit about what was happening, with no singletons and no injection.

I think at that point I was doing some more bitching and whining on #pythonpaste, and Julian Krause was on there too and was feeling a bit annoyed with CherryPy at the time as well (actually about sessions if I remember correctly, a now-resolved problem which is unrelated to anything else here). And he brought up the idea of reimplementing. Or maybe I did. Anyway, so we reimplemented it; he moved over the URL parsing, I set up the package using Paste, and after about a day or two we had a pretty reasonable framework. Frameworks can be really easy to write (and I wrote that document in part because the framework came out so easily and it seemed like a good example). And we searched around for names -- I like Rhubarb Pie, a search on "Rhubarb Python" came up with this, and the name seemed just perfect.

So, what is RhubarbTart? It is functionally pretty much equivalent to CherryPy. That is, it feels similar to work with, the APIs match CherryPy's as much as possible, and all the same features are available. Most of those features actually came from other places, they aren't implemented in RhubarbTart, and that's part of the point as well. The core feature is that RhubarbTart makes a request object, does some URL path parsing, and does a function call and gets a response. It also interacts nicely with WSGI applications, which you can put anywhere in your tree. All the other features are just wrappers coming from elsewhere.

The one thing RT is missing is CherryPy's filters, and there aren't any plans to implement those. CP's filters are kind of complicated, and backward compatibility is hard, and some of the features they implement are a little weird to use in filter form -- like serving static files. Why you don't say static = StaticFiles(directory) in CherryPy, I don't really understand. I've also seen lots of concern about performance, and in my own experience with CherryPaste (which uses filters) the failure cases are confusing.

RhubarbTart will probably be getting somewhat larger, in that more URL resolution schemes will be added, Routes in particular. We also brainstormed some ideas at the PyCon sprint about adding flexibility. I think what we came up with is going to be a lot more general and workable than what you'll see in most other frameworks (like Quixote, Zope, etc). Instead of magic methods and complex overrides, there's just one override -- stop here, aka __call__ or respond. If you want to capture some information then continue parsing, then you capture and call the parser. All sorts of features fall out of this easily, more than traversal hooks offer.

But after that... I don't see any reason for RhubarbTart to get larger. Getting back to sessions, Julian wasn't really happy with Paste Sessions (probably for good reason), and created a Myghty session WSGI middleware. But it's not part of RhubarbTart. Once RT's small number of features are fully worked out -- which shouldn't take too long -- I expect it to become a very boring and stable piece of software. Already Ben Bangert is looking at whether Pylons can be built on RT, and we have TurboGears on it in a branch.

At the same time RhubarbTart may be getting smaller. We're probably going to move the request object out to Paste, with a subclass in RhubarbTart that adds a few CherryPyisms. I've been reluctant to add any request object to Paste in the past -- it seemed like it was too framework-specific -- but this time around it feels much better to me. Ben has put up some code in paste.request.

Now, back to CherryPy. Since the time of my frustration there have been several improvements with its WSGI support. There's also talk of a CherryPy 3. I really don't know how the two will continue to relate. There was some reluctance to embrace WSGI whole-heartedly. I think this is a bad idea -- supporting WSGI as one-among-many backends is not very sensible, it's just more code. I had a similar reaction from Django developers at one time too, where they didn't want to use a particular piece of WSGI middleware because they supported a WSGI and a mod_python frontend (despite the fact the whole concept was impossible under mod_python anyway -- not to mention that you can make a mod_python WSGI server easily enough).

But I digress. So, what if CherryPy is simplified in version 3? I'm not sure if they will be simplified towards what RhubarbTart is doing or not; in particular, there is a strong tendency to make traversal hooks instead of making traversal easy to reapply. If CP 3 does become like RhubarbTart, I'm not sure what the point of the distinction will be. Except, I suppose, that they are developed by a different set of people. If that happens, then even though they don't have any shared code lineage at this time they'll effectively be forks. I don't think that's a huge problem, but it's a funny place to be in.

Created 09 Mar '06

Comments:

I didn't know Rhubarbtart until now. Argh. Some weeks ago i've started to work on Colubrid which absolutly fits my needs but Rhubarbtart seems to look very similar (compared with the object application). Maybe I should have a look at it.

# Armin Ronacher

I guess it is ok to write Yet Another Framework if it is yours, eh? ;)

Seriously, I like the fact that there are so many frameworks from which to choose, and I hope yours meets with success. I also hope this means that you are no longer in the "frameworks suck" camp.

# L. Daniel Burr

I don't worry about the Yet Another thing anymore, I got over that at least a year ago. People spout on about What We Need To Do, but they are approaching it from the wrong angle in this case, I think. We don't need a clear choice for Python, we need compelling choices that happen to be written in Python. And we need to do the best to build a common and comfortable infrastructure, and to break down unnecessary barriers, and so forth.

I do still feel that frameworks suck. Shit smells too, but I don't shove a plug up my butt in the hope I'll never produce anymore shit. Frameworks suck, but they are inevitable. I just hope that they can be small and stay in their place.

# Ian Bicking

Is Routes name resolution high on the priority list? I'd be really interested in it. Ideally, I'd like to manage my URL's as a bunch of string/object mappings and totally bypass the normal cherrypy object hierarchy. I am particularly revolted by the object hierarchy because of the potential for name collisions. For example, I start with something like this:

class Root(object):
    def index(...):
        ...
    expose(index)

    def otherstuff(...): # not exposed...yet
        ...

root = Root()

Later I decide to expose a URL "/otherstuff", which means I have to refactor my Root class. If I forget to do this and just tack it on like this:

root.otherstuff = OtherStuff()

which overwrites the original otherstuff attribute...HORRIBLE! Method names should be decoupled from URL mappings. This can mean a small bit of duplication, but it is usually all in one place (i.e. in the file that contains object/url mappings).

The other reason I want Routes is so I can map any URL to any function (even if the URL is not a valid Python identifier).

# Daniel

Daniel, have you seen the custom cherrypy Request object for Routes I threw together? It allows you to totally bypass the CherryPy dispatch mechanism. http://www.aminus.org/blogs/index.php/fumanchu/2006/02/26/making_a_custom_cherrypy_request_class_f

# Robert Brewer

Ian, let me know about anything that applies to Quixote. I'm making a branch version of Quixote with native WSGI, and I'd like to do a second version that integrates with Paste (with everything that duplicates middleware removed). Routes support is a significant desire too.

My reason for this is I like Quixote's smallness and reliability, yet WSGI and Paste are clearly the way of the future. CherryPy and TurboGears are great but they're more complex than I'd like. (Complexity => Murphy's law) So I see a future for Quixote-style applications integrated with Paste.

One issue is needing a fake 'quixote' importable to access the request/response/session objects. But that shouldn't be any more difficult than a fake 'cherrypy'.

Another question is which session middleware to use. Would session2 as middleware be generally useful, or is there already a middleware object with the same backends? Note that Quixote applications are accustomed to adding attributes to the session rather than dict items, especially the .user attribute, so this would need to be supported.

PS. it would be nice if this blog showed the article publishing date at the top. It took me a while to find it near the "Add comment" button.

# Mike Orr