Thursday, March 09, 2006

Python Web Application Frameworks (Part 4: In Which It All Ends Happily)

This is it! Part 4! We've made it! Exclamation! After parts one, two, and three, I can finally introduce you to today's top players in the web application arena. We've got nine titles to cover, so let's hop right in and see how they stack up.

This is not going to be a detailed review, because that is impossible. By the time I installed every package and gave them a good workout some would be well on to newer versions, and so the comparison would be stale. And the more details one gets bogged down in the less one sees the important overview. So rather I'll summarise other reviews and some of the voluminous discussions that have occurred on the web of late. All this will be filtered through my particular biases and instincts. Which is why you are reading this blog and not some other1.

TurboGears is designed to select the best components and bring them together in a well organised manner. As such it packages CherryPy, SQLObject, and Kid, with some bonuses like Mochikit for JavaScript. The upside to this approach is that as TurboGears gains popularity, it helps all of its components along. The downside is that if you don't want to use this combination of tools you'll go somewhere else. And I don't, so I will. But here's someone who does. (Sorry, that was difficult to follow. I need more caffeine.)

Proponents of TurboGears will say that if you don't like CherryPy (for example) you don't have to use it. TurboGears also works with mod_python and lighthttp. CherryPy itself is an example of this approach: it has a default way of working that you don't need to use. For example, sessions works over cookies but you can choose a different method. Classes compile to standalone servers but you can use other (more standard) web connectors. And so on. What some see as flexibility I see as confusion. What is the point of choosing a product designed to integrate "best-of-breed" solutions if you are going to swap them out?

Put another way: I would rather build up from independent components than have to tear down an integrated structure.

Subway also packages CherryPy and SQLObject, this time with Cheetah. This is also not appealing to me. In any case, the project has been terminated.

Django is the biggest "competitor" to TurboGears. It has its own templating system and a large list of functions. The API appears to be designed with little structure, in what has been called the PHP "bag of functions" style. Yuck. Also there's a lot of "clever-clever" stuff going on behind the code, so much so that they have a "magic removal" version due for release soon. Even if they remove some of the fairy dust I am not confident on this product from a design perspective. The developers have gone on record as having no interest in being Pythonic, preferring to attract an audience of non-programmers.

Still, here's someone who likes it.

Pylons operates at a decidedly granular level, as the developer explains. He lists 17 components of a WAF, even more than I came up with in Part 2 of this article. This toolkit approach saves time in tedious integration without constraining the developer to one particular tool for each of the slots. The trick is in making it easy to swap these in and out. Pylons supports FastCGI, SCGI, AJP, or a standalone server. It does not dictate an ORM, though SQLObjects again seems to be the favoured choice.

A good number2 of the components are taken from Myghty which has templating based on HTML::Mason, a component-based architecture, caching, threading support, sessions and is WSGI-compliant. This looks sharp to me, and gives further incentive to check out Pylons.

At a similar library level of (non-)integration is Paste which contains a server, authentication, testing, URL mapper, logging, exception handling and once again conforms to WSGI. The docs put me off, I must say. But once again, Pylons takes what is good from this toolkit and integrates it.

Jon's Python modules are a disparate collection including connectors for CGI, mod_python, and FastCGI. Additionally you get web templating, session management and a database connection pool.

James Gardner's webmodules provide an ORM, forms, sessions, error handling, WSGI interface, authentication and template parsing (supporting Cheetah).

Finally, mention must be made of Mod_python itself. This is the well known Apache module that embeds a Python interpreter within the web server. As such, it is supported by almost all the other solutions here. But less obvious is the fact that it includes a library of functions for handling requests, sessions, cookies, authentication... many of the elements of a WAF in fact. The major limitation would be the obvious one that it is specific to Apache, not supporting other web server connections. For this reason I would not choose it.

Let's take a big breath and look at what we have. It's quite a list, and even so doesn't come close to the vast number of lesser-known offerings out there floating in the Python universe.

At the top of the list are slick packages solutions that have a greater degree of integration and hence deserve the label "framework". As we get closer to the bottom the glue becomes less binding and the proper description of the product becomes "library". I think the best place to be is somewhere in the middle, where there is a depth of components but a loose coupling that does not lock you in. Building a website is never a simple process repeated for each client; it's different depending on platform, server, and other architectural constraints. And different also based on the product, market, goals, etc. One needs to be flexible, but re-use as much as possible from one gig to the next.

