Nuke integrations - having trouble getting engine context

I’m not sure if this is even possible but I’m working on a menu.py script for SG-integerated Nuke.
So far I’m able to tell that I can import sgtk and get the current engine but after that it seems to not work.

If I make a call like this, it will crash the Nuke startup:

engine = sgtk.platform.current_engine()
project = engine.context.project

Yet if I make that same call in the Nuke scripting terminal it comes up with the project context.

Is this a matter of the engine not being fully started when menu.py is called?

Also, all this is completely invisible to me. I can’t see any logs out of my init or menu.py despite calling the engine logger.

import os
import nuke
import sgtk

logger = sgtk.platform.get_logger(__name__)
logger.info("Hello from menu.py?")

Any possible way I can get this working?

Thanks!

Yeah it does seem your menu.py is probably loading before the engine is initialized.

There’s a couple things you could do here.

  1. Use the engine_init core hook instead of a menu.py. That core hook is guaranteed to run after the engine is fully initialized.

https://developer.shotgridsoftware.com/tk-core/core.html#module-engine_init

  1. Use a thread to wait for the engine to be fully initialized then use nuke.executeInMainThread to call a method that performs the actions using the nuke engine when it’s available. That would probably look something like this (untested).
import time
import threading
import nuke
import sgtk


def startup():
    engine = sgtk.platform.current_engine()
    # Do something with engine here...


def await_sg_engine_and_call(callback):
    retries = 60
    for i in range(retries):

        # Check if an engine is available
        if sgtk.platform.current_engine() is not None:
            print(f"SG Engine loaded!! Executing {callback}...")
            return nuke.executeInMainThread(callback)

        # Wait a second before checking again...
        time.sleep(1)

    print("SG Engine didn't initialize within 60 seconds. Callback will not be executed.")


task = threading.Thread(
    target=await_sg_engine_and_call, 
    args=(startup,),
    daemon=True,
)
task.run()

Option 1 is more robust, but if you don’t have the option of using a hook then using option 2 would probably work. I’m not sure what the best method of waiting for an engine to be fully initialized is, above we simply check if current_engine() returns a value.

Ill give that a try and report back. Thanks!

The threaded wait in the menu.py didn’t seem to work. It times out before the engine is ready. I even set the timeout to 2 minutes and it never started. Not sure what’s up with it.

I would recommend creating a custom app for this so you can hook into the events properly.
Events like app_init, etc.

You can also hook into context change events this way.