Writing Plugins¶
Plugins can exist inside your existing packages or in special namespace packages, which exist only to house plugins.
The only requirement is that any package containing plugins be
designated a “namespace package”, which is currently performed
in Python via the pkgutil.extend_path
utility, seen below.
This allows the namespace to be provided in multiple places on
the python sys.path
, where import
looks, and all the
contents will be combined.
Use a namespace package
This allows multiple packages installed on your system to share this name, so they may come from different installed projects and all combine to provide a larger set of plugins.
Example¶
# logfilter/__init__.py
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
# logfilter/hide_extra.py
from logfilter import Skip
def filter(log_entry):
level = log_entry.split(':', 1)[0]
if level != 'EXTRA':
return log_entry
else:
raise Skip()
Using the plugin¶
In our log tool, we might load all the modules in the logfilter
namespace, and then use them all to process each entry in our logs.
We don’t need to know all the filters ahead of time, and other packages
can be installed on a user’s system providing additional modules
in the namespace, which we never even knew about.
from straight.plugin import load
class Skip(Exception):
pass
plugins = load('logfilter')
def filter_entry(log_entry):
for plugin in plugins:
try:
log_entry = plugin.filter(log_entry)
except Skip:
pass
return log_entry
Distributing Plugins¶
If you are writing plugins inside your own project to use, they’ll be distributed like any other modules in your package. There is no extra work to do here.
However, if you want to release and distribute plugins on their own, you’ll need to tell your setup.py about your namespace package.
setup(
# ...
namespace_packages = ['logfilter.plugins']
)
This will make sure when your plugins are installed alongside the original project, both are importable, even though they came from their own distributions.
You can read more about this at the Distribute documentation on namespace packages.