Publish Plugins

Publish plugins are hooks that handle processing of collected publish items. After all items have been collected, the Publisher attempts to match the items with the appropriate publish plugins. All matched plugins show up as child tasks within the publish item hierarchy.

With tk-multi-publish2 v2.0.0 and higher, each plugin can define a custom UI that allows users to make changes to the publish settings prior to publishing. See the methods and properties section below for details on how to implement a custom publish plugin UI.

Like the collectors, you can override one of the shipped publish plugins or write your own to meet the particular needs of your studio.


Publish Plugin API

class tk_multi_publish2.base_hooks.PublishPlugin(parent)[source]

Bases: tank.hook.Hook

This class defines the required interface for a publish plugin. Publish plugins are responsible for operating on items collected by the collector plugin. Publish plugins define which items they will operate on as well as the execution logic for each phase of the publish process.

icon

The path to an icon on disk that is representative of this plugin (str).

The icon will be displayed on the left side of the task driven by this plugin, as shown in the image below.

_images/task_icon.png

Icons can be stored within the same bundle as the plugin itself and referenced relative to the disk location of the plugin, accessible via sgtk.Hook.disk_location().

Example implementation:

@property
def icon(self):

    return os.path.join(
        self.disk_location,
        "icons",
        "publish.png"
    )

Note

Publish plugins drive the tasks that operate on publish items. It can be helpful to think of items as “things” and tasks as the “actions” that operate on those “things”. A publish icon that represents some type of action can help artists understand the distinction between items and tasks in the interface.

name

The general name for this plugin (str).

This value is not generally used for display. Instances of the plugin are defined within the app’s configuration and those instance names are what is shown in the interface for the tasks.

description

Verbose, multi-line description of what the plugin does (str).

The string can contain html for formatting for display in the UI (any html tags supported by Qt’s rich text engine).

The description is displayed via the plugin’s default create_settings_widget() implementation, as shown in the image below:

_images/plugin_description.png

A simple implementation example:

@property
def description(self):

    return '''
    Creates a publish in Shotgun.

    A <b>Publish</b> entry will be created in Shotgun which will
    include a reference to the file's path on disk. Other users will
    be able to access the published file via the
    <b><a href='%s'>Loader</a></b> so long as they have access to
    the file's location on disk.
    ''' % (loader_url,)
settings

A dict defining the configuration interface for this plugin.

The dictionary can include any number of settings required by the plugin, and takes the form:

{
    <setting_name>: {
        "type": <type>,
        "default": <default>,
        "description": <description>
    },
    <setting_name>: {
        "type": <type>,
        "default": <default>,
        "description": <description>
    },
    ...
}

The keys in the dictionary represent the names of the settings. The values are a dictionary comprised of 3 additional key/value pairs.

  • type: The type of the setting. This should correspond to one of the data types that toolkit accepts for app and engine settings such as hook, template, string, etc.
  • default: The default value for the settings. This can be None.
  • description: A description of the setting as a string.

Example implementation:

@property
def settings(self):
    return {
        "Publish Template": {
            "type": "template",
            "default": None,
            "description": "The output path template for this plugin."
        },
        "Resolution": {
            "type": "str",
            "default": "1920x1080"
            "description": "The output resolution to export before publishing."
        }
    }

The settings are exposed via the settings key as the plugins are configured via the publish_plugins setting in the app’s configuration. Example:

publish_plugins:
    - name: Export and Publish
      hook: "{config}/export_and_publish.py"
      settings:
          Publish Template: export_template
          Resolution: 2048x1556

The values configured for the plugin will be supplied via settings parameter in the accept(), validate(), publish(), and finalize() methods.

The values also drive the custom UI defined by the plugin whick allows artists to manipulate the settings at runtime. See the create_settings_widget(), set_ui_settings(), and get_ui_settings() for additional information.

Note

See the hooks defined in the publisher app’s hooks/ folder for additional example implementations.

item_filters

A list of item type wildcard str objects that this plugin is interested in.

As items are collected by the collector hook, they are given an item type string (see create_item()). The strings provided by this property will be compared to each collected item’s type.

Only items with types matching entries in this list will be considered by the accept() method. As such, this method makes it possible to quickly identify which items the plugin may be interested in. Any sophisticated acceptance logic is deferred to the accept() method.

Strings can contain glob patters such as *, for example ["maya.*", "file.maya"].

accept(settings, item)[source]

This method is called by the publisher to see if the plugin accepts the supplied item for processing.

Only items matching the filters defined via the item_filters property will be presented to this method.

A publish task will be generated for each item accepted here.

This method returns a dict of the following form:

{
    "accepted": <bool>,
    "enabled": <bool>,
    "visible": <bool>,
    "checked": <bool>,
}

The keys correspond to the acceptance state of the supplied item. Not all keys are required. The keys are defined as follows:

  • accepted: Indicates if the plugin is interested in this value at all. If False, no task will be created for this plugin. Required.
  • enabled: If True, the created task will be enabled in the UI, otherwise it will be disabled (no interaction allowed). Optional, True by default.
  • visible: If True, the created task will be visible in the UI, otherwise it will be hidden. Optional, True by default.
  • checked: If True, the created task will be checked in the UI, otherwise it will be unchecked. Optional, True by default.

