Skip to content

interfaces

AYONInterface

Base class of Interface that can be used as Mixin with abstract parts.

This is way how AYON addon can define that contains specific predefined functionality.

Child classes of AYONInterface may be used as mixin in different AYON addons which means they have to have implemented methods defined in the interface. By default, interface does not have any abstract parts.

Source code in client/ayon_core/addon/interfaces.py
16
17
18
19
20
21
22
23
24
25
26
27
class AYONInterface(metaclass=_AYONInterfaceMeta):
    """Base class of Interface that can be used as Mixin with abstract parts.

    This is way how AYON addon can define that contains specific predefined
    functionality.

    Child classes of AYONInterface may be used as mixin in different
    AYON addons which means they have to have implemented methods defined
    in the interface. By default, interface does not have any abstract parts.
    """

    pass

IHostAddon

Bases: AYONInterface

Addon which also contain a host implementation.

Source code in client/ayon_core/addon/interfaces.py
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
class IHostAddon(AYONInterface):
    """Addon which also contain a host implementation."""

    @property
    @abstractmethod
    def host_name(self):
        """Name of host which addon represents."""

        pass

    def get_workfile_extensions(self):
        """Define workfile extensions for host.

        Not all hosts support workfiles thus this is optional implementation.

        Returns:
            List[str]: Extensions used for workfiles with dot.
        """

        return []

host_name abstractmethod property

Name of host which addon represents.

get_workfile_extensions()

Define workfile extensions for host.

Not all hosts support workfiles thus this is optional implementation.

Returns:

Type Description

List[str]: Extensions used for workfiles with dot.

Source code in client/ayon_core/addon/interfaces.py
386
387
388
389
390
391
392
393
394
395
def get_workfile_extensions(self):
    """Define workfile extensions for host.

    Not all hosts support workfiles thus this is optional implementation.

    Returns:
        List[str]: Extensions used for workfiles with dot.
    """

    return []

IPluginPaths

Bases: AYONInterface

Addon has plugin paths to return.

Expected result is dictionary with keys "publish", "create", "load", "actions" or "inventory" and values as list or string. { "publish": ["path/to/publish_plugins"] }

Source code in client/ayon_core/addon/interfaces.py
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
class IPluginPaths(AYONInterface):
    """Addon has plugin paths to return.

    Expected result is dictionary with keys "publish", "create", "load",
    "actions" or "inventory" and values as list or string.
    {
        "publish": ["path/to/publish_plugins"]
    }
    """

    @abstractmethod
    def get_plugin_paths(self):
        pass

    def _get_plugin_paths_by_type(self, plugin_type):
        paths = self.get_plugin_paths()
        if not paths or plugin_type not in paths:
            return []

        paths = paths[plugin_type]
        if not paths:
            return []

        if not isinstance(paths, (list, tuple, set)):
            paths = [paths]
        return paths

    def get_launcher_action_paths(self):
        """Receive launcher actions paths.

        Give addons ability to add launcher actions paths.
        """
        return self._get_plugin_paths_by_type("actions")

    def get_create_plugin_paths(self, host_name):
        """Receive create plugin paths.

        Give addons ability to add create plugin paths based on host name.

        Notes:
            Default implementation uses 'get_plugin_paths' and always return
                all create plugin paths.

        Args:
            host_name (str): For which host are the plugins meant.
        """

        return self._get_plugin_paths_by_type("create")

    def get_load_plugin_paths(self, host_name):
        """Receive load plugin paths.

        Give addons ability to add load plugin paths based on host name.

        Notes:
            Default implementation uses 'get_plugin_paths' and always return
                all load plugin paths.

        Args:
            host_name (str): For which host are the plugins meant.
        """

        return self._get_plugin_paths_by_type("load")

    def get_publish_plugin_paths(self, host_name):
        """Receive publish plugin paths.

        Give addons ability to add publish plugin paths based on host name.

        Notes:
           Default implementation uses 'get_plugin_paths' and always return
               all publish plugin paths.

        Args:
           host_name (str): For which host are the plugins meant.
        """

        return self._get_plugin_paths_by_type("publish")

    def get_inventory_action_paths(self, host_name):
        """Receive inventory action paths.

        Give addons ability to add inventory action plugin paths.

        Notes:
           Default implementation uses 'get_plugin_paths' and always return
               all publish plugin paths.

        Args:
           host_name (str): For which host are the plugins meant.
        """

        return self._get_plugin_paths_by_type("inventory")

