The Swiss Army Knife For Python Web Developers
Back in 2003, Python had a number of web applications and frameworks but all of them had to reimplement a common interface to FastCGI, CGI and mod_python which were the preferred hosting environments. To solve the problem that all these implementations were incompatible, Phillip J. Eby wrote the WSGI specification which defines a very basic interface between web server and application, now the standard among all frameworks.
Django – a very common framework nowadays – was initially developed for mod_python and as a result of that, the WSGI layer is nearly invisible. Werkzeug, on the other hand, only gives you the tools you need to get a WSGI application running, but the process of implementing the actual dispatching method is up to you.
So you need to understand the very basic concept behind WSGI to get started. The following example is a very basic WSGI application:
from cgi import escape, parse_qs def application(environ, start_response): parameters = parse_qs(environ.get('QUERY_STRING', '')) name = parameters.get('name', ['World'])[0] start_response('200 OK', [('Content-Type', 'text/html')]) return [''' <title>Hello World</title> <p>Hello %s!</p> ''' % escape(name)]
A WSGI application is just a simple function or a callable class that accepts two arguments. The first one is the WSGI environment, which contains all the incoming data, while the second one is the start_response function which must be called to start the response. The return value of the application is then an iterable. Every iteration step sends a chunk of data to the client.
As you can see from this example, pure WSGI feels unnatural. Therefore, Werkzeug provides wrappers that wrap the request and response parts (environ and start_response). The request object is passed the environ and parses form data, the query string, HTTP headers and much more, while the response object is a WSGI application itself that you can instantiate and call on return. In the typical Werkzeug application, you will never see a trace of pure WSGI unless you are working on the dispatcher code.
All the details are in the documentation.