On Mon, Mar 18, 2013 at 1:08 PM, Simon Yarde <simonya...@me.com> wrote: > If I understand correctly, one of the goals of WSGI Lite is to keep the > environ out of middleware and app code to prevent modification.
No. You are *allowed* to modify the environment, that's part of the WSGI spec. What you *can't* do is trust that nobody *else* will modify it. Which is why you can't use the environment to communicate with middleware, only objects passed along in the environment. For example, if middleware does env['foobar']=[], it's okay for a called app to modify that list, as long as the middleware saves a reference to it and doesn't try to pull it out of the environ later, e.g.: def middleware(...): my_list = [] env['foobar'] = my_list app(env) if my_list: ....blah But you must NEVER do this: def middleware(...): app(env) if env['foobar']: ....blah Even if you were the one who put 'foobar' into the env. WSGI Lite's argument binding protocol addresses a different problem, which is that after you call app(env), it's too late for you to get anything you need out of the original environment, because app() was within its rights to clear env or change its contents in any way. (It also makes it easier to create application-specific or framework-specific calling conventions, like if you want your controller functions to be called with a user and a cart as parameters, as long as you can define how to get a user and a cart from a WSGI environment.) > Could this particular goal be achieved by the middleware creating references > to the environ values it depends upon prior to calling the app? Yes, you can use that to communicate up the middleware chain, as I showed above. But the problem WSGI Lite bindings solve is not really related to that. > Regarding my own scenario.. > > I have been working on my own small framework, partly as a learning exercise > and partly out of frustrations with existing frameworks. > > I return 3-tuple responses as per WSGI Lite, and my middleware generates > minimal error responses rather than raise exceptions, e.g. ('404 Not Found', > ['Content-Length': '0'], []). > > I use status-handler decorators to customise these basic responses; these > operate at the level of the individual apps or across a dispatch app to > provide global response customising. > > I use a 'final' flag in the environ to indicate to any outer status-handlers > that the response is intended as definitive, i.e. > environ[my_framework.status_handler.final] = True, and should not be altered > again. Don't do that. You need to put a callback in the environ, or a mutable object that you keep a reference to. The environ dictionary itself is strictly passed down to child handlers, and it's perfectly valid for a piece of middleware to clear the environ entirely before returning to its caller. So you can't use raw values in the environ to communicate up the chain, only down. Of course, even if you use another method to communicate this "final" flag, that doesn't necessarily mean that your "final" flag makes any sense in a WSGI context. It might actually be that you need to use a custom header like 'X-MyFramework-Final', that your boundary middleware strips. That is probably actually the right way to do it in WSGI, because there's no guarantee a "final" response returned from one app is actually going to be the same response as one returned from another piece of middleware wrapping that. So really, since this is information about the response, you should put it in a response header. (Perhaps in a future version of WSGI Lite, I could extend the response protocol to support stripping out some special response headers at the protocol boundary between WSGI 1 and WSGI Lite.) > Under WSGI Lite, would I still be able to add flags to the environ? Or is > there some other way I should be signalling to outer middleware? Callbacks and mutable objects are the only way authorized by the WSGI spec to communicate from an app to an outer server or middleware (aside from response headers, bodies, or special response iterators), and WSGI Lite doesn't change this. It just makes it easier to work with values obtained from the environment. _______________________________________________ Web-SIG mailing list Web-SIG@python.org Web SIG: http://www.python.org/sigs/web-sig Unsubscribe: http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com