[Web-SIG] Possible specs

Ian Bicking ianb at colorstudy.com
Fri Nov 10 22:45:13 CET 2006


Luke Arno wrote:
> On 11/10/06, Ian Bicking <ianb at colorstudy.com> wrote:
>> I brainstormed some ideas for wsgiorg specs and added them to the spec
>> page, and also copied here.  I offer them here to see if there's
>> particular specifications that seem interesting, and might be worth
>> pursuing sooner than other ones.
> 
> Wow. This is a tidal wave. :)
> 
> I haven't had a chance to read on the wiki but I will
> comment on the short descriptions.

This is a straight copy of the wiki, I haven't written anything up on 
any of these beyond what you see here.


>>      * Ben Bangert suggested a simple session standard, focused solely
>> on the session ID (persistence handled elsewhere). This is fairly modest
>> but still useful.
>>
> 
> Maybe. Pick a key. wsgiorg.session_id?
> 
> Does anyone use more than one session at a
> time? I don't, but it seems wise to ask.

Since it is backend/persistence-neutral, it's up the app to figure out 
how to consume it; there could be multiple sessions for a given ID, or 
not.  This just gives you a stable ID.  It should probably be created on 
demand, as if you don't care about the session you shouldn't be 
generating a session ID (and cookie to go with).


>>      * Maybe a full session interface built on the session ID standard.
> 
> Maybe.
> 
> I favor the dict interface. Must be lazy-loadable.
> 
> wsgiorg.session_loader = callable that takes environ
> wsgiorg.session = cached dict like object
> 
> We need a method to invalidate (on the dict-like?)

This is more-or-less what paste.session does.  It might be a little too 
minimal, though.  For instance, there's no way to distinguish between 
read-only access and read-write access; hence no way to do locking or 
serialization (without adding some real concurrency problems), and no 
way to avoid rewriting the session on every request in case some 
contents have been changed.


>>      * Debugging mode is something that can be used in all sorts of
>> places; to increase verbosity, annotate output pages, displaying errors
>> in the browser, etc. Having a single key for turning on debugging mode
>> would allow its consumption in lots of places. Not as strict as
>> authenticating.
> 
> Maybe.
> 
> wsgiorg.log_level? If you change the log level,
> do you want this to effect the whole stack or
> just your own stuff?

I often do a bunch of stuff in debugging mode that is more aggressive 
than just log_level, and shouldn't be done at all in normal mode.  So a 
real on-off switch for debugging is useful.


>>      * Some systems prefer that unexpected exceptions bubble up, like
>> test frameworks. A key could define this case (modelled on
>> paste.throw_errors) and thus disable exception catchers.
> 
> -1 I don't need it. Too abstract.
> 
> Usually, you just have one error handling
> middleware on the outside of the rest, no?

Sometimes there's multiple pieces of middleware.  For instance, I might 
have one on the outside, with another one in a subapplication (which is 
independently deployable, so needs some kind of wrapper).  Also it is 
needed to avoid catching errors when running tests, where you want the 
exception to go up all the way to your test runner (which might have a 
debugger or special traceback formatter).


>>      * Logging is a tricky situation. The logging module allows for
>> statically setting up logging systems, then configuring them at startup.
>> This often isn't the best way to set up logging. Putting a
>> logging.Logger instance right in the environment might be better. This
>> requires some design and usage before setting on one spec.
> 
> Maybe a lazy logger loader that takes the level
> as an argument? Seems a little silly.

I'm not really sure here, myself.  I know people ask for it, and 
sometimes I'm pretty sure I want something like this, but I don't feel 
very solid about what best practice in logging is.  I couldn't write 
this one.


>>      * Thread-local values are a common technique in web frameworks,
>> allowing global objects or functions to return request-specific
>> information. This pattern could be codified into one core system, using
>> some feedback from existing systems (which have their advantages and 
>> flaws).
> 
> -1 but I don't like using thread locals for such things.
>    Save the magic for things that need it. :)

Thread local stuff can be a pain; I often curse it.  I think it can be 
okay with the right patterns.


