[Web-SIG] WSGI2: write callable?

PJ Eby pje at telecommunity.com
Sat Sep 27 00:31:33 CEST 2014


On Fri, Sep 26, 2014 at 5:02 PM, Robert Collins
<robertc at robertcollins.net> wrote:
> But perhaps it would be nicer to say:
> iterator of headers_dict_or_body_bytes
> With the first item yielded having to be headers (or error thrown),and
> the last item yielded may be a dict to emit trailers.
>
> So:
> def app(environ):
>     yield {':status': '200'}
>     yield b'hello world'
>     yield {'Foo': 'Bar'}
>
> is an entirely valid, if trivial, app.
>
> What do you think?

I think this would make it harder to write middleware, actually, and
for the same reason that I dislike folding status into the headers.
It's a case of "flat is better than nested", I think, in both cases.
That is, if the status is always required, it's easier to validate its
presence in a 3-tuple than nested inside another data structure.  As
far as trailers go, I'm not sure what those are used for or how they'd
be used in practice, but my initial thought is that they should be
attached to the response body, analagous to how FileWrapper works.

The other alternative is to use a dict as the response object
(analagous to environ as the request object), with named keys for
status, headers, trailers, body, etc.  It would then be extensible to
handle things like the "Associated content" concept.

In this way, middleware that is simply passing things through
unchanged can do so, while middleware that is creating a new response
can discard the old object.


>> wsgi_lite has a couple of other protocol extensions, namely the
>> 'wsgi_lite.closing' environment key, flagging callables' supported
>> WSGI version (for transparent interop), and the argument binding
>> protocol, but for the most part these are orthogonal to the calling
>> schema.  I would suggest, however, that the calling protocol be
>> flagged in some way to allow easier interop.
>
> We're bumping the WSGI version, will that serve as a sufficient flag?

I mean, flagged on the app end.  For example, wsgi_lite marks apps
that support wsgi_lite with a  true-valued `__wsgi_lite__` attribute.
In this way, a container invoking the app knows it can be called with
just an environ (and no start_response).

So, I'm saying that an app callable would opt in to this new WSGI
version, so that servers and middleware don't need to grow new APIs
for registering apps -- they can auto-detect.  Also, having
auto-detection means you can write a decorator (e.g. in wsgiref), to
wrap and convert WSGI 1 apps to WSGI 2, without needing to know if
you're passing something already wrapped.  It means that a WSGI 2
server or middleware can just wrap whatever apps it sees, and get back
a WSGI 2 app, whether the thing it got was WSGI 1 or WSGI 2.


> The closing thing is nice - its basically unittest.TestCase.addCleanup
> for WSGI, allowing apps to not have to write a deep nested finally.
> Lets start a new thread about the design for that specifically. You
> note that exception management isn't defined yet - perhaps we can
> tackle that as a group?

Sure.


More information about the Web-SIG mailing list