DI opens up doors for added functionality not before possible.
def process(self, context, instance): # the function is given the current Context, and Instance
The above mimics the current behaviour, with slightly less typing and options for excluding both
Instance from the function signature where needed.
But it also means the ability to inject custom functionality.
def process(self, instance, time, user): print("%s was published @ %s by %s" % instance.data("name"), time(), user)
user are injected on-demand, providing additional functionality to the plug-in. In this case, a callable function
time which returns the current time, and a static value
Furthermore, services can be registered by developers.
import pyblish.api pyblish.api.register_service( "time", lambda: datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ"))
In the above, a custom service
time is registered and made available to plug-ins, providing a pre-formatted version the current time, such that every plug-in uses the same formatting and needn’t concern themselves with maintaining any updates to it.
Services vs. Data
Where does the line go between what is data and what is a service?
If data, added via e.g.
Context.set_data(key, value), represents data shared amongst plug-ins, services may represent shared functionality.
Though there is technically nothing preventing you from storing callables as data…
import time context.set_data("time", lambda: time.time)
Just as there is technically nothing preventing you from providing constants as a service.
It may make sense from a maintenance point of view to make the data/function separation. This way, data can be kept constant which simplifies archiving and visualisation, like passing the entire thing to a database, whereas functionality can be kept free of constants.
Is additional services something we need, or does it add complexity? When a plug-in requests a service that isn’t available, when do we throw an error?
def process(self, not_exist): pass
- Thrown during discovery
- Thrown during processing, e.g. in the GUI
- Silently skipped; rely on external tool for checking correctness.
# Checking correctness $ pyblish check select_something.py Plug-in is valid.