Plug-in Predicate


#1

Goal

To enable a dynamic evaluation of whether plug-in should be included or not.

Sometimes, a plug-in is part of a group of plug-in, but can only evaluate under certain conditions.

Motivation

When developing a plug-in that was dependent on external binaries - i.e. ffmpeg to extract a .gif file from a .mov, in this case Windows-only - I contemplated how to best approach the situation. Here were the options I could see.

  • Including the plug-in, but causing it to fail because it can’t find the dependency. Not very productive as the artist won’t be able to do anything about it.
  • Including it, and having it silently pass isn’t any good either, because an artist is led to believe that it succeeded that the file was created.

Ideally, the plug-in should not have appeared to begin with.

Implementation

A callable is assigned to an attribute of the plug-in.

import pyblish.api

def if_exists():
  return os.path.exists("c:\bin\ffmpeg.exe")

class ExtractGif(pyblish.api.Extractor):
  predicate = if_exist
  def process(self, instance):
    ...

Returning True means the plug-in is included, False it’s skipped.

About Context sensitive plugins

Since this has to happen before processing begins, it can’t have any knowledge of context or instance etc. Which means that unfortunately, it almost fits your propsal, @mkolar, but not quite.

That is, this will not work.

import pyblish.api

class ValidateFtrackVersion(pyblish.api.Extractor):
  predicate = lambda context: context.has_data("ftrackData")
  def process(self, instance):
    ...

Discussion

I’m sceptical whether this feature is useful outside of this exact use case, so I’m posting it here in an effort to keep it in mind and for you to keep in it mind too when you encounter problems it might help solve.

Usecases

  • Binary support, as in main example
  • OS support, may only apply on certain platforms, such as Windows
  • User support, may only apply to certain (groups of) users, such as power users or bots.
  • Relational support, may depend on the existence of other plug-ins. In this case, predicate may have access to plugins which is the collection of available plug-ins such that it can query against it.

#2

Even though as you say, it is not exactly what I was asking for, I’d say it’s close enough to be used in the same situation. I could just think about it a bit differently and instead of looking for ftrackData, I’ll check if ftrack_connect binary is running. The next best thing to what I was asking for.

I’d say it’ll show it’s usefulness as more and more plugins start being developed, from which I’d assume a fair few might have external depencencies…


#3

Added a few usecases.