get_create_plugin_paths(host_name)

Receive create plugin paths.

Give addons ability to add create plugin paths based on host name.

Notes

Default implementation uses 'get_plugin_paths' and always return all create plugin paths.

Parameters:

Name Type Description Default
host_name str

For which host are the plugins meant.

required
Source code in client/ayon_core/addon/interfaces.py
64
65
66
67
68
69
70
71
72
73
74
75
76
77
def get_create_plugin_paths(self, host_name):
    """Receive create plugin paths.

    Give addons ability to add create plugin paths based on host name.

    Notes:
        Default implementation uses 'get_plugin_paths' and always return
            all create plugin paths.

    Args:
        host_name (str): For which host are the plugins meant.
    """

    return self._get_plugin_paths_by_type("create")

get_inventory_action_paths(host_name)

Receive inventory action paths.

Give addons ability to add inventory action plugin paths.

Notes

Default implementation uses 'get_plugin_paths' and always return all publish plugin paths.

Parameters:

Name Type Description Default
host_name str

For which host are the plugins meant.

required
Source code in client/ayon_core/addon/interfaces.py
109
110
111
112
113
114
115
116
117
118
119
120
121
122
def get_inventory_action_paths(self, host_name):
    """Receive inventory action paths.

    Give addons ability to add inventory action plugin paths.

    Notes:
       Default implementation uses 'get_plugin_paths' and always return
           all publish plugin paths.

    Args:
       host_name (str): For which host are the plugins meant.
    """

    return self._get_plugin_paths_by_type("inventory")

get_launcher_action_paths()

Receive launcher actions paths.

Give addons ability to add launcher actions paths.

Source code in client/ayon_core/addon/interfaces.py
57
58
59
60
61
62
def get_launcher_action_paths(self):
    """Receive launcher actions paths.

    Give addons ability to add launcher actions paths.
    """
    return self._get_plugin_paths_by_type("actions")

get_load_plugin_paths(host_name)

Receive load plugin paths.

Give addons ability to add load plugin paths based on host name.

Notes

Default implementation uses 'get_plugin_paths' and always return all load plugin paths.

Parameters:

Name Type Description Default
host_name str

For which host are the plugins meant.

required
Source code in client/ayon_core/addon/interfaces.py
79
80
81
82
83
84
85
86
87
88
89
90
91
92
def get_load_plugin_paths(self, host_name):
    """Receive load plugin paths.

    Give addons ability to add load plugin paths based on host name.

    Notes:
        Default implementation uses 'get_plugin_paths' and always return
            all load plugin paths.

    Args:
        host_name (str): For which host are the plugins meant.
    """

    return self._get_plugin_paths_by_type("load")

get_publish_plugin_paths(host_name)

Receive publish plugin paths.

Give addons ability to add publish plugin paths based on host name.

Notes

Default implementation uses 'get_plugin_paths' and always return all publish plugin paths.

Parameters:

Name Type Description Default
host_name str

For which host are the plugins meant.

required
Source code in client/ayon_core/addon/interfaces.py
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
def get_publish_plugin_paths(self, host_name):
    """Receive publish plugin paths.

    Give addons ability to add publish plugin paths based on host name.

    Notes:
       Default implementation uses 'get_plugin_paths' and always return
           all publish plugin paths.

    Args:
       host_name (str): For which host are the plugins meant.
    """

    return self._get_plugin_paths_by_type("publish")

