Integrations Developer Guide

Table of Contents:

      Panels

            Configuring what is being displayed

            Configuring Actions

      Publisher

            Overview

                  Publish Phase Summary

            Collectors

                  Publish Items

                  Configuration

            Publish Plugins

                  Plugin Interface

                  Configuration

                  Logging

            Path info hook

                  Configuration

      Loader

      Advanced functionality

      Shotgun Toolkit makes it easy to develop tools

Panels

See https://github.com/shotgunsoftware/tk-multi-shotgunpanel/tree/master/hooks for examples of panel actions.

Configuring what is being displayed

The values in the detail area and the listings are both configurable through the shotgun_fields hook. You can subclass this hook and change the implementation in order to display the exact values you want:

Templating System

The hook supports a simple templating language, allowing for great flexibility. It also supports the HTML subset supported by Qt, so you can control color, font size, weight, etc. of your displayed values. The template language works in the following way:

  • Shotgun values are enclosed in {brackets}, for example <b>Description:</b> {description}. When this template is rendered, the {description} part will be replaced with the description field value.

  • If you want an optional pre- or post-fix for a value which is only shown if the value is not empty, you can use the syntax {[Prefix]sg_field[suffix]}. The template {[Start: ]start_date} {[End: ]end_date} will render Start: 12 July 2009 End: 14 July 2012 if both values are populated but Start: 12 July 2009 if end date isn't set.

  • You can define fallbacks in the case some values are not set. For Shotgun Versions, the artist fields takes precedence over the created_by field in order to support a workflow where a producer submits versions on behalf of an artist. In this case, the Version will be created by the producer but the artist field will be set to the artist. This, however, is not always the case - in some cases, artist is left blank in pipelines where artists submit their own work. When displaying versions, it is therefore useful to be able to check the artist field first, and in case this isn't set, fall back on the created_by field. This is done using the {field1|field2} syntax, for example: Created By: {artist|created_by}. You can combine this with optional fields too, e.g. {[Created By: ]artist|created_by}

This hook contains the following methods:

Controlling items appearing in lists

The get_list_item_definition() method returns a dictionary that controls the appearance of items in the various listings, given a Shotgun entity type. It returns a dictionary with the keys top_left, top_right and body, for example:

{
 "top_left": "<big>{code}</big>",
 "top_right": "{updated_at}",
 "body": "By: {created_by}<br>Description: {description}"
}

Controlling the top detail area

The get_main_view_definition() method returns a dictionary with the keys title and body given a Shotgun entity type. These values controls the appearance of an object in the detail area, for example:

{
 "title": "{type} {code}",
 "body": "By: {created_by}<br>Description: {description}"
}

Controlling the fields shown in the Info tab

The get_all_fields() methods returns a list of fields to display for a given entity when this is rendered in the Info tab.

Configuring Actions

Actions are little snippets of code that operate on a piece of Shotgun data. Examples include:

  • An action that launches RV for a given Shotgun Version
  • An action that allows a user to assign herself to a given Task
  • An action that loads a Shotgun publish into Maya as a Maya reference.

The actual payload of an action is defined in an action hook. Once you have defined the action logic, you can then map that action to Shotgun objects in the app configuration. These action mappings may for example look like this:

action_mappings:
  PublishedFile:
  - actions: [reference, import]
    filters: {published_file_type: Maya Scene}
  - actions: [texture_node]
    filters: {published_file_type: Rendered Image}
  Task:
  - actions: [assign_task]
    filters: {}
  Version:
  - actions: [play_in_rv]
    filters: {}

In the above example, we use the actions reference, import, texture_node, assign_task and play_in_rv. We then map the actions to various Shotgun objects and conditions. For example, we are requesting the import action to appear for all publishes of type Maya Scene.

