Yet Another Comparison of Python Web Frameworks

Author: Michele Simionato
Date: October 2007


You can find on the Net hundreds of reviews/comparisons of Python Web Frameworks, yet they are never enough, since new frameworks continue to appear every day and old frameworks continue to change at an even faster rate. At work we are now shopping for a new Web framework, so I am looking at the available options and I have decided to write this document which may be of help to others in the same situation.

Let me start with a word about me: I have already experience with many Web frameworks (Zope/Plone, Twisted, Quixote, CherryPy, QP and Paste) and I am probably competent enough to write my own, if I wished [1]. My colleagues at work are all competent Pythonistas but we are not really into Web programming. We actually do financial software and we just need a Web interface to manage the requests of our customers. In other words, we are NOT looking into a framework to write e-Commerce sites, community sites, blogs, etc. We need a building block on top of which to write a very customized application which fits our very specific needs. So my evaluation below (this framework is "good"/"bad") must be read in the light of our requirements, not in absolute terms.

[1]Notice that I claim that I am competent enough to write a Web framework, but I do not claim that I am competent enough to write a good Web framework.

Of Plone, Quixote, QP, CherryPy and Twisted

The framework we use at work now is Plone and I have been using it for four years; I never liked it, even at the beginning (it was my first Web framework) and every day I dislike it even more. My colleagues are not fond of it either and this is why for new projects we are looking at a different framework. Of all the frameworks I cited before, the one I like the most for its design and philosophy is Quixote (perhaps not coincidentally, since it was designed from the beginning to be an anti-Zope framework). Some (Ian Bicking IIRC) labelled Quixote as "the framework for hackers", since it is really designed for old school boys used to the Unix way of thinking, and also because its marketing totally sucks [2].

Quixote makes the uncommon choice of using Python as template language (well, actually they hacked a bit Python to make what they call PTL (Python Template Language) [3], but the differences with pure Python are minimal) which I wholeheartedly support. Templates makes sense if you have mostly static pages and if you work with graphical designers, but neither is our case.

I think Quixote can still be recommended for some users (for instance, if you want an absolutely stable framework you should go with it, since its development virtually stopped years ago and it will probably never resume) but most people probably will not want to start with a "dead" framework. I looked at the successor of Quixote, QP, which shares the same philosophy. It is fine but it is nearly completely undocumented, it is less simple than Quixote, and it is even less known and used.

I looked at CherryPy, but I never did anything serious with it, because at each new major version (1, 2, 3) they completely broke backward compatibility and this was a showstopper for me. I used Twisted Web, and it is fine, however:

  1. Twisted Web is going to be replaced with Twisted Web2, so there is no point to use it for new projects;
  2. Twisted Web2 has been in development for ages and who knows when it will be finished;
  3. In any case using Twisted means that we have to rethink various applications we have (which are blocking) and that we must use Twisted.enterprise and not the support for database we already have and know well.

In short, Twisted Web is cool but is seems a risky choice at the moment. Twisted developers themselves basically say "don't use it unless you feel adventurous" [4] .