ITrayAction

Bases: ITrayAddon

Implementation of Tray action.

Add action to tray menu which will trigger on_action_trigger. It is expected to be used for showing tools.

Methods tray_start, tray_exit and connect_with_addons are overridden as it's not expected that action will use them. But it is possible if necessary.

Source code in client/ayon_core/addon/interfaces.py
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
class ITrayAction(ITrayAddon):
    """Implementation of Tray action.

    Add action to tray menu which will trigger `on_action_trigger`.
    It is expected to be used for showing tools.

    Methods `tray_start`, `tray_exit` and `connect_with_addons` are overridden
    as it's not expected that action will use them. But it is possible if
    necessary.
    """

    admin_action = False
    _action_item = None

    @property
    @abstractmethod
    def label(self):
        """Service label showed in menu."""
        pass

    @abstractmethod
    def on_action_trigger(self):
        """What happens on actions click."""
        pass

    def tray_menu(self, tray_menu):
        from qtpy import QtWidgets

        if self.admin_action:
            action = self.add_action_to_admin_submenu(self.label, tray_menu)
        else:
            action = QtWidgets.QAction(self.label, tray_menu)
            tray_menu.addAction(action)

        action.triggered.connect(self.on_action_trigger)
        self._action_item = action

    def tray_start(self):
        return

    def tray_exit(self):
        return

label abstractmethod property

Service label showed in menu.

on_action_trigger() abstractmethod

What happens on actions click.

Source code in client/ayon_core/addon/interfaces.py
251
252
253
254
@abstractmethod
def on_action_trigger(self):
    """What happens on actions click."""
    pass

ITrayAddon

Bases: AYONInterface

Addon has special procedures when used in Tray tool.

IMPORTANT: The addon. still must be usable if is not used in tray even if would do nothing.

Source code in client/ayon_core/addon/interfaces.py
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
class ITrayAddon(AYONInterface):
    """Addon has special procedures when used in Tray tool.

    IMPORTANT:
    The addon. still must be usable if is not used in tray even if
    would do nothing.
    """

    tray_initialized = False
    _tray_manager = None
    _admin_submenu = None

    @abstractmethod
    def tray_init(self):
        """Initialization part of tray implementation.

        Triggered between `initialization` and `connect_with_addons`.

        This is where GUIs should be loaded or tray specific parts should be
        prepared.
        """

        pass

    @abstractmethod
    def tray_menu(self, tray_menu):
        """Add addon's action to tray menu."""

        pass

    @abstractmethod
    def tray_start(self):
        """Start procedure in tray tool."""

        pass

    @abstractmethod
    def tray_exit(self):
        """Cleanup method which is executed on tray shutdown.

        This is place where all threads should be shut.
        """

        pass

    def execute_in_main_thread(self, callback):
        """ Pushes callback to the queue or process 'callback' on a main thread

            Some callbacks need to be processed on main thread (menu actions
            must be added on main thread or they won't get triggered etc.)
        """

        if not self.tray_initialized:
            # TODO Called without initialized tray, still main thread needed
            try:
                callback()

            except Exception:
                self.log.warning(
                    "Failed to execute {} in main thread".format(callback),
                    exc_info=True)

            return
        self.manager.tray_manager.execute_in_main_thread(callback)

    def show_tray_message(self, title, message, icon=None, msecs=None):
        """Show tray message.

        Args:
            title (str): Title of message.
            message (str): Content of message.
            icon (QSystemTrayIcon.MessageIcon): Message's icon. Default is
                Information icon, may differ by Qt version.
            msecs (int): Duration of message visibility in milliseconds.
                Default is 10000 msecs, may differ by Qt version.
        """

        if self._tray_manager:
            self._tray_manager.show_tray_message(title, message, icon, msecs)

    def add_doubleclick_callback(self, callback):
        if hasattr(self.manager, "add_doubleclick_callback"):
            self.manager.add_doubleclick_callback(self, callback)

    @staticmethod
    def admin_submenu(tray_menu):
        if ITrayAddon._admin_submenu is None:
            from qtpy import QtWidgets

            admin_submenu = QtWidgets.QMenu("Admin", tray_menu)
            admin_submenu.menuAction().setVisible(False)
            ITrayAddon._admin_submenu = admin_submenu
        return ITrayAddon._admin_submenu

    @staticmethod
    def add_action_to_admin_submenu(label, tray_menu):
        from qtpy import QtWidgets

        menu = ITrayAddon.admin_submenu(tray_menu)
        action = QtWidgets.QAction(label, menu)
        menu.addAction(action)
        if not menu.menuAction().isVisible():
            menu.menuAction().setVisible(True)
        return action