>>      * Configuration takes fairly common forms, usually a dict of some
>> sort. It could be put somewhere standard.
> 
> -1 Different components may need different configs.
>    I have seen class instances and modules, not
>    just dictionaries.
> 
>>      * Maybe Paste Deploy's entry points could be standardized. (Paste
>> Deploy itself only consumes those entry points; other consumers are
>> possible and packages implementing those entry points don't introduce
>> any dependency on Paste Deploy)
> 
> -1 We would have to conform to your ABC
>    to make use of this, right?

No, not at all, there's no base class (not even an optional base class).

The interface for apps is basically:

   def app_factory(global_conf, **app_conf):
       return wsgi app

It's pretty neutral, with some notable details:

- global_conf is basically inherited configuration.  It may or may not 
apply to this application.  The application factory can ignore it or not 
as it sees fit.  app_conf is definitely intended for this application; 
you can do more strict checking on it, make sure there's no extra values 
or that certain required values are present, etc.

- all values can be strings, and strings should be handled specially. 
That is, if you expect an integer and you get a string, you should 
coerce it to an integer.  If you expect a list and you get a string, you 
should probably split the string in some fashion, or just turn it into a 
one-item list.  If you expect a boolean and you get a string, you should 
convert it intelligently (not based on the truth/falsiness of the string 
itself).


That's it.  Middleware and servers have similar interfaces.  The server 
interface is a little under-powered (it just serves a WSGI application 
forever); it could be extended some, or left unspecified for now. 
Middleware takes as a first argument the application being wrapped.  Oh, 
and composites, which are a little harder -- they take as a first 
argument an object that can load more WSGI apps.  That's used for 
dispatchers that can direct to multiple subapplications.  That's more 
tightly coupled with Paste Deploy's app naming conventions, and it might 
be better to put explicit app loading into the configuration format and 
pass them in as keyword arguments to the dispatching app.


>>      * A way to extend wsgiref.validate to add more validation, for all
>> these new specs. (Probably this is an implementation, not a spec)
> 
> That makes sense if our standards are that involved.
> I don't see standardizable clarity on much that is so
> complex.

WSGI isn't all that complex, but validation is very helpful when people 
get it wrong.  It should be useful for any of these specs as well.  It 
also makes the spec much more explicitly clear, because computers check 
things more reliably than humans ;)


>>      * Anchors for doing recursive calls, similar to paste.recursive.
>> (paste.recursive is kind of an old module that is more complicated than
>> it needs to be)
> 
> Is that really such a common pattern? It is clever
> but I have yet to find a case for it. Maybe I am just
> overlooking something. What do you usually use
> that for?

Originally it was to support internal redirects and inclusion (which 
were part of the Webware API).  Now I find it useful for doing internal 
subrequests when using web-based APIs.


>>      * A place to put a database transaction manager
> 
> -1 Way too specific.

There'd have to be a database transaction manager standard first, anyway.


>>      * More user information than just REMOTE_USER; like 
>> wsgiorg.user_info?
> 
> User objects are like request objects and I don't see
> what we gain from making them fight for a key.
> 
> Could this actually decrease real interop?

This shouldn't be a real user object, more likely a dictionary, just 
like the WSGI request is a dictionary (environ) and not an object. 
Objects are hard to standardize ;)


> I am worried that things are getting a little inventive
> here. This is how things get heavy. Lets try to stick
> to codifying those things that have a clear common
> right way. Most of these don't meet that, in my
> opinion. Pursuing many of these will lead to endless
> arguments as they are just unproven which means
> we should just let the diversity simmer for a while.

Most of them are taken from keys already in Paste (or in a couple cases, 
that I wish were in Paste but have been lazy about adding).

> Sessions *might* be doable.

Possibly; but sessions don't personally interest me a whole lot.  It 
wouldn't be my first choice to write up, but if someone else writes it 
up then great ;)

-- 
Ian Bicking | ianb at colorstudy.com | http://blog.ianbicking.org


More information about the Web-SIG mailing list