Qt-less Engine for publishing


I’m running into some issues getting my tk-mutlipublish2 apps running in an environment without a Qt installation. Is it possible to start a publisher with a qt-less engine? I thought perhaps tk-shell would work but it still requires a qt installation.

Is there a way around this? I’m trying to set up a publisher that doesn’t rely on the user interface.



Hi @StarkRavenSimone!
Yeah, you should be able to use the Publish API without the UI, but we did discover a bug where it would attempt to use the UI when it shouldn’t, however we fixed that in the most recent version that just went out.

At what point is it saying you need the UI?
It’s possible there might be another case where it’s unintentionally expecting a UI.


In publish_plugin_instance.py line 161.
It does a check to see if the current engine has a UI.
If that’s false, it tries to import QtCore.

Why would it try to import QtCore if there isn’t supposed to be a UI?

In order to get it to work (and I’m using tk-shotgun engine) I have to basically tell the engine it does have a UI in order to get it to work.

1 Like

Oh, shoot, you’re totally right :woman_facepalming:t4:. We just fixed that exact error further down in the file (you can see the whole story in this thread), but it looks like we missed that one.

I’ve put in an internal bug ticket and it should be a very quick fix. We’ll report back when it’s out. So sorry about that!

1 Like

no worries. my workaround works just fine.


1 Like

Hiya – Just wanted to let you know that this has been fixed. You can get the fix in v2.5.1+ of tk-multi-publish2. Let us know if you hit any other snags!


Hey There.

Seems like I’m running into this issue again.
I’m using tk-multi-publish2 ver 2.5.3.

I start my engine with
self.engine = self.toolkit_manager.bootstrap_engine("tk-remote", entity={"type": "Project", "id": self.project["id"]})

and I end up with this error:
App C:\Users\xxx\AppData\Roaming\Shotgun\bundle_cache\app_store\tk-multi-publish2\v2.5.3 failed to initialize. It will not be loaded: The Shotgun Toolkit App you are trying to execute requires a full QT environment in order to render its UI. A valid PySide2/PySide/PyQt installation could not be found in your python system path.

The way I got around this in the past was forcing the current_engine._has_ui = True
This does not work now. Is there any way to circumvent this issue so I can continue to run non-ui toolkit scripts?


1 Like

I just need to be able to run publishing that follows the publish hooks I’ve established for my configs. Is there some what I can do this without having to rely on the UI?


1 Like

How is it even locating this QT installation? Is it looking at an environment variable? I’ve tried this on one system and it loads tk-multi-publish2 just fine. I try it on another and I get an error.

If it helps, here is how I’m bootstrapping the system:

First I import a shared install of the tk-core:
import sgtk
Then I set an authenticated user
from tank_vendor.shotgun_authentication import ShotgunAuthenticator
sa = self.sgtk.authentication.ShotgunAuthenticator()

Then I boostrap the toolkit manager
self.toolkit_manager = self.sgtk.bootstrap.ToolkitManager(sg_user=self._auth_user)
self.toolkit_manager.base_configuration = "sgtk:descriptor:app_store?name=tk-multi-publish2"
self.toolkit_manager.plugin_id = "basic.my_toolkit_plugin"
self.engine = self.toolkit_manager.bootstrap_engine("tk-remote", entity{"type": "Project", "id": self.project["id"]})

Where tk-remote is just an engine I’m using to load tk-multi-publish2.

On my personal pc if i show all the apps the engine has available I get:
10:46:06 INFO start_publish_engine tk-multi-publish2
10:46:06 INFO start_publish_engine tk-multi-screeningroom
10:46:06 INFO start_publish_engine tk-shotgun-launchfolder

however on a deadline render worker I will get:
10:39:13 INFO start_publish_engine tk-multi-screeningroom
10:39:13 INFO start_publish_engine tk-shotgun-launchfolder

Let me know if there’s anything else I can provide to make this clearer. I’m trying to work via a distributed configs system and I’m pretty new to how that works.



So, the error is coming from the engine; I see it in tk-shotgun, and here in tk-shell:

