어떻게 하면 shotgunEvents 데몬을 사용하여 다른 Toolkit Core 모듈을 로드할 수 있습니까?

이 정보를 공유해 준 Benoit Leveau @ Milk VFX에게 깊이 감사드립니다.

문제

shotgunEvent 데몬을 사용 중인 경우 특정 이벤트에 대해서는 플러그인 내에서 툴킷 작업을 수행하고 싶을 수 있습니다. 하지만 Python은 모듈을 한 번만 가져오기 때문에 이렇게 하는 것은 위험할 수 있습니다. 따라서 프로젝트 A용 Toolkit Core API를 플러그인을 처음 실행할 때 가져오면 그 버전이 데몬의 사용 기간 동안 가져온 채로 유지되는 버전이 됩니다. 즉, 플러그인으로 발송된 다음 이벤트가 프로젝트 B의 이벤트인 경우 프로젝트 A용 Core API를 사용하여 프로젝트 B를 위한 새 툴킷 객체의 인스턴스화를 시도하면 툴킷에서 오류가 발생할 수 있습니다.

툴킷은 프로젝트를 중심으로 하기 때문에 프로젝트마다 서로 다른 버전의 Toolkit Core 및 구성을 가지게 됩니다. 이벤트가 생성된 프로젝트에 따라 올바른 툴킷 인스턴스를 생성하려면 다른 위치에서 다른 버전의 sgtk 모듈을 가져와야 할 수도 있습니다. 설명한 것처럼 기본적으로 Python은 모듈을 한 번만 가져옵니다. 따라서 sgtk 모듈의 새 위치를 가리키도록 sys.path를 수정하고 이를 가져오려고 한다고 해도 Python은 이를 이미 가져온 sgtk 모듈로 인식하여 바꾸지 않습니다. 그리고 이로 인해 Core API를 로드해 온 프로젝트와 다른 프로젝트에서 툴킷 작업을 수행하려고 하면 오류가 발생합니다.

예:

  • 이벤트 123은 프로젝트 A의 이벤트입니다.
  • 프로젝트 A의 Core API는 /mnt/toolkit/projectA/install/core/python에 위치합니다.
  • 이 디렉토리를 sys.path에 접두사로 붙입니다.
  • "import sgtk"가 이 위치에서 이 API를 가져옵니다.
  • 이 Core API로 툴킷 인스턴스를 인스턴스화하고 작업을 수행합니다.
  • Core API 디렉토리를 sys.path에서 분리합니다.
  • 이벤트 234는 프로젝트 B의 이벤트입니다.
  • 프로젝트 B의 Core API는 /mnt/toolkit/projectB/install/core/python에 위치합니다.
  • 이 디렉토리를 sys.path에 접두사로 붙입니다.
  • Python은 이를 이미 가져온 sgtk로 인식하기 때문에 "import sgtk"는 아무 동작도 하지 않습니다.
  • 이 Core API로 툴킷 인스턴스를 인스턴스화하고 작업을 수행합니다.
  • 툴킷 코어가 작업을 수행하려는 프로젝트 (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 댓글

댓글을 남기려면 로그인하세요.