When an object is loaded into the Panel, the action configuration above is read in and analyzed. A list of suitable actions for the current object is determined and the generate_actions() hook method will be executed. Shotgun data for the given entity will be passed to the hook at this point so that the hook code can determine if the action can be run for this particular Shotgun object. This is a way to allow each hook to run a check prior to being displayed. For example, the play_in_rv hook may only be relevant in the case there is media available locally - the action mappings set up in the configuration tells the panel which actions to enable for a given shotgun entity but they may not all be displayed because the generate_actions() method may determine that they are not suitable for the given object.

The actions returned from the generate_actions() method will be displayed on the actions menu and when a user clicks on it, the execute_acton() hook method is called to run the action.

For each application that the panel supports, there is an actions hook which implements suitable actions. For example, with something like Maya, the default hook will implement reference, import and texture_node actions, each carrying out specific Maya commands to bring publishes into the current Maya scene. As with all hooks, it is perfectly possible to override and change these, and it is also possible to create a hook that derives from the built in hook, making it easy to add additional actions to a built-in hook without having to duplicate lots of code.

The panel uses Toolkit's second generation hooks interface, allowing for greater flexibility. This hook format uses an improved syntax. You can see this in the default configuration settings, looking something like this:

actions_hook: '{self}/tk-maya_actions.py'

The {self} keyword tells Toolkit to look in the app's hooks folder for the hook. If you are overriding this hook with your implementation, change the value to {config}/panel/maya_actions.py. This will tell Toolkit to use a hook called hooks/panel/maya_actions.py in your configuration folder.

For more information, please see the hook files that come with the app. The hooks also take advantage of inheritance, meaning that you don't need to override everything in the hook, but can more easily extend or augment the default hook in various ways, making hooks easier to manage.

By using inheritance in your hook, it would be possible to add additional actions to the default hooks like this:

import sgtk
import os

# toolkit will automatically resolve the base class for you
# this means that you will derive from the default hook that comes with the app
HookBaseClass = sgtk.get_hook_baseclass()

class MyActions(HookBaseClass):

    def generate_actions(self, sg_data, actions, ui_area):
        """
        Returns a list of action instances for a particular object.
        The data returned from this hook will be used to populate the 
        actions menu.

        The mapping between Shotgun objects and actions are kept in a different place
        (in the configuration) so at the point when this hook is called, the app
        has already established *which* actions are appropriate for this object.

        This method needs to return detailed data for those actions, in the form of a list
        of dictionaries, each with name, params, caption and description keys.

        Because you are operating on a particular object, you may tailor the output 
        (caption, tooltip etc) to contain custom information suitable for this publish.

        The ui_area parameter is a string and indicates where the publish is to be shown. 

        - If it will be shown in the main browsing area, "main" is passed. 
        - If it will be shown in the details area, "details" is passed.

        :param sg_data: Shotgun data dictionary with all the standard publish fields.
        :param actions: List of action strings which have been defined in the app configuration.
        :param ui_area: String denoting the UI Area (see above).
        :returns List of dictionaries, each with keys name, params, caption and description
        """

        # get the actions from the base class first
        action_instances = super(MyActions, self).generate_actions(sg_data, actions, ui_area)

        if "my_new_action" in actions:
            action_instances.append( {"name": "my_new_action",
                                      "params": None,
                                      "caption": "My New Action",
                                      "description": "My New Action."} )

        return action_instances

    def execute_action(self, name, params, sg_data):
        """
        Execute a given action. The data sent to this be method will
        represent one of the actions enumerated by the generate_actions method.

        :param name: Action name string representing one of the items returned by generate_actions.
        :param params: Params data, as specified by generate_actions.
        :param sg_data: Shotgun data dictionary with all the standard publish fields.
        :returns: No return value expected.
        """

        if name == "my_new_action":
            # do some stuff here!

        else:
            # call base class implementation
            super(MyActions, self).execute_action(name, params, sg_data)

We could then bind this new action to a set of publish types in the configuration:

action_mappings:
  PublishedFile:
  - actions: [reference, import, my_new_action]
    filters: {published_file_type: Maya Scene}
  Version:
  - actions: [play_in_rv]
    filters: {}

