As a designer, I think the Django template language hits a sweet spot between being flexibile/powerful and simple/consistent. It's clean, intuitive and flexible (between drilling into model classes within variables and chaining filters, you can go a long way without a lot of complexity). It mixes well with HTML, and it makes sense to front-end developers (like me) who are at ease in declarative markup languages, but completely out of their element in a real procedural language like Python. And with loose coupling at every turn, if Django's template language doesn't fit the bill, you've got all the other usual suspects at your disposal.

It will survive high traffic sites nicely as it can cache output as well as data in a very straightforward way.

The templating language ultimately compiles to Python bytecode (which is cached) - so if it doesn't behave as you expect, you can figure out why. Most of the tags are either for convenience or based on Python flow control. It also shows template tracebacks on errors (in addition to the regular Python traceback).

It will *use all available processors* if necessary; a place where threaded and asynchronous Python servers fall down, because it spawns multiple processes. The number of processes is, of course, configurable.

It has no built-in assumptions that the website(s) it hosts will be hosted on a single machine (so sessions can work cross machine).

It does have date formatting functions (and a tag in the templating languauge to deal with it).

It can be hooked up either by cgi, apache module, a few others, or can serve up HTTP all by itself.

It has been in production use for over 5 years and has shipped in commercial products to non-technical customers.

It has message catalogs if you ever need I18N.

It has URL rewriting options (one application translated URLs from Spanish and Portuguese to English and back).

It has built-in cookie handling and request/response header handling.

It has pluggable authentication methods, using either a basicauth like scheme or login/out pages with cookies, using flatfiles or whatever authentication backend you want.

It has a flexible CGI argument extraction tag (in the templating language) and function (usable from Python code) that can extract, validate and provide defaults for arguments passed in (via POST or GET).

The general philosophy of SkunkWeb is that you have stuff at your disposal, but it doesn't force anything on you, or into any particular development model.

You could write a whole site without templates, components, caching or message catalogs if you want, using just straight Python. It does offer a OR-mapper, called PyDO, but you don't have to use it. The general assumption is that the developer knows better than the server author what he needs.

Great to finally have you looking at all the work we in the web framework community have been doing !

I am the author of two of the framework components you have seen mentioned in this thread, Myghty (http://www.myghty.org) and SQLAlchemy (http://www.sqlalchemy.org). Both grew from my own need for very high performing and bug-free frameworks that fit in well with large-scale, highly customized applications, since thats the kind of work I do (in other languages). While I have made them as "Pythonic" as I can, at the same time the ultimate goal of these two projects is to "get the job done" without any letdowns...including good threading behavior, efficient memory and CPU usage, and enough modularity to fit into a wide range of situations.

The main critique of both is that they are too open-ended and still require a developer to figure out on his or her own how to lay out a new application. For me, I prefer such a design since each project is different, but fortunately higher-level frameworks such as Paste and Pylons have been stepping in to help fulfill people's desire to have it "all figured out" ahead of time.

While Myghty has been out for over a year and has hit 1.0, SQLAlchemy is not released yet but is already growing in popularity just from people checking out the latest SVN builds. Should you be interested, I would welcome any comments or questions you have either via email or the project mailing lists.

> I'd be interested if you have different initial opinions> about how an 'ideal' templating system would look (I'll> ignore the framework thing for the moment).I do also think that valid XML template files are the most logical path for generating XML/HTML output, and I do think that big chunks of logic in the template is the tool of the devil.

I do agree that the templating language should be as close as possible to the language being coded in

But I disagree with your consideration that "code and XML on the same line is evil", I think that the minor logic of the templating system should be built in the language, this is why I usually use Kid: the logic is added with very simple python expressions (one liners) into the HTML/XML tags via specific attributes. This means that you can for example use a generic Python iterator syntax for building structures from sequence, and use Python's helpers (such as the itertools stuff) yet you keep a very clean structure.

The only thing missing is that SciTE currently doesn't use Python highlighting on the Kid attributes, but the expressions are more than simple enough for this not to be an issue.

