Actions

An action is a custom script that is executed from the ftrack interface. It can be used to extend functionality in ftrack such as generating reports or launching applications. A custom action can be setup to run from inside connect by adding a hook or as a standalone script to perform company-wide operations.

Actions build on top of the Events framework.

Tip

You can read about how to use actions in Integrating using actions.

Example action

This example registers a new action which only shows up when a single version is selected in the ftrack interface.

import logging

import ftrack


class MyCustomAction(ftrack.Action):
    '''Custom action.'''

    label = 'My Action'
    identifier = 'my.custom.action'
    description = 'This is an example action'

    def discover(self, event):
        '''Return action config if triggered on a single asset version.'''
        data = event['data']

        # If selection contains more than one item return early since
        # this action can only handle a single version.
        selection = data.get('selection', [])
        self.logger.info('Got selection: {0}'.format(selection))
        if len(selection) != 1 or selection[0]['entityType'] != 'assetversion':
            return

        return {
            'items': [{
                'label': self.label,
                'description': self.description,
                'actionIdentifier': self.identifier
            }]
        }

    def launch(self, event):
        '''Callback method for custom action.'''
        selection = event['data'].get('selection', [])

        for entity in selection:

            version = ftrack.AssetVersion(
                entity['entityId']
            )

            #DO SOMETHING WITH THE VERSION

        return {
            'success': True,
            'message': 'Ran my custom action successfully!'
        }


def main():
    '''Register action and listen for events.'''
    logging.basicConfig(level=logging.INFO)

    ftrack.setup()
    action = MyCustomAction()
    action.register()

    ftrack.EVENT_HUB.wait()


if __name__ == '__main__':
    main()

Tip

To group actions together, give them the same label and specify a unique variant per action.

Custom UI

Actions can be setup to ask for more information through a custom UI before being launched. To show a UI before launching the action an items configuration should be returned from the launch method.

When the user has entered the requested information the launch method is called again and the event data will contain the result.

The items can be of different types but should all have a name to identify them. They can also have a value which will be the default value and a label to present what they mean to the user.

text

A text is a single line string that can have value, name and label.

textarea

A text area is a multiline string that can have value, name and label.

number

A number can have a value, name and label.

date

A date can have a value that should be in ISO format, name and label.

enumerator

An enumerator is a dropdown menu that allows for selecting between different options. The enumerator field can have a value, a name and a label but should also have a data config specifying the options to choose from.

myEnumerator = {
    'label': 'My Enumerator',
    'type': 'enumerator',
    'name': 'my_enumerator',
    'data': [
        {
            'label': 'Option 1',
            'value': 'opt1'
        }, {
            'label': 'Option 2',
            'value': 'opt2'
        }
    ]
}

label

A label does not allow any input from the user but can be used to display information. The label supports Markdown but should not have a name or label, only a value.

hidden

A hidden field that is not visible to the user. It can be used to pass around data to keep the action script implementation stateless.

Example

import logging
import datetime

import ftrack


class MyCustomAction(ftrack.Action):
    '''Custom action.'''

    label = 'My Action'
    identifier = 'my.custom.action'
    description = 'This is an example action returning UI'

    def launch(self, event):
        if 'values' in event['data']:
            # Do something with the values or return a new form.
            values = event['data']['values']
            print values

            return {
                'success': True,
                'message': 'Ran my custom action successfully!'
            }

        return {
            'items': [
                {
                    'label': 'My String',
                    'type': 'text',
                    'value': 'no string',
                    'name': 'my_string'
                }, {
                    'label': 'My String2',
                    'type': 'text',
                    'value': 'no string2',
                    'name': 'my_string2'
                }, {
                    'label': 'My Date',
                    'type': 'date',
                    'name': 'my_date',
                    'value': datetime.date.today().isoformat()
                }, {
                    'label': 'My Number',
                    'type': 'number',
                    'name': 'my_number',
                    'empty_text': 'Type a number here...'
                }, {
                    'value': '## This is a label. ##',
                    'type': 'label'
                }, {
                    'label': 'Enter your text',
                    'name': 'my_textarea',
                    'value': 'some text',
                    'type': 'textarea'
                }, {
                    'label': 'My Enum',
                    'type': 'enumerator',
                    'name': 'my_enumerator',
                    'data': [
                        {
                            'label': 'Option 1',
                            'value': 'opt1'
                        }, {
                            'label': 'Option 2',
                            'value': 'opt2'
                        }
                    ]
                }
            ]
        }


def main():
    '''Register action and listen for events.'''
    logging.basicConfig(level=logging.INFO)

    ftrack.setup()
    action = MyCustomAction()
    action.register()

    ftrack.EVENT_HUB.wait()


if __name__ == '__main__':
    main()