execute_in_main_thread(callback)

Pushes callback to the queue or process 'callback' on a main thread

Some callbacks need to be processed on main thread (menu actions must be added on main thread or they won't get triggered etc.)

Source code in client/ayon_core/addon/interfaces.py
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
def execute_in_main_thread(self, callback):
    """ Pushes callback to the queue or process 'callback' on a main thread

        Some callbacks need to be processed on main thread (menu actions
        must be added on main thread or they won't get triggered etc.)
    """

    if not self.tray_initialized:
        # TODO Called without initialized tray, still main thread needed
        try:
            callback()

        except Exception:
            self.log.warning(
                "Failed to execute {} in main thread".format(callback),
                exc_info=True)

        return
    self.manager.tray_manager.execute_in_main_thread(callback)

show_tray_message(title, message, icon=None, msecs=None)

Show tray message.

Parameters:

Name Type Description Default
title str

Title of message.

required
message str

Content of message.

required
icon MessageIcon

Message's icon. Default is Information icon, may differ by Qt version.

None
msecs int

Duration of message visibility in milliseconds. Default is 10000 msecs, may differ by Qt version.

None
Source code in client/ayon_core/addon/interfaces.py
190
191
192
193
194
195
196
197
198
199
200
201
202
203
def show_tray_message(self, title, message, icon=None, msecs=None):
    """Show tray message.

    Args:
        title (str): Title of message.
        message (str): Content of message.
        icon (QSystemTrayIcon.MessageIcon): Message's icon. Default is
            Information icon, may differ by Qt version.
        msecs (int): Duration of message visibility in milliseconds.
            Default is 10000 msecs, may differ by Qt version.
    """

    if self._tray_manager:
        self._tray_manager.show_tray_message(title, message, icon, msecs)

tray_exit() abstractmethod

Cleanup method which is executed on tray shutdown.

This is place where all threads should be shut.

Source code in client/ayon_core/addon/interfaces.py
161
162
163
164
165
166
167
168
@abstractmethod
def tray_exit(self):
    """Cleanup method which is executed on tray shutdown.

    This is place where all threads should be shut.
    """

    pass

tray_init() abstractmethod

Initialization part of tray implementation.

Triggered between initialization and connect_with_addons.

This is where GUIs should be loaded or tray specific parts should be prepared.

Source code in client/ayon_core/addon/interfaces.py
137
138
139
140
141
142
143
144
145
146
147
@abstractmethod
def tray_init(self):
    """Initialization part of tray implementation.

    Triggered between `initialization` and `connect_with_addons`.

    This is where GUIs should be loaded or tray specific parts should be
    prepared.
    """

    pass

tray_menu(tray_menu) abstractmethod

Add addon's action to tray menu.

Source code in client/ayon_core/addon/interfaces.py
149
150
151
152
153
@abstractmethod
def tray_menu(self, tray_menu):
    """Add addon's action to tray menu."""

    pass

tray_start() abstractmethod

Start procedure in tray tool.

Source code in client/ayon_core/addon/interfaces.py
155
156
157
158
159
@abstractmethod
def tray_start(self):
    """Start procedure in tray tool."""

    pass

ITrayService

Bases: ITrayAddon

Source code in client/ayon_core/addon/interfaces.py
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
class ITrayService(ITrayAddon):
    # Module's property
    menu_action = None

    # Class properties
    _services_submenu = None
    _icon_failed = None
    _icon_running = None
    _icon_idle = None

    @property
    @abstractmethod
    def label(self):
        """Service label showed in menu."""
        pass

    # TODO be able to get any sort of information to show/print
    # @abstractmethod
    # def get_service_info(self):
    #     pass

    @staticmethod
    def services_submenu(tray_menu):
        if ITrayService._services_submenu is None:
            from qtpy import QtWidgets

            services_submenu = QtWidgets.QMenu("Services", tray_menu)
            services_submenu.menuAction().setVisible(False)
            ITrayService._services_submenu = services_submenu
        return ITrayService._services_submenu

    @staticmethod
    def add_service_action(action):
        ITrayService._services_submenu.addAction(action)
        if not ITrayService._services_submenu.menuAction().isVisible():
            ITrayService._services_submenu.menuAction().setVisible(True)

    @staticmethod
    def _load_service_icons():
        from qtpy import QtGui

        ITrayService._failed_icon = QtGui.QIcon(
            resources.get_resource("icons", "circle_red.png")
        )
        ITrayService._icon_running = QtGui.QIcon(
            resources.get_resource("icons", "circle_green.png")
        )
        ITrayService._icon_idle = QtGui.QIcon(
            resources.get_resource("icons", "circle_orange.png")
        )

    @staticmethod
    def get_icon_running():
        if ITrayService._icon_running is None:
            ITrayService._load_service_icons()
        return ITrayService._icon_running

    @staticmethod
    def get_icon_idle():
        if ITrayService._icon_idle is None:
            ITrayService._load_service_icons()
        return ITrayService._icon_idle

    @staticmethod
    def get_icon_failed():
        if ITrayService._failed_icon is None:
            ITrayService._load_service_icons()
        return ITrayService._failed_icon

    def tray_menu(self, tray_menu):
        from qtpy import QtWidgets

        action = QtWidgets.QAction(
            self.label,
            self.services_submenu(tray_menu)
        )
        self.menu_action = action

        self.add_service_action(action)

        self.set_service_running_icon()

    def set_service_running_icon(self):
        """Change icon of an QAction to green circle."""

        if self.menu_action:
            self.menu_action.setIcon(self.get_icon_running())

    def set_service_failed_icon(self):
        """Change icon of an QAction to red circle."""

        if self.menu_action:
            self.menu_action.setIcon(self.get_icon_failed())

    def set_service_idle_icon(self):
        """Change icon of an QAction to orange circle."""

        if self.menu_action:
            self.menu_action.setIcon(self.get_icon_idle())

label abstractmethod property

Service label showed in menu.

set_service_failed_icon()

Change icon of an QAction to red circle.

Source code in client/ayon_core/addon/interfaces.py
363
364
365
366
367
def set_service_failed_icon(self):
    """Change icon of an QAction to red circle."""

    if self.menu_action:
        self.menu_action.setIcon(self.get_icon_failed())

set_service_idle_icon()

Change icon of an QAction to orange circle.

Source code in client/ayon_core/addon/interfaces.py
369
370
371
372
373
def set_service_idle_icon(self):
    """Change icon of an QAction to orange circle."""

    if self.menu_action:
        self.menu_action.setIcon(self.get_icon_idle())

set_service_running_icon()

Change icon of an QAction to green circle.

Source code in client/ayon_core/addon/interfaces.py
357
358
359
360
361
def set_service_running_icon(self):
    """Change icon of an QAction to green circle."""

    if self.menu_action:
        self.menu_action.setIcon(self.get_icon_running())