In addition to the item, the configured settings for this plugin are supplied. The information provided by each of these arguments can be used to decide whether to accept the item.

For example, the item’s properties dict may house meta data about the item, populated during collection. This data can be used to inform the acceptance logic.

Example implementation:

def accept(self, settings, item):

    accept = True

    # get the path for the item as set during collection
    path = item.properties["path"]

    # ensure the file is not too big
    size_in_bytes = os.stat(path).st_stize
    if size_in_bytes > math.pow(10, 9): # 1 GB
        self.logger.warning("File is too big (> 1 GB)!")
        accept = False

    return {"accepted": accepted}
Parameters:
  • settings (dict) – The keys are strings, matching the keys returned in the settings property. The values are Setting instances.
  • item – The Item instance to process for acceptance.
Returns:

dictionary with boolean keys accepted, required and enabled

validate(settings, item)[source]

Validates the given item, ensuring it is ok to publish.

Returns a boolean to indicate whether the item is ready to publish. Returning True will indicate that the item is ready to publish. If False is returned, the publisher will disallow publishing of the item.

An exception can also be raised to indicate validation failed. When an exception is raised, the error message will be displayed as a tooltip on the task as well as in the logging view of the publisher.

Simple implementation example for a Maya session item validation:

def validate(self, settings, item):

     path = cmds.file(query=True, sn=True)

     # ensure the file has been saved
     if not path:
        raise Exception("The Maya session has not been saved.")

     return True
Parameters:
  • settings (dict) – The keys are strings, matching the keys returned in the settings property. The values are Setting instances.
  • item – The Item instance to validate.
Returns:

True if item is valid, False otherwise.

publish(settings, item)[source]

Executes the publish logic for the given item and settings.

Any raised exceptions will indicate that the publish pass has failed and the publisher will stop execution.

Simple implementation example for a Maya session item publish:

def publish(self, settings, item):

    path = item.properties["path"]

    # ensure the session is saved
    cmds.file(rename=path)
    cmds.file(save=True, force=True)

    # the hook's parent is the publisher
    publisher = self.parent

    # get the publish info
    publish_version = publisher.util.get_version_number(path)
    publish_name = publisher.util.get_publish_name(path)

    # register the publish and pack the publish info into the item's
    # properties dict
    item.properties["sg_publish_data"] = sgtk.util.register_publish(
        "tk": publisher.sgtk,
        "context": item.context,
        "comment": item.description,
        "path": path,
        "name": publish_name,
        "version_number": publish_version,
        "thumbnail_path": item.get_thumbnail_as_path(),
        "published_file_type": "Maya Scene",
        "dependency_paths": self._maya_get_session_depenencies()
    )
Parameters:
  • settings (dict) – The keys are strings, matching the keys returned in the settings property. The values are Setting instances.
  • item – The Item instance to validate.
finalize(settings, item)[source]

Execute the finalize logic for the given item and settings.

This method can be used to do any type of cleanup or reporting after publishing is complete.

Any raised exceptions will indicate that the finalize pass has failed and the publisher will stop execution.

Simple implementation example for a Maya session item finalization:

def finalize(self, settings, item):

    path = item.properties["path"]

    # get the next version of the path
    next_version_path = publisher.util.get_next_version_path(path)

    # save to the next version path
    cmds.file(rename=next_version_path)
    cmds.file(save=True, force=True)
Parameters:
  • settings (dict) – The keys are strings, matching the keys returned in the settings property. The values are Setting instances.
  • item – The Item instance to validate.
create_settings_widget(parent)[source]

Creates a Qt widget, for the supplied parent widget (a container widget on the right side of the publish UI).

Parameters:parent – The parent to use for the widget being created
Returns:A QtGui.QWidget or subclass that displays information about the plugin and/or editable widgets for modifying the plugin’s settings.
get_ui_settings(widget)[source]

Invoked by the publisher when the selection changes so the new settings can be applied on the previously selected tasks.

The widget argument is the widget that was previously created by create_settings_widget.

The method returns an dictionary, where the key is the name of a setting that should be updated and the value is the new value of that setting. Note that it is not necessary to return all the values from the UI. This is to allow the publisher to update a subset of settings when multiple tasks have been selected.

Example:

{
     "setting_a": "/path/to/a/file"
}
Parameters:widget – The widget that was created by create_settings_widget
set_ui_settings(widget, settings)[source]

Allows the custom UI to populate its fields with the settings from the currently selected tasks.

The widget is the widget created and returned by create_settings_widget.

A list of settings dictionaries are supplied representing the current values of the settings for selected tasks. The settings dictionaries correspond to the dictionaries returned by the settings property of the hook.

Example:

settings = [
{
     "seeting_a": "/path/to/a/file"
     "setting_b": False
},
{
     "setting_a": "/path/to/a/file"
     "setting_b": False
}]

The default values for the settings will be the ones specified in the environment file. Each task has its own copy of the settings.

When invoked with multiple settings dictionaries, it is the responsibility of the custom UI to decide how to display the information. If you do not wish to implement the editing of multiple tasks at the same time, you can raise a NotImplementedError when there is more than one item in the list and the publisher will inform the user than only one task of that type can be edited at a time.

Parameters:
  • widget – The widget that was created by create_settings_widget
  • settings – a list of dictionaries of settings for each selected task.