start_response and write
wsgistraw is a tiny Python library that simplifies coding WSGI applications and middleware by removing
write from signatures of functions.
We could remove
start_responseand the writer that it implies. This would lead to a signature like:
def app(environ): return '200 OK', [('Content-type', 'text/plain')], ['Hello world']
That is, return a three-tuple of
(status, headers, app_iter). It’s relatively simple to provide adapters to and from this signature to the WSGI 1.0 signature.
This is what exactly wsgistraw does. It provides several decorators for your simplified functions, classes or factories to bring them to conformity with the WSGI 1.0 spec.
wsgistraw is licensed under the LGPL license.
Download the latest release from wsgistraw‘s Cheese Shop Page.
Get the source code from the wsgistraw‘s Subversion repository.
A bugfix release. Fixed a bug in
app_proxy with extending an iterable with the results of
app_proxy, fixed a couple of inconsistencies with PEP 333.
+) Added public
_app_proxy, thanks to Ian Bicking)
-) If an app uses
response.close()after iterating over it
-) If an app hasn’t invoked
start_resposnse()before returning then
app_proxyforces this invocation by calling
This is a “hello world” WSGI application slightly simplified by using wsgistraw:
import wsgistraw @wsgistraw.app def hello_world(environ): response = ["<h1>Hello World!</h1>"] return "200 OK", [("Content-Type", "text/html")], response
Another app that returns the
environ dictionary is:
class environ_debugger(object): @wsgistraw.app def __call__(environ): response = ("%s: %s\n" % (k, v) for k, v in environ.items()) return "200 OK", [("Content-Type", "text/plain")], response
write are much more annoying in a WSGI middleware. wsgistraw makes your middleware code cleaner. This is an example of a “lowercase” middleware factory:
@wsgistraw.mid_factory def lowercase(app): def mid(environ): status, headers, response = app(environ) return status, headers, (s.lower() for s in response) return mid
The same example coded as a class is:
class _lowercase(object): def __init__(self, app): self.app = app def __call__(self, environ): status, headers, response = self.app(environ) return status, headers, (s.lower() for s in response) lowercase = wsgistraw.mid_factory(_lowercase)
Yet another way of writing such a middleware is using an
class lowercase(object): def __init__(self, app): self.app = app def __call__(self, environ, start_response): proxy = wsgistraw.app_proxy(self.app) status, headers, response = proxy(environ) start_response(status, headers) return (s.lower() for s in response)
The wsgistraw library provides the following decorators to allow writing WSGI applications and middleware using the simplified signature mentioned above:
app— decorates WSGI application callables (both functions and methods)
mid_factory— decorates WSGI middleware factories, i. e. callables that accept a WSGI application as their first positional parameter and return a middleware callable
Also wsgistraw provides the following classes:
app_proxy— replaces a WSGI application callable on the caller side, returns the application with the simplified signature
As all calls to
write are buffered by a
mid_factory decorator instance, a WSGI application that:
- Is called by a (possibly nested) middleware with
- Uses such
writecalls to transmit its response and
- Transmits a very large amount of data or an infinite data stream
will suffer a significant performance penalty and require a huge amount of memory. So don’t use
mid_factory in such a setting.
There are no known drawbacks except those mentioned above.