This brings up a very good point.
I’ve taken for granted that kits are to be distributed as Python packages or modules. Some benefits include:
- Familiarity, we work with them all the time
- Standardisation, it’s proven to work and many deployment methods build upon it, like
pip
- Room for expansion; it covers both single modules and large interdependent hierarchies of packages.
For example, in the case you mention of a kit being just a directory of plug-ins.
└── pyblish-deadline
├── select_instance.py
├── validate_instance.py
└── extract_instance.py
Some of the plug-ins may eventually benefit from shared utilities.
└── pyblish-deadline
├── select_instance.py
├── validate_instance.py
├── extract_instance.py
└── _util.py
And suddenly, plug-ins and non-plug-ins become mixed. Not to mention the potential for README
files or additional configuration data.
└── pyblish-deadline
├── select_instance.py
├── validate_instance.py
├── extract_instance.py
├── README.md
├── config.yaml
└── _util.py
A Python package also enables the use of kits for things other than plug-ins, for scripting or extended behaviour.
import pyblish_deadline
pyblish_deadline.submit("custom_things")
Or for configuration.
import pyblish_deadline
pyblish_deadline.path_template = "{project}/published/renders/{pass}"
Installation
At one point or another, a user will need to “expose” plug-ins to the pipeline. A Python distribution simplifies this as well.
In the case of chucking plug-ins into any directory:
import pyblish.api
path = "/some/directory/pyblish-deadline"
pyblish.api.register_plugin_path(path)
But contrast that with this.
import pyblish_deadline
pyblish_deadline.register_plugins()
No absolute paths, and the flexibility rides on an already maintained PYTHONPATH
.
# Implementation
import os
import sys
import pyblish.api
def register_plugins():
"""Expose Deadline plugins to Pyblish"""
module_path = sys.modules[__name__].__file__
package_path = os.path.dirname(module_path)
plugin_path = os.path.join(package_path, 'plugins')
pyblish.api.register_plugin_path(plugin_path)
log.info("Registered %s" % plugin_path)
Examples
The Napoleon kit is a good example of how plug-ins could be bundled with reusable functionality.
import napoleon
napoleon.register_plugins()
Magenta is another good example of a larger collection of shared utilities.
For distributions as simple as a single plug-in, something like this is equally well suited.
└── magic-selector
├── select_magic_instances.py
├── setup.py
└── README.md