Categorizing Packages: Clarifying Terms
Some of the friction which comes up on the zope-dev list, apparently due to different goals, might in fact be due to some confusion in the terms we use to talk about our goals, and about the shared software we manage toward those goals. In the interests of reducing the friction, I would like to sketch out how I am using those terms.
Created by tseaver. Last modified 2009-03-16 17:02:48.
Second, I'm sure that the examples listed under each section below are woefully incomplete: I'm mostly picking the packages I know well, and don't mean to be making value judgements about any I haven't listed.
A reusable Python module or package which supplies functionality to
other components. The normal mode for using a library is via a Python
A component or package which provides services on one side (like a library), and defines slots / plug-in interfaces on the other which are intended to be filled with objects supplying application-specific implementations or policies. The key concept of a framework is that it is both rigid and configurable: it defines some parts of its functionality as "unchanging", (e.g., the order in which it processes inputs and calls into its plugins), with other points where plugins supply the remainder of the functionality.
Note that some frameworks are designed to be usable (as libraries) even in the absence of explicitly configured plugins: in these cases, the framework supplies an "overridable default" implementation of the plugin API.
Plugins are components / packages which implement the API defined by a given framework.
Having frameworks and plugins requires some way to spell which plugins get configured into the slots provided by the framework. This kind of configuration is distinct from the kind which spells out declarative policy choices (e.g., port numbers, database connection strings, etc.), but this distinction can get muddied by the way various frameworks "spell" their configuration.
For example: in Zope-based applications, while the
machinery is configured through calls to
registerUtility, etc., most people think of that configuration as being
done via ZCML, as implemented by the XML dialect of
That dialect itself is both a mini-application (the interpreter which
maps XML elements onto the corresponding
register* actions) and it
is a framework: it is designed to be extended by plugins defining new
A "stack" is a set of software components, divided into separate "layers". Each layer functions consumes APIs / services defined in the layers beneath it, and provides APIs to the layers above it. Stacks are often illustrated as "layer cakes," although there is often more than one "underlying" layer used by a single layer.
Managing a stack involves keeping the layering "clean": there should be no dependency cycles or uses of undocumented APIs between the layers. The "higher" layers tend to be more like "applications", including specific policies, while the lower layers tend to be more like "libraries."
The term "platform" indicates a software configuration which forms the basis for building applications. Platorms are often organized as "stacks", at least internally.
This term, originated by the TurboGears folks, originally meant to signal that TurboGears was designed as a loosely-collaborating arrangement of "best-of-breed" frameworks (e.g., one for templating, one for request-response processing, one for RDBMS connectivity, etc.): it was meant to be used to differentiate TurboGears from "monolithic" platforms such as Django and Zope. We should probably avoid using it to refer to our own platforms.
The term, "pluggable application", refers to a kind of platform which is organized as a web application, designed to "pluggable" in the sense of a framework.
Applications are normally deployed as websites in our world (they have URLs). They are normally built on a given "web framework ("stack" / "platform"), according to one a couple of patterns:
Because managing TTW glue code is hard, we often migrate it down to filesystem-based "productcs", somewhat muddying the distinction.
These frameworks tend to trade away the notion of running multiple applications, or instances of applications, within a given process, gaining instead some conceptual clarity: the application is in the genrated code, which uses the services supplied by the framework in library-like fashion. Any "configuration" of the framework tends to be done in Python code.
Products are applications which are noremally installed and run in their "out-of-the box" form, with minimal configuration and without requiring any customization / glue code.
The "acid test" for determining whether a bit of code is a "product" or a "platform" is whether anybody who is not the developer deploys it in production without customizing it through code. It seems interesting that none of the Python-based web applications widely-installed in this fashion use one of the frameworks we have been discussing: I'm not sure what that means, unless it is that using one of the "frameworks" is a predictor of "one-off" applications.