[Distutils] Standardizing distribution of "plugins" for extensible
apps
Phillip J. Eby
pje at telecommunity.com
Wed Dec 8 04:40:11 CET 2004
Many applications need or want to be able to support extension via dynamic
installation of "plugin" code, such as Zope Products, Chandler Parcels, and
WSGI servers' "application" objects. Frequently, these plugins may require
access to other plugins or to libraries of other Python code. Currently,
application platforms must create their own binary formats to address their
specific requirements, but these formats are of course specific to the
platform and not portable, so it's not possible to package a third-party
module just once, and deploy it in any Python application platform.
Although each platform may have its own additional requirements for the
contents of such a "plugin", the minimum basis for such plugins is that
they include Python modules and other files, and import and export selected
modules. Although the standard distutils pattern is to use a platform's
own packaging system, this really only makes sense if you are dealing with
Python as a language, and not as an application platform. Platform
packaging doesn't make sense for applications that are end-user
programmable, because even if the core application can be installed in one
location, each instance of use of that application (e.g. per user on a
multi-user system) may have its own plugins installed.
Therefore, I would like to propose the creation of:
* a binary package format optimized for "plugin" use (probably just a
specific .zip layout)
* a distutils "bdist" command to package a set of modules in this format
* A PEP 302 importer that supports running of code directly from plugin
distributions, and which can be configured to install or extract C
extension modules. (This will serve as a base for platform developers to
create their platform-specific plugin registries, installation mechanisms,
etc., although there will be opportunity for standardization/code sharing
at this level, too.)
* additions to setup() metadata to support declaration of:
* modules required/provided, with version information
* platform metadata for C extensions contained in the plugin distribution
* ability to specify metadata files to be included in the distribution,
that are specific to the target application platform (e.g. Zope config
files, Chandler parcel schemas, WSGI deployment configuration, etc.)
(This is actually only "level 1" of the standardization that I'd like to
do; levels 2 and 3 would address runtime issues like startup/shutdown of
plugins, automatic dependency resolution, isolation between plugins, and
mediated service discovery and service management across plugins. However,
these other levels are distinct deliverables that don't necessarily relate
to the distutils, except insofar as those levels may influence requirements
for the first level. Also, it's important to note that even without those
higher levels of standardization, the availability of a "plug and play"
distribution format should be beneficial to the Python community, in making
it easier for applications to bundle arbitrary libraries. Indeed, tools
like py2exe and py2app might grow the ability to automatically "link"
bundles needed by an application, and there will likely be many other
spin-off uses of this technology once it's available.)
My main idea is to expand the existing PKG-INFO format, adding some
formally-defined fields for system processing, that are supplied by the
setup script or in additional files. The additional metadata should be
syntactically validated (and semantically, to the extent possible), and the
distutils should not knowingly produce a plugin package with invalid
execution metadata. The specific kinds of metadata needed (that I know of
currently) are:
* Static imports (module names and specification of compatible versions)
* Dynamic imports (wildcard masks)
* Exports (module names and versions)
* Platform requirements for included extension modules
* Other platform requirements
* Entry point for dynamic integration (technically a level 2 feature, but
it'd be nice to reserve the header and define its syntax)
* Update URL (for obtaining the "latest" version of the plugin)
There are several issues that would have to be hammered out,
here. Versioning, for example, both in the sense of formats and
qualifiers, and in the sense of versioning a module/package versus
versioning a distribution. Gathering information about imports is also
tricky. Tools like py2exe try to gather some of this information
automatically, but that info doesn't include version requirements. (It may
be that we can get by without version requirements, taking the default
state to mean, "any version will do.")
Platform specs are another dicey issue, since we're talking about trying to
define binary compatibility here. This includes the issue that it might be
necessary to include shared libraries other than the C extensions
themselves. (For example, like the wxWidgets libraries that ship with
wxPython.)
While researching a deployment strategy for WSGI, I discovered the OSGi
specifications for Java, which address all of these issues and more. Where
OSGi's solutions are directly usable, I'd like to apply them, rather than
re-inventing wheels... not to mention axles, brakes, and
transmissions! However, their syntax for these things is often weird and
verbose, and could probably use some "Pythonizing".
Anyway, I would see the deliverables here as being a PEP documenting the
format, and a prototype implementation in setuptools (for current Python
versions), that would then migrate to an official implementation in the
distutils for Python 2.5. I'd like to find out "who's with me" at this
stage in having an interest in any aspect of this project, especially if
you have requirements or issues I haven't thought of. Thanks!
More information about the Distutils-SIG
mailing list