At EuroPython 2006 I grokked WSGI and after that I am convinced that WSGI is the one obvious way to go. So I looked at Paste and I was happy with it. Actually, the more I look at Paste the more I like it. That does not means that I like Paste in full (for one, I don't care at all about the thread support, I am convinced the right way to go is to write single-threaded programs and to run them in multiple processes, for instance via Apache and mod_wsgi) but it is well written in the sense that I can extract from Paste what I need and write my own framework with almost no effort. This was the design goal of Paste from the beginning and I think Ian Bicking succeded; this is not a minor feat.

OTOH, we asked ourselves "why should we write our own framework on top of Paste where there is an already written framework built on top of Paste called Pylons"? So we evaluated Pylons on the field, by writing a couple of test applications and by porting a pre-existing Paste application. A detailed summary of our finding follows.

[2]which is one of its strongest points IMO.
[3]nowadays PTLs have been superseded by a "templating" system called qpy which is a newer and improved version of PTLs, practically backward-compatible and used in the framework QP; I still say "templating" with quotes, since in pratice this is not a real templating language, it is just pure Python with minimal changes.

Of Pylons

Pylons has got some good press recently and people I trust spoke well of it in, so I started with good hopes. At the present, however, I am not as happy as when I started. The impression it that the framework is still new, still fragile, too much cutting edge and with too many dependencies. This was not entirely unexpected, though. However I did expect porting a Paste application to Pylons to be a breeze: it turned out it was not the case. Probably most of the problems we encountered are due to our ignorance with the framework, but still I would have expect to encounter much less issues [5].

Pylons is basically a collection of third party eggs with some glue in it. The Pylons-related eggs I have in my site-packages are the following (in alphabetical order):

  1. Beaker-0.7.5-py2.5.egg
  2. decorator-2.2.0-py2.5.egg
  3. FormEncode-0.7.1-py2.5.egg
  4. Mako-0.1.8-py2.5.egg
  5. nose-0.10.0b1-py2.5.egg
  6. Paste-1.4.2-py2.5.egg
  7. PasteDeploy-1.3.1-py2.5.egg
  8. PasteScript-1.3.6-py2.5.egg
  9. Pylons-0.9.6-py2.5.egg
  10. Routes-1.7-py2.5.egg
  11. SQLAlchemy-0.3.10-py2.5.egg
  12. WebHelpers-0.3.2-py2.5.egg

Here is my evaluation of each of them, using the Pythonic score of +1, 0, -1 (+1 means "good for the kind of applications we are interested in", -1 means "not good", 0 means I have not strong opinion).

  1. Beaker [?]

It is the session management mechanism. I still have to evaluate it.

  1. decorator [0]

I am the author of this module and it may surprise people that I am not +1 on it. But the reason is easy to explain, once you understand why I wrote the decorator module in the first place. The decorator module comes out from a shortcoming of the standard library: as of now, it is very difficult to write signature-preserving decorators unless you use the decorator module or the DecoratorTools by P.J. Eby. I wrote the module to make people aware of this shortcoming and hoping from a better solution at the core Python level. The better solution is now forthcoming (PEP 362 Function Signature Object [6]) and in future versions of Python it will be possible to fiddle with the signature of functions directly. Then the decorator module will become obsolete and I don't want to use in production a technology which I am already know is going to be obsolete. On the other hand, it may take years before we switch to a Python version with a proper signature object so the decorator module can be useful meanwhile. Finally, I do not use many decorators in practice (I use them only if there are no better alternatives). This is why my score is 0 for the moment.

  1. FormEncode [?]

I have not looked at it in person but my coworker Lawrence Oluyede says it is okay.

  1. Mako [-1]

As I said before, as a matter of principle I am against templating language and I prefer to write Python code. Template languages makes sense if you pass them to a graphic designer, but then they should be valid (X)HTML, compatible with the tools used by the designers and this is not the case of Mako. Besides, nowadays everything graphic should be done with CSS and I see nothing bad in generating the page from Python. Separation of logic and presentation is a matter of discipline and has nothing to do with the existence of a templating language. Besided, in our firms everybody understand Python better than HTML.

  1. nose [+1]

The unittest framework in the standard library sucks and we absolutely need something better, compatibile with the past, easy to install and that works. I think nose fits the bill. I especially like the py.test inspired (a better word would be stolen) features. Incidentally, the change form nose-0.9 to nose-0.10 once broke my Pylons installation, this is one of the reasons I say Pylons is fragile. Also I would recommend to use just the basic features of nose because I am sure these will stay, where other things like the plugin system have already changed.

  1. Paste [+1]

As I said I like Paste. It is well written, well documented and with a design philosophy I agree with. As I said the only thing I am skeptical about is the thread support. Notice that I do not mean that Paste support for threads is of of low quality (far from it!): it is just that I am on the anti-thread camp and that by choice I avoid them when I can. The thread support is making Paste much more complicated that it would be without it. Anyway, I am sure the thread support will make happy the fans of threads and the poor guys condamned to work on platforms without fork.

  1. PasteDeploy [-1]
  2. PasteScript [-1]

I am a big fan of .INI configuration files for simple applications. However, the configuration of a Web application is complicated enough to stretch the limit of .INI files. So I don't like particularly the Paste configuration mechanism. I think the configuration file should be in a format like JSON or in pure Python. At work we already use a configuration mechanism based on configuration classes (so that we may inherits from configurations) and it is easier for us to build on it than to use Paste mechanism. Moreover I have already equivalents of the paster utility, which I wrote by stealing ideas from QP; it is not surpring in retrospect to discover, by looking at the comments in the source code, that Ian Bicking went further and even took code from QP.

  1. Pylons [-1]

I don't think Pylons is adding much value to the other components. I think it would take less time to write myself the glue code than to understand how Pylons did it. As a proof of concept yesterday I took the two test Pylons application we wrote and I removed the dependency from Pylons in four hours. I just had to write a few lines of code for the SQLAlchemy support and a few lines for the javascript support. Then I removed the mako templates, I converted the Pylons controllers into pure WSGI applications and I removed Routes support by using paste.URLMap instead. I think now the code is much simpler, less coupled and it does the same with smaller effort and exactly as I want it to do it.

  1. Routes [-1]

I have no Ruby On Rails background, so I don't see the advantages of routes.

  1. SQLAlchemy [?]

SQLAlchemy is big and should be evaluated on its own. One thing to say is that the change form 0.3.9 to 0.3.10 broke our test application, and that SQLAlchemy did not cooperate well with pymssql. So, I would still wait until the framework will stabilize.

  1. WebHelpers [?]

I still have to evaluate it.

[5]for instance we had a Paste application making plots, saving them in a temporary file and returning them as 'image/png'; in Pylons, to make Routes and the Controller happy, my coworked Lawrence had to copy the temporary file in the public directory and to remove the start_response call in the original code.

What about Diango?

I can't say anything about Django, since I never used it. However my coworker Lawrence who has used it says it is this more stable and better thought than Pylons and I usually believe Lawrence.


All in all, at the moment I am not much in favor of Pylons over Paste. OTOH, it may happen that a killer application will appear for Pylons, which will help enormously with our business, so we may still want Pylons with all its dependencies. As of now, I would do our things in Paste and wait and see for the new developments in the Pylons word.

Disclaimer to the reader: since I only spent a couple of days for this evaluation, in the future I may well realize that I was wrong and change my mind. So take this evaluation (as any evaluation) cum grano salis. You and only you can decide what it is good for your situation.