jump to navigation

Python Guy Gets WSGI February 25, 2008

Posted by PythonGuy in Advanced Python, Python, Web Technologies, WSGI.
add a comment

Thanks to patient explanation by an article written by James Gardner, this old web programmer gets the point of WSGI.

Let me say, WSGI rocks my world. It’s one of those things that says, “There’s a whole fresh new world of opportunity out there, and you’re invited.”

Before WSGI, the web world was strange and convoluted. You had to either edit a slew of Apache config files (which, while better than the predecessor, was still a major pain). Or you had to build your own web server (which, while better than before, was still painful.)

Apache was nice because you could use something like mod_perl or mod_python and actually get in there and change the way the request was handled. It was bad because the request stack was extremely complicated, and the config files didn’t make any sense to the new Apache hacker.

Hand-coded web servers were not nice because each one was different, and most were not that flexible. In the end, you had a new hand-coded web server that was incompatible with the last one. Hence, we have seen Zope and Django succeed.

Ruby-on-rails merely opened the world’s eyes to what a good set of options can give you in the world of hand-coded web servers. It is, in a way, the apex of that kind of technology.

However, WSGI is a whole new experience. It is a combination of the best parts of hand-coded web servers, with the best parts of the Apache request stack. Now, before you start pulling your hair out because it sounds so complicated (you mean I have to wrestle with config files and hack on web servers?), realize that WSGI is the simplest solution one could ever possible come up with.

It has, in its interface, three parts.

First, WSGI handlers are functions. (That’s not rocket science. Apache request handlers were functions. RoR controllers are, ultimately, functions.)

Second, the function takes exactly two parameters. The parameters are “environ” and “start_response”. “environ” is a dictionary, a map. It can list whatever you want. Some things are expected, but they don’t have to be. In different parts of the stack, people will expect different things. “environ” is by far the most complicated part of WSGI, and it is only complicated because different people will need and provide different keys. “start_response”, on the other hand, is a function. It takes a response code (“200 OK”) and a list of HTTP headers.

Third, the WSGI handler must return something iterable. This is going to be the body of the HTTP response.

Pretty simple, huh?

Now, let’s consider what you can do with this.

Obviously, you can create your hand-coded web application. It will simply be a WSGI handler. It will call “start_response” with the appropriate parameters, and then send back the body of the response. Plug this in to any default web server that supports WSGI, and viola! You have a working web application where you can replace the underlying technology. One solution fits all.

Or, you can create a WSGI server. This would take incoming HTTP requests and translate them into WSGI requests. It would take the response and send it out as an HTTP response. Pretty simple, huh? Well, the possibilities are endless. In fact, there are already WSGI handlers for pretty much anything you can imagine, as well as CGI-WSGI translators if you just want to work from the CGI environment. Your options are endless—and they are all interchangeable. One solution fits all.

Or, you can write WSGI middleware. What is middleware? It is what you can put between the web server (which handles the HTTP request and sends an HTTP response) and the web application (which does something interesting with the request.) For instance, if you wanted to do HTTP AUTH, you could write a WSGI middleware app that takes the incoming WSGI request, checks to see if it has been authenticated, and returns an auth request if not. Otherwise, it just passes it along, adding who was authenticated to the environ. You could write an error handler. It would catch exceptions and show a very neatly formatted web page, one that could even allow people to play with the program state. The possibilities are endless. And best of all, middleware is universally useful. One solution fits all.

In short, thanks to WSGI, the world of web application development just got a lot easier, and your options just got a lot bigger. You can literally remove one component of the request stack and replace it with another. And the interface is quite simple.

Now, once you understand this, and once you actually get around to building a web application with six or seven different pieces, you are going to find that the hardest part is configuration. Getting all the pieces configured to behave just the way you want is going to be a bear, because each one is configured in its own way. Never fear, that’s what Python Paste is for. Python Paste takes a config file (in .ini format) and configures each component on the stack. You just have to write the code that puts it together, informing each part that there is a configuration for it from the paste infrastructure.

Python Paste also handles some fairly common tasks, tasks that many different components will want to do. For instance, given a WSGI request, try to build the URL that generated that request. These util functions are actually quite simple. Take a look at them if you get a chance. But they are useful for anyone who is doing any work anywhere on the WSGI stack.

So Python Paste makes it really easy to put together your WSGI app and configure it.

With Python Paste and WSGI, your possibilities have grown significantly, and the overhead has dropped just as much. Now, more than ever, it is going to be possible to build web apps in an afternoon.