By deriving from the hook as shown above, the custom hook code only need to contain the actual added business logic which makes it easier to maintain and update.

Publisher

Overview

The Publish app is highly customizable by way of hooks that control how items are presented to artists for publishing and how those files are then processed. The following sections outline all of the hooks and APIs available to studios.

For more information on how to use the Publish app, see the User Guide. If you are looking for more information about the first generation Publisher, please visit the classic Publisher docs.

Publish Phase Summary

The publisher has several phases of execution that developers should be aware of.

  • Collection: When the Publisher is launched, items for the current user session are collected via the collector hook. Collection also happens as files are dragged and dropped into the Publish UI.

  • Acceptance: After collection, configured publish plugins are given the opportunity to decide if they will operate on the collected items. An initial acceptance pass is done by checking the item’s type against the plugin’s filters. If an item’s type matches a plugin’s filter then a method will be called on the plugin to execute more specific acceptance logic.

  • Validation: Items that have been accepted by one or more plugins will be validated once the user clicks the Validate or Publish buttons in the UI. The validation phase is used to perform checks on the state of the items to ensure they can be published without error.

  • Publish: When the Publish button is clicked, the items are then processed by each matched plugin. The plugins can perform any actions required by a studio from creating Publish entries in Shotgun to uploading reviewable media.

  • Finalize: Once the publish phase is complete, the plugin’s finalize phase is executed to handle any cleanup or summary reporting required.

Collectors

The collector hook handles processing the current user’s session for items to publish. It also handles processing and files that have been dragged and dropped onto the Publisher. It’s primary purpose is to discover and classify items to present to the user for publishing. There are two methods that must be implemented.

process_file(parent_item, path)

This method accepts a path that has been dropped from an external source onto the Publisher’s UI. The path is analyzed by the method and one or more publish items is created to display to the user for publishing. The items should be created as children of the supplied parent item.

process_current_session(parent_item)

This method analyzes the user’s content creation session (Maya scene, Nuke script, Photoshop documents, etc.) and creates one or more publish items. These items can represent already exported files on disk or components within the session that will be exported during the publish process. The items should be created as a subtree under the supplied parent item.

Publish Items

Creation

Publish items are created via the create_item method of an existing item (typically the parent_item supplied to one of the collector methods):

create_item(item_type, display_type, name)

The item_type is a string that represents the type of the item. This can be any string, but is typically defined by studio convention. This value is used by the publish plugins to identify which items to act upon. The basic Shotgun integrations use a hierarchical dot notation. Examples include: file.image, file.movie, and maya.scene.

The display_type argument corresponds to the item type, but is used for display purposes only.

Examples include: Image File, Movie File, and Maya Scene.

The name argument is the display name for the item instance. This can be the name of a file or a node name in Nuke or Houdini, or a combination of both. This value is displayed to the user and should make it easy for the user to identify what the item represents in terms of the current session or a file on disk.

Methods and Properties

Once created, the item can be further customized for display to the user via the following methods and properties:

Associated Items

parent

The parent publish item (read only).

children

A list of child publish items (read only).

Item Information

context

The context associated with this item. If no context has been defined, the parent context will be returned or if that hasn't been defined, None will be returned.

description

The publish description for this item that will be displayed to the user and associated with the eventual Publish in Shotgun. If no description has been set for this item, the parent item’s description will be returned. If no description has been set for the parent, None will be returned.

display_type

The display type as defined when creating the Publish item.

name

The item’s display name as defined during creation.

properties

A free form dictionary where arbitrary data can be stored on the item. The properties dictionary itself is read only (calling item.properties = my_properties is invalid) but arbitrary key value pairs can be set within the dictionary itself. This property provides a way to store data for an item across publish plugins and between the various publish phases within a plugin.

thumbnail

