shotgunEvent デーモンを使用してさまざまな Toolkit コア モジュールをロードするにはどうすればいいですか?

Benoit Leveau @ Milk VFX の協力に感謝します。

問題点

shotgunEvents デーモンを使用している場合、特定のイベントについてはプラグイン内で Toolkit のアクションを実行することができます。 これは、Python がモジュールを一度しか読み込まないため少々厄介です。 そのため、プロジェクト A の Toolkit Core API をプラグインの初回実行時に読み込む場合、このバージョンはデーモンの存続期間中読み込まれたままになります。 つまり、プラグインに割り当てられる次のイベントがプロジェクト B 用である場合、プロジェクト A の Core API を使用してプロジェクト B の新しい Toolkit オブジェクトのインスタンスを作成しようとすると、Toolkit にエラーが表示されます。

Toolkit はプロジェクトをベースにしているため、各プロジェクトには Toolkit コアと基本設定のさまざまなバージョンがあります。 イベントの生成元のプロジェクトに応じて、適切な Toolkit インスタンスを作成するために、さまざまな場所からさまざまなバージョンの sgtk モジュールを読み込む必要があります。 上述のとおり、Python は既定でモジュールを一度しか読み込みません。 そのため、sgtk モジュールの新しい場所を指定するように sys.path を修正して読み込んでみても、Python には既に読み込まれた sgtk が表示され、置き換えられません。 これにより、Core API のロード元のプロジェクトとは異なるプロジェクトで Toolkit アクションを実行するとエラーが発生します。

例:

  • イベント 123 はプロジェクト A 用である
  • プロジェクト A 用の Core API が /mnt/toolkit/projectA/install/core/python に配置されている
  • このディレクトリの先頭に sys.path を追加する
  • 「import sgtk」でこの場所から読み込む
  • この Core API を使用して Toolkit のインスタンスを作成していくつかのアクションを実行する
  • sys.path から Core API ディレクトリを取り出す
  • イベント 234 はプロジェクト B 用である
  • プロジェクト B 用の Core API が /mnt/toolkit/projectB/install/core/python に配置されている
  • このディレクトリの先頭に sys.path を追加する
  • Python に sgtk が既に読み込まれていると表示されるため、「import sgtk」は何も実行しない
  • この Core API を使用して Toolkit のインスタンスを作成していくつかのアクションを実行する
  • これにより、Toolkit コアがアクションの実行対象のプロジェクト(B)とは異なるプロジェクト(A)用であるため、エラーが発生します。

 

解決策

次の例では、異なるバージョンのモジュールが既に読み込まれている場合にスクリプトやプラグインで正しいバージョンの sgtk コアを読み込む一般的な方法を説明します。 元の読み込みのロードが解除され、Python のメモリから削除されるため、モジュールの新しいインスタンスを読み込んで適切に使用することができます。

"""
Example of how to import the correct sgtk core code in a script where
a different instance of the module may have already been imported. The
original import is unloaded and removed from memory in Python so the new
instance of the module can be imported and used successfully.
    
Thanks to Benoit Leveau @ Milk VFX for sharing this.
"""

import os
import sys


def import_sgtk(project):
    """
    Import and return the sgtk module related to a Project.
    This will check where the Core API is located on disk (in case it's localized or shared).
    It shouldn't be used to get several instances of the sgtk module at different places.
    This should be seen as a kind of 'reload(sgtk)' command.

:param project: (str) project name on disk for to import the Toolkit Core API for. """ # where all our pipeline configurations are located shotgun_base = os.getenv("SHOTGUN_BASE", "/mnt/sgtk/configs") # delete existing core modules in the environment for mod in filter(lambda mod: mod.startswith("tank") or mod.startswith("sgtk"), sys.modules): sys.modules.pop(mod) del mod # check which location to use to import the core python_subfolder = os.path.join("install", "core", "python") is_core_localized = os.path.exists(os.path.join(shotgun_base, project, "install", "core", "_core_upgrader.py")) if is_core_localized: # the core API is located inside the configuration core_python_path = os.path.join(shotgun_base, project, python_subfolder) else: # the core API can still be localized through the share_core/attach_to_core commands # so look in the core_Linux.cfg file which will give us the proper location (modify this # to match your primary platform) core_cfg = os.path.join(shotgun_base, project, "install", "core", "core_Linux.cfg") if os.path.exists(core_cfg): core_python_path = os.path.join(open(core_cfg).read(), python_subfolder) else: # use the studio default one # this assumes you have a shared studio core installed. # See https://support.shotgunsoftware.com/entries/96141707 core_python_path = os.path.join(shotgun_base, "studio", python_subfolder) # tweak sys.path to add the core API to the beginning so it will be picked up if sys.path[0] != "": sys.path.pop(0) sys.path = [core_python_path] + sys.path # now import the sgtk module, it should be found at the 'core_python_path' location above import sgtk return sgtk

 

フォローする

0 コメント

ログインしてコメントを残してください。