Can I use multiple collectors in tk-multi-publish2?


I’m looking to implement a Maya Alembic camera publish option in tk-multi-publish2. I watched the tutorial here which was quite helpful.

One thing I’ve noticed though, is that while I can have multiple publish plugin hooks for various purposes (eg. and here), it seems that there can only be one

I attempted adding more than one to the tk-multi-publish2 config as below, but it seems like the multiple paths override each other.
  collector: "{self}/{engine}/tk-multi-publish2/basic/{config}/tk-multi-publish2/maya/{config}/tk-multi-publish2/maya/"

(in this case, only seems to be run)

I’d love to be able to avoid copying and pasting whole files to my config, since it means that I would miss any updates that are made to the default, and it’s just extra stuff that I need to maintain. In a perfect world it would be great if SGTK provided some common collector classes in the default tk-multi-publish2 that I could subclass into small modular collector plugins without duplicated code.

Is this correct, or maybe I’m doing something wrong?


1 Like

Hey Matt

Welcome to the forums!!

In a way, you’re correct in that you can only have one collector per Publish2 settings block, unlike the plugins where you can list multiple. However, you can use inheritance to subclass the base collector plugin.

When setting the hook paths you can define a chain of inheritance by separating the paths using :.
In your example, the order of inheritance is (from base to subclasses)

  1. The collector from the publish2 app ({self}/
  2. Then you have the engine’s implementation of the collector {engine}/tk-multi-publish2/basic/
  3. Then your mesh collector {config}/tk-multi-publish2/maya/
  4. And finally your {config}/tk-multi-publish2/maya/

So in this situation, the needs to ensure that it calls super per overridden method so that the method gets called, and likewise, that needs to call super if you want the engine’s implementation of the hook called.

The tk-maya implementation of the collector does this for the settings property:

Hopefully that helps?



Hi Phil, thanks!

I did see that before but I assumed that sgtk.get_hook_baseclass() would just get the default class defined by the plugin but I just tested it out then and it does what I want!

It wasn’t clear to me before but after looking in the Hook documentation I think I understand it now, the order of inheritance of hooks is defined by the environment config .yml, and the base class retrieved by sgtk.get_hook_baseclass() becomes whatever is the hook class that’s defined in the previous file in the .yml ‘collector:’ path list.

Is this right?


I think I have this working quite happily now, with much less code to maintain! :slight_smile:

I did have to do a little bit of extra work to find the correct parent_item to add my camera item to in process_current_session()

def process_current_session(self, settings, parent_item):
    super(MayaCameraCollector, self).process_current_session(settings, parent_item)

    # find the maya session item to attach to
    session_item = next((item for item in parent_item.descendants if item.type_spec == 'maya.session'), None)
    if session_item == None:


It might be nice if the default process_current_session() inside tk-maya’s MayaSessionCollector returned the item so that subclasses could continue attaching to it? Is there any recommended way to make small requests like this? A PR against the Shotgun Toolkit github repo?

thanks again

1 Like

We are looking into putting a guide together to compliment the reference documentation, so hopefully, this will make it clearer to others in the future. And yes your understanding is correct!

I’ve popped a suggestion into our product team on your behalf, and of course your more than welcome to submit a pull request. However, I’m not sure my self how much that would help, the reason being is that the process_current_session method could create and link multiple items to the parent item, and those items, in turn, could have child items, so you would need to return back either a dictionary or perhaps a flat list of items, which you can essentially access through the parent_item.descendants.