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

Phillip J. Eby pje at telecommunity.com
Tue Jul 26 00:27:17 CEST 2005


At 10:54 PM 7/25/2005 +0100, James Gardner wrote:
>The new way is like this (correct me if I'm wrong)
>
>The modules have egg_info files like this respectively defining the
>"entry points":
>
>wsgiFilters.egg:
>
>[wsgi.middleware]
>gzipper = GZip:GZip

Almost; this one should be:

    [wsgi.middleware]
    gzipper = GZip:GZip [GZip]

So that using gzipper doesn't require specifying "extras" in the pipeline 
descriptor.  See below.


>helloworld.egg:
>
>[wsgi.middleware]
>cs = helloworld:CaseChanger
>
>[wsgi.app]
>myApp = helloworld:HelloWorld
>
>
>We would then write an "import map" (below) based on the "deployment
>descriptors" in the .eggs used to describe the "entry points" into the
>eggs.

Actually, the new thing you write is the deployment descriptor or pipeline 
descriptor.  The "import map" is the thing you put in the eggs' setup.py to 
list the entry points offered by the eggs.



>The order the "pipeline" would be built is the same as in the
>Python example eg middleware first then application.
>
>[gzipper from wsgiFilters[GZip] == 1.4.3]
>[cs from helloworld  >= 0.2 ]
>newCase = 'lower'
>[myApp from helloworld >= 0.2]

You wouldn't need the [GZip] part if it were declared with the entry point, 
as I showed above.


>It is loaded using an as yet unwritten modules which uses a factory
>returning a middleware pipeline equivalent to what would be produced in
>the Python example (is this very last bit correct?)

Yes.  The order in the file is the order in which the items are invoked by 
the controlling server.


>Doing things this new way has the following advantages:
>* We have specified explicitly in the setup.py of the eggs that the
>middleware and applications we are importing are actually middleware and
>an application
>* It is simpler for a non-technical user.
>* There are lots of other applications for the ideas being discussed
>
>It has the following disadvantages:
>* We are limited as to what we can use as variable names. Existing
>middleware would need customising to only accept basic parameters.

This depends a lot on the details of the .ini-like format, which are still 
up in the air.


>* We require all WSGI coders to use the egg format.

Not so; you can use [GZip.GZip] as a section header in order to do just a 
plain ol' import.


>* Users can't customise the middleware in the configuration file (eg by
>creating a derived class etc and you lose flexibility).

No, but all they have to do is create a Python file and refer to it, and 
they are thereby encouraged to separate code from configuration.  :)


>* If we use a Python file we can directly import and manipulate the
>pipeline (I guess you can do this anyway once your factory has returned
>the pipeline)

Yep.


>Both methods are the same in that
>* We have specified the order of the pipeline and the middleware and
>applications involved
>* Auto-downloading and installation of middleware and applications based
>on version requirements is possible (thanks to PJE's eggs)

One difference here: the .ini format is parseable to determine what eggs 
are needed without executing arbitrary code.


>Other ideas:
>
>Is it really necessary to be able to give an entry point a name?

Yes.  Entry points are a generic setuptools mechanism now, and they have 
names.  However, this doesn't mean they all have to be exported by an egg's 
import map.


>If not
>because we know what we want to import anyway, we can combine the
>deployment descriptor into the import map:
>
>[GZip:GZip from wsgiFilters[GZip] == 1.4.3]

We could perhaps still allow that format; the format is still being 
discussed.  However, this would just be a function of the .wsgi file, and 
doesn't affect the concept of "entry points".  It's just naming a factory 
directly instead of accessing it via an entry point.


>We can then simplify the deployment descriptor like this:
>
>[wsgi.middleware]
>GZip:GZip

If you don't care about the entry point, you can just not declare one.  But 
you can't opt out of naming them.


>Why do you need to assign names to entry points?

Because other things that use entry points need names.  For example, 
setuptools searches a "distutils.commands" entry point group to find 
commands that extend the normal setup commands.  It certainly doesn't know 
in advance what commands the eggs are going to provide.

The question you should be asking is, "Why do we have to use entry points 
to specify factories?", and the answer is, "we don't".  :)


>Although writing a middleware chain is dead easy for a Python
>programmer, it isn't for the end user and if you compare the end user
>files from this example I know which one I'd rather explain to someone.

Yep.  Ian gets the credit for further simplifying my "sequence of 
[factory.name] sections" proposal by coming up with the idea of having 
named entry points declared in an egg.  I then took the entry points idea 
to its logical conclusion, even refactoring setuptools to use them for its 
own extensibility.


>So although this deployment format seemed at first like overkill, I'm
>now very much in favour. I was personally considering YAML for doing my
>own configuration using a factory but frankly the new format is much
>cleaner and you don't need all the power of YAML anyway! Count me in!

There's one other advantage: this format will hopefully become as 
successful as WSGI itself in adoption by servers and 
applications.  Hopefully within a year or so, *the* normal way to deploy a 
Python web app will be using a .wsgi file.

Beyond that, we can hopefully begin to see "Python" rather than "framework 
X" as being what people write their web apps with.



More information about the Web-SIG mailing list