[Web-SIG] wsgiconfig design

Ian Bicking ianb at colorstudy.com
Sat Jul 7 05:41:49 CEST 2007


Every so often I get in this cleanup/redux mood where I feel a need to 
revisit things I've done before in an attempt to Do Them Right.

We've discussed Paste Deploy here before, and I'm thinking about Redoing 
It Right.  I thought I'd share some thoughts on the design:

I still am quite happy with the entry points from Paste Deploy, and plan 
to keep them, except perhaps paste.composite_factory which I might 
replace with another way of creating composites that takes a dictionary 
as an argument (a dictionary of section names to WSGI applications).  I 
will probably rename them, but also support the old Paste Deploy names. 
  The composite entry point isn't too big a deal, because it's mostly 
just Paste that implements those kinds of components -- normal people 
just write applications and middleware that dispatches to a single 
application.

There will be a few levels of pluggability.  The first is the loader 
itself, which will default to the wsgiconfig loader itself.  This is 
only applicable to file-based configuration.  When you load up the 
application from a file, it will search for a #! line that specifies a 
loader, which is the name of a distribution or module.  It will search 
the distribution for some entry point (wsgiconfig.config_loader:main), 
and that entry point is a callable like:

   def config_loader(filename, options, object_type):
       return wsgi_application

options is a flat dictionary of options that are passed in, which the 
config loader can use at its discretion.  A common way to use it would 
be for variable substitution.  This allows for things like "paster serve 
config.ini var1=value var2=value", for ad hoc customization.  It returns 
a single application.  (This does mean that a feature from Paste Deploy 
is lost, where you could do "paster serve config.ini#section_name" to 
load a specific application from several defined in a file -- but you 
are less likely to get dead sections or confusing config file factorings).

object_type is the kind of object we want to get out.  Here I'll only 
specify 'wsgi.application'.  'wsgi.server' will probably also be 
implemented, but that's all I plan for now.  'wsgi.appserver' or 
something might be possible, for the process manager that runs an entire 
application.

 From there, you can do whatever.  But importantly, wsgiconfig defines a 
loader which I hope people will like.

Unlike Paste Deploy, section names will not be arbitrary.  A section 
name has a prefix and name.  The prefix, as in Paste Deploy, says what 
you are describing.  The default prefix is "app:"; you can also give 
"middleware:".  Prefixes not recognized will be ignored.  A possible 
prefix might be "logging:" for logging, which if I don't implement it 
will be initially ignored (but someone else could handle it).  Similarly 
the server as with Paste Deploy can be defined with "server:".  For now 
all we're concerned with is applications, middleware, and composites.

The applications and middleware are grouped together using the names. 
That is, if you have an application "/" and a middleware "middleware:/", 
then the middleware wraps that application.  Middleware sections can 
have trailing numbers to indicate ordering and keep section names 
unique.  Thus "middleware:/ 1", "middleware:/ 2", etc.  Negative numbers 
and floats are allowed.  Anything but trailing numbers is considered 
part of the name; thus names can have parameters or other structure.

All the applications in the server are put in a single dictionary, and 
that is based to the composer.  The composer by default is urlmap (which 
also includes optional host-based dispatch).  You can specify another 
composer with a global option "composer = (specifier)"

The sections still have a "use" option, which indicates what implements 
the option.  It will take "egg:", and dotted module/object names, and 
module names may have trailing entry point specifiers (if the object 
doesn't implement the "preferred" interface for that kind of output). 
You cannot use "config:" anymore, instead that will be handled by the 
config file format.

The config files will use INITools, which is similar to ConfigParser but 
a bit nicer.  It will include improved string substitution, including 
similar constructs to what zc.buildout has.  While still keeping 
applications firmly separated from the config files, I'm planning on 
paying close attention to call signatures and exceptions to give good 
error messages.  E.g., if you raise something like TypeError("... got an 
unexpected keyword argument 'X'") I'll figure out where the keyword 
arguments came from and improve the text of that error message.  Not 
perfect, but should be passable, and better than what Paste Deploy does now.

That's pretty much it.  I won't write any server stuff for now, except 
maybe try to get "paster serve" to work with these files.  I'll try to 
include a simple framework for applications that want to have their own 
command-line runners, so that if you have some neat little application 
you can just tell people to install it and run "serve-applicationname" 
or whatever you call your script.

Anyway, those are my thoughts.  I'm going to give it a go this weekend.


-- 
Ian Bicking : ianb at colorstudy.com : http://blog.ianbicking.org
             : Write code, do good : http://topp.openplans.org/careers


More information about the Web-SIG mailing list