The associated thumbnail, as a QPixmap. The thumbnail is an image to represent the item visually such as a thumbnail of an image or a screenshot of a scene. If no thumbnail has been defined for the item, the parent thumbnail is returned. If no thumbnail exists, the value will be None.

type

The item type as defined when Publish item was created.

Item State

checked

A bool indicating whether the publish item’s check box should be checked by default. Note that the item’s check state is also affected by any child items and publish plugins. The default is True.

enabled

A bool indicating whether the item should be enabled or disabled in the publish UI. This can be used in combination with the checked property to indicate required publish plugins that can not be disabled by the user. The default is True.

expanded

A bool indicating whether the item should be expanded or collapsed in the publish UI. The default is True.

thumbnail_enabled

A bool indicating whether thumbnail generation is enabled or disabled for the publish item. The default is True.

Icon and Thumbnail

set_thumbnail_from_path(path)

Helper method to create a thumbnail for the publish item from the given path.

set_icon_from_path(path)

Helper method to create an icon for the publish item from the given path.

Configuration

The collector hook is configured via the Publish app’s collector setting of type hook. See the developer documentation for more information about the hook setting data type.

For the basic Shotgun integration, the convention is to use a base class collector for handling files that are dragged and dropped into the Publisher. A collector that handles the specific content creation software then subclasses the base collector. Here is an example of how that looks in the basic configuration:

collector: "{config}/tk-multi-publish2/basic/collector.py:{config}/tk-multi-publish2/maya.basic/collector.py"

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.

Plugin Interface

The following methods and properties must be defined by publish plugin hooks:

icon

The path to an image on disk to use as this plugin’s icon.

name

A one line name for this plugin.

description

Verbose, multi-line description of what the plugin does. This can contain simple HTML for formatting.

settings

Dictionary defining the settings that this plugin expects to receive through the settings parameter in the accept, validate, publish and finalize methods. The dictionary takes the following form:

    {
        "Settings Name": {
            "type": "settings_type",
            "default": "default_value",
            "description": "One line description of the setting"
        },

        "Another Setting": {
            "type": "settings_type",
            "default": "default_value",
            "description": "One line description of the setting"
        }
    }

The type string should be one of the data types that toolkit accepts as part of its environment configuration.

item_filters

A list of item types that this plugin is interested in. Only items matching entries in this list will be presented to the accept method. Strings can contain glob patterns such as *, for example ["maya.*", "file.maya"].

accept(settings, item)

Called by the publisher to determine if an item is of any interest to this plugin. 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. Returns a dictionary with the following booleans:

  • accepted: Indicates if the plugin is interested in this value at all. Required.
  • enabled: If True, the plugin instance will be enabled in the UI, otherwise it will be disabled. Optional, True by default.
  • visible: If True, the plugin instance will be visible in the UI, otherwise it will be hidden. Optional, True by default.
  • checked: If True, the plugin instance will be checked in the UI, otherwise it will be unchecked. Optional, True by default.

The settings argument is a dictionary of settings matching the keys returned in the settings property. The values are the configured instances of the settings.

The item argument represents the item to process.

validate(settings, item)

Validates the given item to check that it is ok to publish. Returns a boolean to indicate validity.

The settings argument is a dictionary of settings matching the keys returned in the settings property. The values are the configured instances of the settings.

The item argument represents the item to process.

publish(settings, item)

Executes the publish logic for the given item and settings.

The settings argument is a dictionary of settings matching the keys returned in the settings property. The values are the configured instances of the settings.

The item argument represents the item to process.

finalize(settings, item)

Executes the finalization pass. This pass executes once all the publish tasks have completed.

The settings argument is a dictionary of settings matching the keys returned in the settings property. The values are the configured instances of the settings.

The item argument represents the item to process.

Configuration

The publish plugin hooks are configured via the Publish app’s publish_plugins setting. The setting is defined as a list of hooks. See the developer documentation for more information about the hook data type.

