Python framework design
Lately I’ve found myself being baited into the same old debate over and over and over again, and I’m getting tired of making the same arguments each time. Usually it begins with someone lamenting how Django is anti-community or too inflexible or generally suffering from a raging case of NIH. From there it progresses into people proclaiming how TurboGears or (more often) Pylons is objectively “better” because of how they’re designed, and how it would be nice for Django to follow their lead.
Before I go any further, I’d like you to go watch Malcolm Gladwell’s 2004 TED talk. He’s going to talk about Pepsi and pickles and spaghetti sauce and mustard, but you should watch the whole thing because it has a relevant lesson for the Python web framework world:
There is no perfect Python web framework. There are only different Python web frameworks that suit different kinds of people.
Horizontal segmentation
Fundamentally, there are two ways you can go about building a Python web framework; I’m going to refer to them as “full-stack” and “glue”. In a nutshell:
- A full-stack framework’s primary goals are to provide a single set of components, covering the entire spectrum of things you’ll need to build web applications, and to ensure that those components work well with one another.
- A glue framework’s primary goals are to provide a set of adapters and interface code which can handle many different components in each part of the stack, and to ensure that those adapters work well with as many different combinations of components as possible.
The choice of methodology here will affect every aspect of the eventual framework, and no matter how hard the developers try, they will never be able to mask that from end users of the frameworks.
Django is a full-stack framework. Pylons and TurboGears are glue frameworks. These are fundamentally different approaches to building a framework, and they are both perfectly valid; the developers behind them have made a conscious choice about which approach they prefer, and put all their time and energy into fulfilling the goals of that approach. Web developers — the end users of web frameworks — also tend to have a preferred approach, and will naturally congregate around a framework which suits their preference.
There will always be framework developers who prefer the full-stack and there will always be framework developers who prefer glue. There will also always be web developers in each camp. Thus there will always be a market for both kinds of frameworks.
There is no perfect framework. There are only different frameworks that suit different kinds of people.
But they’re wrong!
Also, there will always be people in both camps who are utterly, steadfastly convinced that they are objectively right and the other group is objectively wrong. I expect that with time, full-stack versus glue will become one of the great holy wars of the Python web-development community (and it probably already has).
People in the full-stack camp will go on and on about how glue frameworks don’t really give you a clear roadmap; sure, they may have a default configuration which pre-selects a particular set of components, but that doesn’t really mean much and the tutorials and documentation will have to be fragmented according to which template engine or which ORM you use, and you’ll have to go hunt up all these other projects and read their manuals, and it’s just icky.
Those people will be wrong. A glue framework isn’t terribly hard to learn, and if you don’t want to research all the different options you can just go with the defaults, but the primary goal isn’t to give you just one set of components and say “here it is”. And the ability to cherry-pick exactly the right set of components for a particular project is incredibly powerful. It’s like the world’s most powerful Lego set; you’ve got blocks in all shapes and sizes, and you can build pretty much anything by combining them in just the right way.
People in the glue camp will go on and on about how full-stack frameworks are too inflexible; sure, you can drop in another ORM or another template engine, but then you’ll lose all the handy shortcuts and have to write more code. And because they tend to develop their own components, they’re not good community players — it’d be so much better if they’d just pull stuff off the shelf and contribute improvements back to other projects!
Those people will also be wrong. A full-stack framework isn’t inflexible, it’s just highly optimized for one set of components. It’s still easy to use others with it if you want to, but the primary goal isn’t to support every conceivable combination of components and say “go pick what you want”. And having a full set of tested components that Just Work out of the box is incredibly powerful. It’s like having the greatest toolbox ever; you’ve got hammers and wrenches and screwdrivers and drills right there, and you can build pretty much anything by using them in just the right way.
The fact that all of these people are wrong will not stop any of them from continuing to maul each other in public over whose philosophy is better.
Can’t we do both?
Unfortunately, I don’t think so. Taking one approach seems — though I could be proven wrong in time — to mean that so much of your time and effort will be spent on fulfilling the goals of that approach that you won’t be able to focus enough time and effort on the goals of the other, and if you try you’ll end up looking like you did a half-assed job of it; Jack of all trades will be master of none. A full-stack framework has to ensure that its components are of high quality and all work together; that’s a big enough job in itself without trying to make them work with any random thing somebody pulls off the shelf. And a glue framework has to ensure that its adapters and interfaces scrupulously follow various standards and specifications (like WSGI, which is not trivial to get right) and work with as many components as possible; that’s a big enough job in itself without spending development time on maintaining a particular arbitrarily-chosen set of components.
And again, no matter how hard developers try, a full-stack framework is always going to obviously be a full-stack framework, and a glue framework is always going to obviously be a glue framework. That fundamental choice of development methodology is going to affect every bit of code in the framework, and the particular strengths and weaknesses of each approach are always going to show through. So this division will probably exist for as long as there are Python web frameworks.
Can’t we all get along?
I’d like to think so, but it’s doubtful that it’ll happen. In an ideal world we’d all realize that the choice of methodology comes down to subjective preference, and that it’s a great thing to have the choice; Python web development wouldn’t be nearly as much fun if everyone were shackled into a single vision of the One True Framework (even if Guido were to Pronounce on this, which he really hasn’t — “as standard as PIL” isn’t much of a Pronouncement). And in that ideal world the folks who like full-stack frameworks would hack on them and use them, and the people who like glue frameworks would hack on them and use them, and we’d all come together and sing songs round the campfire about how much better off we are than those poor guys who are stuck with PHP.
But it’s not an ideal world, and so we’ll have the holy war and name-calling and FUD from both sides (I’ve certainly been guilty of it, and I’m only hesitantly trying to reform), and in the end that only thing we’ll agree on is the bit about PHP.
I’d love to be proved wrong, though. Anybody want to sing around the campfire and toast marshmallows with me after the web frameworks panel at PyCon?