[Web-SIG] Entry points and import maps (was Re: Scarecrow deployment config

Phillip J. Eby pje at telecommunity.com
Mon Jul 25 19:35:11 CEST 2005


At 12:59 PM 7/25/2005 -0400, Chris McDonough wrote:
>   In order to define a pipeline, we use a ".ini"-format configuration

Ultimately I think the spec will need a formal description of what that 
means exactly, including such issues as a PEP 263-style "encoding" 
specifier, and the precise format of values.  But I'm fine with adding all 
that myself, since I'm going to have to specify it well enough to create a 
parser anyway.

With respect to the format, I'm actually leaning towards either treating 
the settings as Python assignment statements (syntactically speaking) or 
restricting the values to being single-token Python literals (i.e., 
numbers, strings, or True/False/None, but not tuples, lists, or other 
expressions).

Interestingly enough, I think you could actually define the entire format 
in terms of standard Python-language tokens, it's just the higher-level 
syntax that differs from Python's.  Although actually using the "tokenize" 
module to scan it would mean that all lines' content would need to start 
exactly at the left margin, with no indentation.  Probably not a big deal, 
though.

The syntax would probably be something like:

   pipeline    ::= section*
   section     ::= heading assignment*
   heading     ::= '[' qname trailer ']' NEWLINE
   assignment  ::= NAME '=' value NEWLINE

   qname       ::= NAME ('.' NAME) *
   trailer     ::= "from" requirement | "options"
   value       ::= NUMBER | STRING | "True" | "False" | "None"
   requirement ::= NAME versionlist?
   versionlist ::= versionspec (',' versionspec)*
   versionspec ::= relop STRING
   relop       ::= "<" | "<=" | "==" | "!=" | ">=" | ">"

The versions would have to be strings in order to avoid problems parsing 
e.g '2.1a4' as a number.  And if we were going to allow structures like 
tuples or lists or dictionaries, then we'd need to expand on 'value' a 
little bit, but not as much as if we allowed arbitrary expressions.


>   file conventionally named '<something>.wsgi'.  This file may
>   optionally be marked as executable and associated with a simple UNIX
>   interpreter via a leading hash-bang line to allow servers which
>   employ stdin and stdout streams (ala CGI) to run the pipeline
>   directly without any intermediation.

For that matter, while doing development and testing, the interpreter could 
be something like "#!invoke peak launch wsgifile", to launch the app in a 
web browser from a localhost http server.  (Assuming I added a "wsgifile" 
command to PEAK, of course.)


>   Factories which construct middleware must return something which is
>   a WSGI "callable" by implementing the following API::
>
>      def factory(next_app, [**kw]):
>          """ next_app is the next application in the WSGI pipeline,
>          **kw is optional, and accepts the key-value pairs
>          that are used in the section as a dictionary, used
>          for configuration """

Note that you can also just list the parameter names you take, or no 
parameter names at all.  I don't want to imply that you *have* to use kw, 
because it's fairly easy to envision simple middleware components that only 
take two or three parameters, or maybe even just one (e.g., their config 
file name).


>   Factories which construct middleware must return something which is
>   a WSGI "callable" by implementing the following API::

You probably meant "application" or "terminal application" here.  (Or 
whatever term we end up with for an application that isn't middleware.


>   A deployment descriptor can also be parsed from within Python.  An
>   importable configurator which resides in 'wsgiref' exposes a
>   function that accepts a single argument, "configure"::
>
>     >>> from wsgiref.runwsgi import parse_deployment
>     >>> appchain = parse_deployment('myapplication.wsgi')
>
>   'appchain' will be an object representing the fully configured
>   "pipeline".  'parse_deployment' is guaranteed to return something
>   that implements the WSGI "callable" API described in PEP 333.

Or raise SyntaxError for a malformed descriptor file, or ImportError if an 
application import failed or an entry point couldn't be found, or 
DistributionNotFound if a needed egg couldn't be found, or VersionConflict 
if it needs a conflicting version.

Or really it could raise anything if one of the factories failed, come to 
think of it.



More information about the Web-SIG mailing list