The publish plugins settings for the Maya integration in the basic Shotgun integration look like this:

    publish_plugins:
        - '@common.settings.tk-multi-publish2.publish_file'
        - '@common.settings.tk-multi-publish2.upload_version'
        - name: Begin file versioning
          hook: "{config}/tk-multi-publish2/maya.basic/start_version_control.py"
          settings: {}
        - name: Publish to Shotgun
          hook: "{config}/tk-multi-publish2/maya.basic/publish_maya_session.py"
          settings: {}

The first two plugins defined are included and handle publishing and uploading media for standard files. The third and fourth plugin handle maya session publishing.

Any number of publish plugins can be configured within an instance of the Publisher.

Logging

Any logging in the collector and publish plugin hooks will be displayed in the progress details widget of the Publisher. The standard logging methods can be used to display information, warnings, errors, and debug messages to the user.

The publisher has a special logging handler that will make use of the standard extra dictionary to display action buttons next to the log messages. The following examples represent the recognized action button dictionary forms.

action_button

A generic button to execute a callback method when clicked. Example:

    {
        "label": "Hello, world!",
        "tooltip": "This button says hello to the world.",
        "callback": self._hello_world,
        "args": {"foo": 123, "bar": 456}
    }

The label is the text to display on the button. The tooltip is the button’s tooltip. The callback is the method to execute when clicked. The args are the arguments to supply to the callback.

action_show_folder

A common action for showing the folder for a supplied path in the system's file browser. Example:

    {
        "label": "Show Publish Folder",
        "tooltip": "Show the publish path in a file browser.",
        "path": path,
    }

The path is the path to the file or folder to show in the file browser. The label and tooltip are optional. The default values are "Show Folder" and "Reveal in the system's file browser", respectively.

action_show_in_shotgun

A common action for showing an entity's detail page in Shotgun. Example:

    {
        "label": "Show Version",
        "tooltip": "Show uploaded Version in Shotgun.",
        "entity": entity,
    }

The entity is a standard Shotgun entity dictionary corresponding to the entity to show in Shotgun. The label and tooltip are optional. The default values are "Show Entity" and "Reveal the entity in Shotgun", respectively.

action_show_more_info

A common action for showing more information than what typically fits on a single line of logging output. The output will be shown in a text browser popup dialog. Example:

    {
        "label": "Show Error",
        "tooltip": "Show the full error stack trace.",
        "text": formatted_stack_trace,
    }

The text is a long string of text to display in a popup dialog. The label and tooltip are optional. The default values are "More Info..." and "Show additional logging info", respectively.

action_open_url

A common action for opening a supplied URL in the default browser. Example:

    {
        "label": "Show Docs",
        "tooltip": "Show the associated documentation.",
        "url": url,
    }

The url is the URL to open. The label and tooltip are optional. The default values are "Open URL" and "Opens a url in the appropriate browser", respectively.

Path info hook

The path_info hook contains methods that are used by the basic Shotgun integration to infer information from file paths. This includes version and frame number identification, publish display name, image sequence paths, etc. Studios can override these path processing methods to account for their own naming conventions and path structures.

All of the methods of the path_info hook are exposed via the publisher’s util module to make them easily callable within the collector hook and publish hooks. The methods defined in the hook are:

get_publish_name(path, sequence=False)

Given a file path, return the display name to use for publishing. Typically, this is a name where the path and any version number are removed in order to keep the publish name consistent as subsequent versions are published. Example:

    # versioned file. remove the version
    in: /path/to/the/file/scene.v001.ma
    out: scene.ma

    # image sequence. replace the frame number with #s
    in: /path/to/the/file/my_file.001.jpg
    out: my_file.###.jpg

The path argument is the path to a file, likely one to be published. If the sequence argument is True, treat the path as a sequence name and replace the frame number with placeholder.

The method returns a string that is the publish display name for the provided path.

get_version_number(path)

Extract a version number from the supplied path. This is used by plugins that need to know what version number to associate with the file when publishing.