Let me start off with saying, Nevow scares me too, more and more every day, and as a twisted.web2 developer that is saying something. So what is this paradox? The simpler a Nevow application is the more complicated it looks, and the more complicated an application is (assuming you've yielded sufficiently to the "magic" of Nevow) becomes easier to write.

Now that I'm done with that, it should be noted that I do not take regular doses of the Nevow kool-aid, but I have had more than my share of the Twisted kool-aid. So here is my flat out no-nonsense opinion of web frameworks (not limited to python.)

There are no good Web Frameworks. Or atleast, there isn't a Web Framework that is good for everyone, so everyone will end up with their own Web Framework. Popularity of course has nothing to do with how GOOD the framework is, the metric for popularity is "how inept are the users compared to the developers." The metric for good varies greatly, from project to project, and It sounds like you just need something that doesn't get in the way very much, so there is no real reason not to just write your own, other than the fact that it'll undoubtly become immensly popular, and be touted as _THE_ Python Web Framework, and a lot of people will love you or and a lot more will hate you.

Form the web site:"Snakelets is a very simple-to-use Python web application server. It provides a threaded web server (you don't have to provide a web server such as Apache yourself), Ypages (Python HTML template language, similar to Java's JSPs) and Snakelets: code-centric page request handlers (similar to Java's Servlets). Snakelet's focus is to make the creation of dynamic web sites as quick and easy as possible. To get started it is enough to extract Snakelets somewhere, add a single directory that will contain your files, copy-paste-edit a small configuration file that describes your site, and you're set to add your own pages and images and other content!"

I think that Django actually fits all your requirements published at the end of article. Especially Magic Removal branch.

But the best part is it's not "going to be better in 3 month" --- it is good *now*. It is easy to use and resulting web applications scale without much efforts (proved by high traffic web sites). Did I mention it is fun to work with Django?

If I may suggest, you should take a look at Django's Magic Removal branch and see for yourself. Django has excellent documentation, new design decisions, and incompatible changes are thoroughly documented --- you'll have no trouble to get started.

If re-use is important, WSGI should definitely be on your mind. Almost every framework (if not all) now have WSGI support in some form or another. Usually this means they went to the minimum effort to support a WSGI call to their application, which in their usage scenarios is the most that will ever occur. They still assume you would never run anything other than their framework, and their frameworks applications.

First, the framework myself and James Gardner have created is called Pylons (http://pylons.groovie.org/), and is close to a 0.8 release. It is however used in at least one large production scenario now. Pylons is mainly Myghty, with a custom Resolver, full Paste and WSGI integration, and defaults that will likely work for the vast majority of people. As such, the code base is quite small, building on the reliability of Myghty's code.

Pylons fully exploits the power of WSGI, more so than any of the other "full-stack" frameworks out there. When Ian Bicking put out the very cool and extremely useful AJAX webapp debugger (http://blog.ianbicking.org/ajaxy-exception-catching.html), it was merely a few minutes of effort to slot it into place for use in Pylons.

People have said that being able to mix things, rather than writing it all yourself will lead to a 'frankenweb'. I think that's a load of crap, especially with a language like Python which makes it so trivial to use multiple libraries in a cohesive bundle. Pylons utilizes re-use as much as possible, and pulls it together in what I (of course) would consider a very compelling package.

For your list of things you want,1) Pylons uses Paste (thus flup). You can run your webapp stand-along, with Fast CGI, SCGI, or AJP. All with merely a toggle of one line in a config file.Pylons uses middleware to catch exceptions, in development mode you get the powerful AJAX debugger to interactively explore what went wrong. In Production mode it will first try and call your webapp's error handler for a nice message, if even that fails it falls back to a static 500 page and will of course email you the full traceback.

2) Pylons, as a super-set of Myghty, provides powerful templating capabilities and a component methodology that maximizes re-use of templates. It has a concept few other template engines have, called multiple component root inheritance, which lets you setup re-usable components. On top of that, every component has powerful caching abilities, so you can cache specific sections of a page, function responses, or the entire page. There's good reasons that Amazon.com, Salon.com and other major companies used Mason (Myghty started as a direct port)

3) Myghty handles all the cookies, sessions, etc. and has been very robust.

4) Form parsing is handled by Ian Bicking's excellent FormEncode package, that makes it easy to ensure the form is valid and coerce form values to the Python types you wanted. (TurboGears also uses this). Myghty handles basic query arg parsing.

5) For URL dispatch, the Routes (http://routes.groovie.org/) package I wrote is used. This allows for flexibility of URL's matching Django, though in what I'd consider a slightly easier way. It also provides powerful URL generation throughout the web application.

For ORM, Pylons doesn't strictly dictate what you should use. It provides some defaults to make it easy to get started with SQLObject if you choose, and we have a few people using the powerful SQLAlchemy package as well.

Since the entire setup utilizes WSGI and middleware, its very easy to get in and change how you want your webapp to function should any of the defaults not suit you. If you want regexp based matching, Myghty provides that and it can be used easily as well.

As I mentioned at the top how these things divide, thought I'd clarify how I'm hoping to avoid that. Anytime a package would stand alone, it does so. Pylons originally had a batch of helper functions ported from Rails. They're useful outside of Pylons though, so we spun them off into their own package where they're now being used by people using other frameworks. We utilize WSGI middleware, and if something would work well in that layer, we put it there so again, more people can use it. So far, the first thing I put into middleware was an OpenID authentication system, which joined Clark Evans middleware that lets you do Digest, Basic, and CAS authentication.

By using WSGI, you can easily plug-in middleware that takes care of a lot of hassles for you, and you aren't bound to a framework. The argument I hear for frameworks including tons of stuff (a toolbox, an admin interface, etc.) is that they're more usable if its all packaged together. Python is powerful enough that this doesn't need to be true.

Take the useful Catwalk program (small webapp for exploring your database through SQLObject), here's what Ian's proposed Routes based integration would look like:

Is that so bad? Imagine being able to go and put the Django admin interface under /admin/ with just one more line. Ah yes, people will scream, but then they won't have a reason to use your framework. Or perhaps they'll complain about the usability of it.

Anyways, Pylons is about maximizing re-use, this means you can use Pylons applications in other fully WSGI capable frameworks, in addition to using other WSGI apps in Pylons. It makes it easy to re-use applications, and create new ones. As frameworks more fully utilize WSGI, the differences between the frameworks will shrink and the useful things; an admin interface or model browser will be usable by anyone.

Whether you choose Aquarium, Django, Myghty, Pylons, Quixote, Snakelets, Skunkweb, eventually great things written in any of them will be as re-usable (I hope). Pylons mainly just does the somewhat daunting task of streamlining the configuration of these things into a usable system that attempts to maximize ones existing knowledge of Python with a configuration that makes it easy to change around middleware to suit your task.

Guido, you'll probably find that web.py ( http://webpy.org/ ) best suits your style. It's a single module (~1000 lines) that does WSGI and an extremely simple O-R mapping, with Cheetah for (non-XML) templates. If you don't like it, I can't imagine which of the other dozens of frameworks out there you *would* like. It's a bit rough around the edges (I suspect that its SQL quoting is broken for some database quoting styles, for example), and it's nothing particularly fancy, and it's about as far away as possible from something I or Jim Fulton would write, so it shouldn't be the least bit scary. :)

