Chapter 4. Plug-Ins

Table of Contents
Plug-In Basics
Plug-In Objects

Previously, several major parts of Pyrite have been described as "collection(s) of plug-ins". A plug-in collection is a set of modules, all of which are interchangeable because they share a common interface. Applications which use this common interface can use any plug-in from the collection, without knowing what each one actually does. Plug-ins may be added later, and the additional functionality they provide can be used by applications without additional programming.

In addition to whatever interface each collection of plug-ins has in common, all plug-ins, regardless of type, share some common behavior. This behavior is encapsulated in the Plugin class (which all plug-ins ultimately inherit from) in the Plugin module.

Plug-In Basics

A plug-in is an ordinary Python class. At run time, your application can use it by importing the appropriate module and creating an object of that class. This object is the "live" form of the plug-in, ready to be used by your application. All plug-in objects follow the interface described here, as well as the interface common to the collection they are in. Some plug-ins may also have extra behavior of their own; using that behavior may require special code in your application.

A collection of plug-ins is simply a Python package, named after the type of plug-ins it contains ("App" or "Conduit", for example). Each module in the package contains a single plug-in, which is also named after its type. The package itself defines a parent class for all of the plug-ins it contains, and that parent class is named after the package.

That is all probably a bit confusing, so perhaps an example will help. Pyrite's conduits are all plug-ins, and their type is "Conduit". Therefore, Pyrite contains a subpackage called Conduit, which holds all of the conduits. The Backup conduit is in its own module, Conduit.Backup, and that module defines a class called Conduit. Meanwhile, importing the Conduit package itself gives access to another class called Conduit, which is the base class for the Conduit classes in each individual conduit module.

All of those classes named the same might seem redundant, but there is a good reason for using the same name over and over again: it allows plug-in modules to be loaded without knowing in advance what is in them. If your application finds an unknown module in the Conduit package, for example, it knows it can import it and instantiate its Conduit class to do whatever it is that that plug-in is supposed to do. This way, when new plug-ins are added to Pyrite, your application will be able to use them without changes.

The Plugin module includes a function which can be used to locate plug-ins. The find_plugins function takes one argument, the name of a Python package to search. Each module in the package will be imported and searched for plug-in classes. The return from find_plugins is a tuples, each containing three items: the name of a module, the name of a plug-in class within that module, and a dictionary containing copies of the plug-in's informational attributes. The find_plugins function is not recursive.