Python Web Frameworks
In these lines I will try to provide an introduction to Python web frameworks, or, at least, to those frameworks I have worked with. I will try to show their most salient features and their weaknesses, from the point of view of my own experience with them, and explain the criteria I would use to choose each framework for particular projects.
Django is always a safe choice. If you need to develop some web application where the data model will not be very complex, and there will be no special requirements, and you want the codebase to be maintainable, extensible, and flexible, Django is perfect. It ships a very sensible set of utilities. The ORM is extremely easy to use, not as complete and flexible as other solutions, such as SQLALchemy, but quite enough for not too complex needs. The html forms library is a pleasure to use, specially in its integration with the ORM. The html template library is good enough, as is the views system. It has solutions for most common problems in web development, and there are loads of add ons in github for most any possible functionality that might be needed in a web app. The documentation is really excellent, and on top of that you will find it difficult to think of any django related question that is not already answered in stack overflow. As an added bonus, django ships with the admin app, that can become a perfect window into your database.
The part in django that I find most lacking is the authorization framework. It consist of users, groups of users, and permissions. Users can be assigned permissions, and can belong in groups that can also be assigned permissions. Django provides a set of basic permissions for each model (add, change, delete), and you can add custom permissions. It doesn’t provide contexts of authorization, or roles as sets of permissions, which are very basic needs, and thus access control can become quite messy in django apps that cater for a few different kinds of users.
With django, more than a question of when would I choose it for some project, for me it’s more a question of when would I *not* choose django: I would not choose it if I knew that the requirements of the project will force me to fight the framework, or use it in an undocumented way. For example with a data model with little structure where a document database is more appropriate, or for some API that will not serve html (and of course I know about django rest framework, but I would try to choose a tool specifically designed for the task at hand).
I will talk here about Zope and Plone even though I would not choose them for any new project; it seems that their prime time is past. However they have been hugely important players, and they are perhaps the main reason that Python is a strong player in the arena of web development. Zope (in its various incarnations: Zope2, zope3, bluebream…) is a framework comparable in scope to django, but bigger, since many things where django uses external tools, are native to Zope (e.g., it provides a full blown object database). And Plone is a web development framework and a fully functional out of the box content management system. Zope and Plone do most of the things in their own special way, different from most other tools, and they do a lot. Developing with Zope and Plone had in my experience two quite clear phases. First, you spent a few months or years where you just struggled and produced little. But once you learnt the Plone ways, it was amazingly productive. Every single part of it is industrial grade, and the gluing is incredibly versatile. In short, I was in love with Plone. But its long ands steep learning curve put off most developers, made it very expensive, and frightened customers.
Pyramid is an offspring of Zope and Pylons. Its developers come from the Zope world, and took from Zope the basic tools they used to build the framework, mainly the ZCA, or zope component architecture. And Pyramid replaced the basic framework in the Pylons project, that had previously been built in a too rigid manner, so that Pyramid now provides easy integration with other Pylons subprojects, such as deform, the html forms library.
Pyramid is more flexible than django, in many ways, thanks mainly to the ZCA. You can choose different object stores, integrating natively with both the ZODB or SQLAlchemy. It is natively integrated with the Chameleon templating library, but you can easily replace Chameleon with e.g. Jinja2, or Mako. You can also choose among different modes of routing the requests. In addition to all this, the ZCA allows you to programmatically override any of the internal components of the framework. This provides for a model that would excel with large community and a rich ecosystem of add-on components, which is a bit lacking.
There is also a full blown content management system built on top of Pyramid, called kotti, that looks promising.
In general I would not choose Pyramid, but that is probably a matter of personal preference. Once django is out of question for some web project, I would think of either Pyramid or Flask(/bottle). With Pyramid you would have to configure and extend components, that already have their place within the framework; with Flask/bottle, you have to develop the components (or choose them from pypi) and then provide the plumbing.
Flask is usually called a microframework. It provides request and response objects, extended from Ian Bicking’s WebOB, routing of requests, a flexible way of hooking views into routes, integration with the jinja2 template library, and basic facilities such as sessions. It also brings out of the box development support, with a built-in development server and debugger, and integration of unit tests.
As said, I would use flask, rather than django, when you need more control over your stack: For example, if django’s ORM does not fit with your data model, or you want to use a no-SQL database engine, flask will allow you to naturally choose one or another data store, whereas with django you would be fighting the framework if you were to try to use something other than its ORM.
Bottle is the smallest of the lot, since it consists on just one 4346 lines long python module. It provides WSGI integration, request objects form WebOB, routing of requests, support for integration with any of a few templating libraries, and a development server. The philosophy for using bottle is basically the same as that for flask, taken to the extreme: maximum control over your stack.
It is important to not be fooled by its size into thinking that it is some small toy not fit for production: it serves its purpose of interfacing Python with HTTP perfectly well, and combined with a WSGI app server such as gunicorn or gevent, will serve your web application without any surprise.