[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