Python: Werkzeug

I just finished the Werkzeug tutorial, and it looks pretty good.
Werkzeug started as simple collection of various utilities for WSGI applications and has become one of the most advanced WSGI utility modules. It includes a powerful debugger, full featured request and response objects, HTTP utilities to handle entity tags, cache control headers, HTTP dates, cookie handling, file uploads, a powerful URL routing system and a bunch of community contributed addon modules.

Werkzeug is unicode aware and doesn't enforce a specific template engine, database adapter or anything else. It doesn't even enforce a specific way of handling requests and leaves all that up to the developer.

Werkzeug is most useful for end user applications which should work on as many server environments as possible (such as blogs, wikis, bulletin boards, etc.).
Having coded applications in Aquarium, Django, Pylons, Ruby on Rails, Zope, Plone, etc., I've been fascinated by the idea of an anti-framework. A framework establishes the flow of the application and calls your code at certain points. That's the opposite of a library. A library lets you call its code whenever and however you want. Werkzeug is a collection of libraries.

There's a bunch of glue that's required to tie all the libraries together in order to build a Web application. Werkzeug gives you some code as an example, but basically, you're on your own. Hence, it's not for everyone, but it's great if you're someone like me who hates when things get in his way.

Anyway, it looks simple and clean. The tutorial was very good. Here are some other random comments:

The tutorial used Jinja which is a templating system based on Django templates. Personally, I don't like Django templates. (That's not an insult. Templating engines are a matter of taste.) Fortunately, there's absolutely nothing in Werkzeug tying you to any templating system or ORM. It doesn't even make it any easier to stick to Jinja.

Werkzeug has view functions like Django instead of controller classes with methods like Pylons. I personally prefer the Pylons approach since I can do a lot of stuff before and after the method call. On the other hand, I guess that just means I'd have to make better use of decorators. It's interesting because the tutorial itself said "A callable class has huge advantages over a function" when it was talking about the WSGI entry point. Of course, you're free to not use the built in URL dispatcher, in which case you could do whatever you want ;)

Like Pylons, parameters parsed from the URL path are passed in as arguments to the functions. Unlike Turbo Gears, form parameters are not passed in as function arguments. I don't personally like that approach anyway.

I love the way it's just a bunch of libraries and you have to write all the glue code. They show you examples for all the glue code. I can definitely see where I'd be less likely to get irritated by frustrating restrictions.

It supports the Pylons goal of having multiple instances of the same application in the same Python interpreter.

Rather than putting all your URL mappings in one place, they also show you how to declare your mappings on a per-view basis using function decorators.

They made it easy to write management scripts that operate outside a Web context, yet understand how to work with the app.

In the tutorial, they hard coded the dburi in the top-level module manage.py. Especially in the past, I use to get frustrated while using Pylons because I would need the dburi and it would be locked away in a .ini file. In order to support multiple instances of the same application in the same process, you need a procedure to get access to the correct .ini file, and in strange situations like management scripts, etc., it was hard to get access to this stuff. In Werkzeug, you're on your own to figure out how you want to manage your configuration data. That's fine with me--I've always disliked .ini files anyway ;)

It looks like you return redirects as instances. In a lot of systems like Pylons and Aquarium, when you do a redirect, it actually raises an exception to halt processing.

It does look like it's easy to create a hierarchy of views in a hierarchy of Python modules. That's good.

Well, I haven't written an application with it, but it looks nice ;)

Comments

The docs are great.

The source code isn't 100% PEP 8, but it looks way nicer than most Python source that I end up working on.
i had much the same impressions about werkzeug. i'd really like to start using it, but i have a few questions:

* werkzeug uses greenlets* to do thread-local variables. i understand very little about the requirements when serving under mod_python/mod_wsgi, but it somehow scares me that i have to use a less-than universally accepted C extension that doesn't compile under windows for a central system component. what are the alternatives here?

*http://codespeak.net/py/dist/greenlet.html

* the documentation of werkzeug is well written, but there is not very much of it. googling for independent writeups does not yield much either.

* where is the community? these days i dump libraries when i discover their community talks live in mailman archives (argh) or is served by sourceforge (belch). those are web 0.4 and web 1.0 applications and they suck big time. there is a pocoo group on google** but it only has 33 members as of now (including me) and 14 discussion topics.

**http://groups.google.com/group/pocoo-libs?lnk=sg

maybe someone wants to comment on these perceived issues. i would very much like to have a minimalist approach to setting up web applications with python, and werkzeug does look nice.
Max M said…
Your posting is timely. I have similar ideas in this posting
pjz said…
You should also check out web.py, the original anti-framework at webpy.org.
Armin Ronacher said…
Just a few words as I'm in a hurry. Werkzeug doesn't even require you to use view functions. I think there is an example in the sourcetree that uses controller classes like pylons.

And greenlet is not a requirement :)

We're trying to stick as closely to PEP8 as it makes sense for us :) There are a few things where we disagree with PEP8, namely indentation of continued statements but I think that's such a minor violation I can defend ^^


Regards,
Armin
> werkzeug uses greenlets* to do thread-local variables.

Greenlets are cool. However, as the other poster confirms, I'm sure they probably support greenlets but do not require greenlets.

> the documentation of werkzeug is well written, but there is not very much of it.

You think? I read most of http://werkzeug.pocoo.org/documentation/ yesterday. It's orders of magnitude better than most of the code I have to use. I can't think of anything else I wish they would have documented. Maybe it's because it all seems very familiar to me.

> where is the community?

That's a good point. Personally, I care a bit more about good code than I do about community. If I just wanted community, I'd go use PHP ;)

However, you have a point. Let's remember, that it's still young, and it isn't for the faint of heart.

For me, Werkzeug has *way* more community than the alternative, which is coding an anti-framework myself. I'm just glad someone else had the same idea I did, and did a good job executing on it. Looking at the code, I trust the competence of the author.
> Just a few words as I'm in a hurry. Werkzeug doesn't even require you to use view functions. I think there is an example in the sourcetree that uses controller classes like pylons.

Yeah, I guessed that. That's why I said, "Of course, you're free to not use the built in URL dispatcher, in which case you could do whatever you want ;)"

> We're trying to stick as closely to PEP8 as it makes sense for us :) There are a few things where we disagree with PEP8, namely indentation of continued statements but I think that's such a minor violation I can defend ^^

The problem with shying away from PEP 8 is that we all hate different things about PEP 8. Sticking with PEP 8 very closely means that we all get pissed off equally slightly ;) Anyway, it's close enough that it doesn't drive me crazy. Thanks for that ;)
regarding coding styles, i believe you have to go far beyond pep8 styles. i violate a lot of those coding standards all of the time and i believe my code is (potentially) readable (in places). much more important than the question whether to write `f(a=42)` or `f( a = 42 )` (i always do the latter) is to use sane variable names, sane procedures, and sane interfaces. you can't put that inside a style guide, i guess.

regarding the relative paucity of documentation and community, that was meant as an encouragement to point out and start such things. i am afraid that a tool that has its central communication going on within an IRC channel is not easy to catch up with for a lot of guys. IRC is just too transient, too hard to recapitulate, and too invisible for search engines.
> regarding coding styles, i believe you have to go far beyond pep8 styles.

Agreed. PEP 8 is just a good start that takes care of the stupid things. "The Practice of Programming" by Kernigan and Pike cover a lot of the other things.

> i am afraid that a tool that has its central communication going on within an IRC channel is not easy to catch up with for a lot of guys.

I agree completely. I can't keep up with IRC.