With respect to WSGI, its original purpose wasn't to do "middleware"; it was just a way to connect an application to arbitrary web servers, so the same application can be run under mod_python, CGI, FastCGI, SCGI, in a Twisted or other Python HTTP server, etc. That was and is the main point of WSGI. The existence of middleware is just a natural side-effect of having a way to connect an app to a server, in the same way that proxy servers and caches are a side-effect of having HTTP.

But just as it was a good idea to specify some of the allowed behaviors of proxies and caches in the HTTP spec, so too it was a good idea to address middleware in the WSGI spec. Basically, WSGI in itself is just a Python encoding of HTTP, nothing more.

Looking back at your post, I just realized you hadn't actually read the WSGI PEP, so I should probably mention that it it's basically a port of the Java servlet API, implemented in terms of simple callables and built-in data types rather than having an object/method interface.

Thus, any framework that's WSGI compliant support should give you the "server independence" you're looking for. You just need a WSGI "gateway" for the server, and find out how the framework exposes an "application" object to be run by the gateway.

Re Django's tempating language being "so rich and powerful that it might as well be PHP" -- having deployed sites using both, I find Django templating is much cleaner than pure PHP templating and easier to *keep* clean. As a web developer I don't *want* a pythonic template language. Templating is about integration with unpythonic (X)HTML.

IMO the biggest factor (besides inexperience) that leads people to "produce lousy websites quickly" is template systems that tempt one to include business logic.

The template power in Django (and other similar systems, e.g. Smarty for PHP) is all focused on presentation. It's better than raw Python (or PHP) for presentational things, and worse (if capable at all) for business logic things. As it should be!

WSGI does have a few things it adds to HTTP, which I find very important (even if they can seem trivial)...

"Proxy" done right. The original request information isn't lost. Not all information is passed along the same channels as the original request, so for instance you can add authentication information without having to use signatures or other restrictions to be able to trust the information. The original client isn't lost, nor is the host name. One of the most important to me is that the context of the request path is maintained -- the path general contains two parts "how we got this far" (SCRIPT_NAME) and "what is left to process" (PATH_INFO).

Much of this is due to WSGI's heritage using CGI conventions. CGI is a great protocol, even if its process model doesn't scale.

Anyway, since proxying works well (aka delegating the request or dispatching the request), you can use WSGI to compose small bits of code into full sites. (These little proxying details make this work, and are the basis of Paste, which is why I get all in a tizzy when frameworks don't work well with these specified WSGI conventions.)

Another important feature is that you can extend WSGI beyond CGI, putting new information or callbacks inside the environment. These can be arbitrary Python objects. This follows Python's general portability philosophy, IMHO -- you are given full access to the environment (including information previously added during the request handling), but you can also restrict yourself to the "standard" portions of the environment. This way you get the advantages of insulation, without being forced to depend on the container to insulate you from absolutely everything.

One good non-feature of WSGI is that the container for this information is not smart, it's just a dumb dictionary (and restricted to be exactly a dictionary by the spec). I think this is part of what makes WSGI a protocol and not an API. Just like HTTP headers aren't an object, they are just bytes sent over a channel. The objects inside the container can be anything, but an application is also free to ignore all those objects, and anyone who adds something to the request environment needs to take into account the potential that they will be ignored.

I think these all facilitate decoupled pieces, testability, and reliable interactions better than typical framework stacks that use request objects and object publishers and whatnot. Those systems turn into APIs, not protocols, and have hidden and sometimes quite deep assumptions about how things should work. WSGI is HTTP plus a little something, and as such is just right for building a foundation. Using a good foundation doesn't mean limiting yourself, it means you have more time to spend on the more interesting aspects of application design. (Of course, using a bad foundation does often mean you are limiting yourself -- sometimes people confuse the badness of A framework they have encountered with the badness of ALL frameworks.)