I’m guessing you’ve got it in your tk-remote engine as well.

I’m not sure exactly how/when this code is run, but looking at the comment, it looks like the exception should only be raised when Qt code tries to use it, not at engine initialization time. Did you get a full stack trace for that error? I’m hoping it will have some line numbers and we can see specifically where in the Publisher code it’s falling down.

Beyond that, I’ll run this by an engineer early next week and see if I can get more info.

1 Like

Hi, Thanks for getting back to me!

Tk-shotgun is indeed where the trouble seems to be originating for me. My question then is there a way I can circumvent the check for the UI without having to modify any of the toolkit code?

Because the toolkit populates to a user’s roaming path, I don’t know that there’d be a way I can modify that code without having to keep my own repository of the toolkit. This is troublesome because then I won’t be able to keep up with changes that Shotgun rolls out.

Failing this, can I define a new engine (much like I did with tk-remote) that doesn’t require any UI confirmation?

I’ll keep trying some things on my end in the meantime.


1 Like

What puzzles me is why this is failing when I was able to circumvent it in the past.

Before I was initializing the engine like this

self.context = self.tk.context_from_entity(“Project”,


self.logger.info(“Context enabled {}”.format(self.context))

self.engine = self.sgtk.platform.start_engine(self.engine_name,



self.sgtk.platform.current_engine()._has_ui = True

Where I would trick the current engine into thinking it had the UI. This apparently worked because, well, it works. Haha. (that isn’t to say there’s some other factor involved making this work)

Now with updated toolkit apps I try to boostrap the engine like this:

self.toolkit_manager = self.sgtk.bootstrap.ToolkitManager(sg_user=self._auth_user)

self.toolkit_manager.base_configuration = sgtk:descriptor:app_store?name=tk-basic-config"

self.toolkit_manager.plugin_id = “basic.my_toolkit_plugin”

self.engine = self.toolkit_manager.bootstrap_engine(“tk-desktop”, entity={“type”: “Project”, “id”: self.project[“id”]})

Does anything here look out of the ordinary?

If I use tk-desktop as the engine I will get this error:

"Looks like you are trying to run an App that uses a QT based UI, however the "

ank.errors.TankError: Looks like you are trying to run an App that uses a QT based UI, however the python installation that the Desktop engine is currently using does not seem to contain a valid PySide or PyQt4 install. Either install PySide into your python environment or alternatively switch back

to using the native Shotgun Desktop python installation, which includes full QT support.

What might be causing this to happen when it wouldn’t happen in the first instance? Let’s just say for the sake of argument that I’m using tk-desktop as the engine instead of what I mentioned before. That was just me trying a test.

If you could advise an approach to bootstrapping or creating a means of using this without a UI that would be great!


1 Like

Sorry for the barrage of questions!
So I think the easiest way to deal with this is to install Pyside to the deadline worker python installations. This is easily enough done and seems to fix the issue.

My current pipeline is to mount sgtk from a shared tk-core path on the network and let the engine bootstrap install the needed apps to the local users bundle_cache.

I think i’d prefer to use the local bundle_cache for toolkit and apps and I’ve set my code up to check for the existence of the bundle_cache before importing the shared toolkit.

My question is if there’s a way to get the project configs core_api version before importing the toolkit? I can assume what version of tk-core to add to that bundle_cache path but I’d rather let the configs drive this dynamically. If it were somehow stored in the pipeline configurations entity that would make it easily accessible. Right now I’m using my descriptor to point to a git repo where my configs live. Can I add an app store descriptor along with a git descriptor ie

If not is there an advised way of storing an api version? Add a new field to the pipeline configs entity?

Thanks again!


Hey @StarkRavenSimone!

So I talked this over with the team, and got confirmation on your hunch: your best bet is indeed to install Pyside on your render nodes if that’s possible.

As for the descriptor/core version question: have a look at the code snippet here – you’ll want to create a descriptor object for your pipeline config, then query the associated_core_descriptor property, which will return a dictionary that includes the core version from core_api.yml.

Hope that helps! Let us know if you have any other questions.

1 Like