For a new web project we’re working on, we wanted to use a dynamic environment. Initially we considered Ruby on Rails, but after using it for some time decided the shortcomings of the framework and the language outweigh the benefits. We’ve resolved to use Python, a language we feel very comfortable with, and I went to test several pythonic web components, in particular the stuff that gets bundled with TurboGears and web.py (we briefly considered Django, the web framework adopted by Python’s creator Guido van Rossum, but identified all of the same problems we had with Rails, so we didn’t spend too much time with it).

TurboGears

TurboGears is a collection of Python web components, rather than a top-down complete framework like RoR. It uses CherryPy for the controller (using WSGI for low-level infrastructure), SQLObject for database access and manipulation, [old link: http://kid-templating.org/ ] Kid for templating and [old link: http://mochikit.com/ ] MochiKit as its main Javascript library. On top of that TurboGears provides several integration tools which are supposed to turn this collection into a ‘framework’ (a skeleton generator, some simple web-bsed administration, a shell preloaded with the project modules, etc).

My experience working with TurboGears has been much better than working with RoR. Partly, that’s because I know and like Python better than Ruby, but mostly the approach is saner and much less demanding – there’s very little magic, and it’s quite easy to understand how to go about implementing your ideas. With TurboGears I was able to complete the same amount of work I did in my RoR test in ~20% of the time!

I wasn’t very impressed with the framework / integration parts of TurboGears. The quickstart tool (for building the skeleton) did some stuff that was quite obvious and I could have completed myself with little effort, and some stuff that I didn’t expect or want it to do (just like RoR). The shell is convenient, but again, I felt that I paid a price in flexibility without gaining much – after all that’s just the Python REPL with some modules imported. The build and deployment tools are a great idea, but they don’t seem to be powerful enough, and extending them may or may not be easier than just doing it ourselves using a build tool like SCons or Make, or simply writing straight python scripts.

Components

Data Access: SQLObject – When we first tried out SQLObject we found it enticing – the interface is simple and easy to understand and the features it provides looked like a perfect match for our needs. After working with SQLObject for a while, however, we were shocked to discover that it’s hardly adequate. SQLObject’s model of working with databases is naive, at the very least – for every attribute you set (on a data-bound object) the mapping issues a separate SQL update statement and what’s worse, if you plan to use SQLObject’s cache (which is the only way to use it efficiently to query the database) you can simply forget about transactions. I find it hard to understand how TurboGears can get away with that – after all, with optimization and ACIDity thrown out of the window, it’s hard to see in what way saving objects to a relational database is any better than simply [old link: http://docs.python.org/lib/module-pickle.html ] pickling them.

Templating: Kid – Kid is an attribute language (like ZPT) – it allows you to generate XML by inserting special attributes instructing the processor how to do dynamic things (like looping, inserting values and so on). Unlike ZPT, Kid is much more pythonic – almost all constructs map directly to control flow structures known from Python. I was able to start working with Kid without having to read any of the documentation and got good results immediately. (Kid is now slowly being replaced by Genshi as the state-of-the-art in Python XML templating, but for our needs we felt that Kid is just good enough).

Javascript / AJAX: MochiKit – I had quite a lot of previous experience with MochiKit, so I didn’t bother testing it in this context. MochiKit shines in comparison to other JS libraries (Prototype, Dojo, YUI) – it is very high quality, got excellent documentation, and anyone with experience using Python or any functional programming languages will feel very comfortable using it. I prefer it to any other JS library.

Controller: CherryPy – I didn’t like CherryPy, although it did look adequate. Particularly, CherryPy relies on mapping Python objects and attributes to HTTP access more than I would like it to. My experience working with web.py was better (the library is richer and provides some neat facilities for rapid development, the mapping of requests to handlers is saner).

We ended up deciding to mix and match – we use web.py as a controller. Instead of an ORM we design our own model objects and connect them to the database using web.py’s data access facilities. We use Kid for templating and some other Python libraries for supporting more specific features of the website.

Conclusions

Dynamic languages and frameworks are the hot thing in web development for a good reason, but RoR’s lead is not wholly justified. 1

Python has a huge collection of frameworks and components for web development, but the quality varies quite a lot. Choosing the right mix of tools and libraries can be difficult, but being able to mix and match gives you great power and flexibility.

TurboGears is a nice take on this idea, but the choices made are dissatisfactory.

Web.py is an excellent start, but to do useful things you’ll have to augment it with bits from other sources.