In comparing these products all I can say for sure is that the market is very much more mature than it was even two years ago. No matter which toolkit you choose you will be saved much development time and hassle. You will be able to focus your time not on repetitive infrastructure but on the particular distinct characteristics of the job.

Python is not like Ruby. It does not have a single good solution. It's got eight good solutions (or more!) all worthy of your attention. No matter which choice you make it's the right one3. Nonetheless, I hope this article has saved you much reading and helped point you in a fruitful direction.

In a follow-on article I'll give you some further references.

Me, I'll be looking at Pylons. I will try to give pointers as I go for those following the same path.

1 What's that? You say you are reading some other blog? How metaphysical of you!

2 If you think that five is a good number. Personally, I think it is just fine.

3 And no, I don't think this is a cop-out. Any developer worthy of the name could put one of these products to work and get up and running in a short time.



Anonymous said...

Hey there,

I'm a lead dev of Django. I'm curious to see where you read that we're "having no interest in being Pythonic, preferring to attract an audience of non-programmers." That's quite an inaccurate statement, as we're *very* interested in being Pythonic.

Please point out where you read that, and I'll clarify whatever document needs to be clarified. Thanks for your entry!


robin said...

I will follow up with links for those who want to see more of my context. Some of my impressions come from the freely available code snippets on product sites or blogs. And others from direct statements that I'm buying into. Perhaps a little game of telephone is occurring and, being at the far end of a very distant call, I am misinterpreting.

I am not sure exactly what Pythonic means to all parties. I will simply say that I dislike hidden behaviours, magical name-matching cleverness, overly sugared syntax, any reduce/operator/lambda junk, and other obfuscations. Not that I mean to imply that Django exhibits all of these, just a proper subset.

"Magic removal" says it all to me. Though I suppose the existence of this code branch backs up your statement that you aim to be more Pythonic. I will wait and see.

Eugene Lazutkin said...

Django's template language is for (surprise! surprise!) web designers. Yes, it is easy to implement a presentation logic in it. No, it is not suitable for implementing a business logic in it. That was the intentional separation of concerns. If someone wants to mix them up together, there are "better" solutions: ASP, PHP, and so on.

Another point of Django's templating solution was to make it reasonably secure --- designers cannot break a web site with their mistakes.

Maybe it sounds unnecessary for a 1 man army --- simple pure Python can be good enough for 1 man projects. But if there is a team --- at some point a person realises that in most cases programmers are bad web designers, and web designers are not programmers. Django supports separation of roles, if it is required. I believe this is the point of confusion: "an audience of non-programmers", "no interest in being Pythonic"... :-)


robin said...

Eugene, I agree on two main points. First, my interpretation that Django has "no interest in being Pythonic" was in part driven by a statement by Adrian Holovaty regarding the templating side of the app. Second, template languages should be for web designers not programmers.

However, I do not think the Django templating meets this goal. Visually I find the combination of regular HTML tags and "{%" delimiters to be messy. There are far too many tags and filters for my liking. Any designers I have worked with would be completely overwhelmed.

These tags will also not sit well with various design tools that expect well-formed XML. In this regard, my favourite templating system is Kid. But even there I do not like embedding code blocks and the resulting need for crufty escape characters.

Code should not be in HTML. Period.

Anonymous said...

As a designer who actually uses Django's template language nearly every day, I'd say you're overstating the messiness or overwhelmingness of the syntax. Sure, there are a decent number of tags and filters, but just like any other language, you only ever need a fraction of them at once, and when you do need the extra tags, you can look them up easily and you're damn glad they're there.

I think Django's template language has a good balance of a small core set of functional tags that do most of the heavy lifting of templating, and a good set of utilities available for specific needs.

As for "code should not be in HTML", I guess that's a personal preference. I personally have a distaste for template languages that mix in a lot of pseudo-HTML or even the ones that extend it with XML syntax, which has its own downsides. The nice thing about the Django template language is that you can replace it - with another template language, or pure Python if you want - and there's work being done to make that even easier (and document it).

Anonymous said...

I would like to here about Karrigell which I took now into consideration. Any observation?

Post a Comment