The path argument is the path to a file, likely one to be published.

The method returns an integer representing the version number in the supplied path. If no version found, None will be returned.

get_frame_sequence_path(path, frame_spec=None)

Given a path with a frame number, return the sequence path where the frame number is replaced with a given frame specification such as {FRAME} or %04d or $F.

The path argument is the input path with a frame number. The frame_spec argument represents the frame specification to replace the frame number with.

The method returns a string representing the full frame sequence path.

get_frame_sequences(folder, extensions=None, frame_spec=None)

Given a folder, inspect the contained files to find what appear to be files with frame numbers.

The path argument is the path to a folder potentially containing a sequence of files.

The extensions argument is a list of file extensions to retrieve paths for. If not supplied, the extension matching will be ignored.

The frame_spec argument is a string to use to represent the frame number in the returned sequence path.

The method returns a list of tuples for each identified frame sequence. The first item in the tuple is a sequence path with the frame number replaced with the supplied frame specification. If no frame spec is supplied, a python string format spec will be returned with the padding found in the file. Example:

    # method call:
    get_frame_sequences(
        "/path/to/the/folder",
        extensions=["exr", "jpg"],
        frame_spec="{FRAME}"

    )

    #results:
    [
        (
            "/path/to/the/supplied/folder/key_light1.{FRAME}.exr",
            [<frame_1_path>, <frame_2_path>, ...]
        ),
        (
            "/path/to/the/supplied/folder/fill_light1.{FRAME}.jpg",
            [<frame_1_path>, <frame_2_path>, ...]
        )
    ]

get_version_path(path, version)

Given a path without a version number, return the path with the supplied version number. If a version number is detected in the supplied path, the path will be returned as-is.

The path argument is a path to inject a version number info.

The version argument is the number to inject into the path.

The method returns the modified path with the supplied version number inserted.

get_next_version_path(path)

Given a file path, return a path to the next version. This is typically used by auto-versioning logic in plugins that need to save the current work file to the next version number. If no version can be identified in the supplied path, None will be returned, indicating that the next version path can't be determined.

The path argument is the path to a file, likely one to be published.

The method returns the path to the next version of the supplied path.

util methods

Other methods are defined by the Publisher’s util module which can be useful when authoring publish plugins. These methods are described below.

get_file_path_components(path)

Convenience method for determining file components for a given path.

The path argument is the path to the file to componentize.

The method returns file path components in the following form:

    # path="/path/to/the/file/my_file.v001.ext"
    {
        "path": "/path/to/the/file/my_file.v001.ext",
        "folder": "/path/to/the/file" ,
        "filename": "my_file.v001.ext",
        "extension": "ext",
    }

    # path="/path/to/the/folder"
    {
        "path": "/path/to/the/folder",
        "folder": "/path/to/the" ,
        "filename": "folder",
        "extension": None,
    }

Configuration

The path info hook is configurable via the Publish app’s path_info setting. See the developer documentation for more information about the hook data type.

Loader

See https://github.com/shotgunsoftware/tk-multi-loader2/tree/master/hooks for examples of load actions.

Advanced functionality

Shotgun Toolkit makes it easy to develop tools

Did we mention that you can write your own Apps? Each Engine exposes a consistent interface based on Python and PySide, so you can write a single App that works in both Nuke, Photoshop and 3dsmax. With the Core API functionality, there is no need to build a big pipeline stack for the studio - instead focus dev resources on solving production problems. Reusing tools between projects is easy with our Toolkit - if file naming conventions or other requirements are changing, simply reconfigure the app. Roll out tools safely via the Toolkit's built-in Git and Github support and quickly hot-load your code when doing development. Work in your own Dev Sandbox and invite TDs and early adopters to test your code without having to roll it out to everyone on the project.

Tell the doc gen system that we don't want a header by adding this special markup: TANK_NO_HEADER

Follow

0 Comments

Please sign in to leave a comment.