mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Applications: Use prelaunch hooks to extract environments (#5387)
* ApplicationManager can have more granular way how applications are launched * executable is optional to be able create ApplicationLaunchContext * launch context can run prelaunch hooks without launching application * 'get_app_environments_for_context' is using launch context to prepare environments * added 'launch_type' as one of filtering options for LaunchHook * added 'local' launch type filter to existing launch hooks * define 'automated' launch type in remote publish function * modified publish and extract environments cli commands * launch types are only for local by default * fix import * fix launch types of global host data * change order or kwargs * change unreal filter attribute
This commit is contained in:
parent
55aead8470
commit
7e9f42b447
35 changed files with 266 additions and 152 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import os
|
||||
|
||||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class AddLastWorkfileToLaunchArgs(PreLaunchHook):
|
||||
|
|
@ -28,6 +28,7 @@ class AddLastWorkfileToLaunchArgs(PreLaunchHook):
|
|||
"substancepainter",
|
||||
"aftereffects"
|
||||
]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
if not self.data.get("start_last_workfile"):
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import os
|
||||
import shutil
|
||||
from openpype.lib import PreLaunchHook
|
||||
from openpype.settings import get_project_settings
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
from openpype.pipeline.workfile import (
|
||||
get_custom_workfile_template,
|
||||
get_custom_workfile_template_by_string_context
|
||||
|
|
@ -20,6 +20,7 @@ class CopyTemplateWorkfile(PreLaunchHook):
|
|||
# Before `AddLastWorkfileToLaunchArgs`
|
||||
order = 0
|
||||
app_groups = ["blender", "photoshop", "tvpaint", "aftereffects"]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
"""Check if can copy template for context and do it if possible.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import os
|
||||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
from openpype.pipeline.workfile import create_workdir_extra_folders
|
||||
|
||||
|
||||
|
|
@ -14,6 +14,7 @@ class CreateWorkdirExtraFolders(PreLaunchHook):
|
|||
|
||||
# Execute after workfile template copy
|
||||
order = 15
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
if not self.application.is_host:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import subprocess
|
||||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class LaunchFoundryAppsWindows(PreLaunchHook):
|
||||
|
|
@ -15,6 +15,7 @@ class LaunchFoundryAppsWindows(PreLaunchHook):
|
|||
order = 1000
|
||||
app_groups = ["nuke", "nukeassist", "nukex", "hiero", "nukestudio"]
|
||||
platforms = ["windows"]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
# Change `creationflags` to CREATE_NEW_CONSOLE
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from openpype.client import get_project, get_asset_by_name
|
||||
from openpype.lib import (
|
||||
from openpype.lib.applications import (
|
||||
PreLaunchHook,
|
||||
EnvironmentPrepData,
|
||||
prepare_app_environments,
|
||||
|
|
@ -10,6 +10,7 @@ from openpype.pipeline import Anatomy
|
|||
|
||||
class GlobalHostDataHook(PreLaunchHook):
|
||||
order = -100
|
||||
launch_types = set()
|
||||
|
||||
def execute(self):
|
||||
"""Prepare global objects to `data` that will be used for sure."""
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import os
|
||||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class LaunchWithTerminal(PreLaunchHook):
|
||||
|
|
@ -13,6 +13,7 @@ class LaunchWithTerminal(PreLaunchHook):
|
|||
order = 1000
|
||||
|
||||
platforms = ["darwin"]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
executable = str(self.launch_context.executable)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import os
|
||||
|
||||
from openpype.lib import (
|
||||
from openpype.lib import get_openpype_execute_args
|
||||
from openpype.lib.applications import (
|
||||
get_non_python_host_kwargs,
|
||||
PreLaunchHook,
|
||||
get_openpype_execute_args
|
||||
LaunchTypes,
|
||||
)
|
||||
from openpype.lib.applications import get_non_python_host_kwargs
|
||||
|
||||
from openpype import PACKAGE_DIR as OPENPYPE_DIR
|
||||
|
||||
|
|
@ -19,6 +20,7 @@ class NonPythonHostHook(PreLaunchHook):
|
|||
app_groups = ["harmony", "photoshop", "aftereffects"]
|
||||
|
||||
order = 20
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
# Pop executable
|
||||
|
|
@ -54,4 +56,3 @@ class NonPythonHostHook(PreLaunchHook):
|
|||
|
||||
self.launch_context.kwargs = \
|
||||
get_non_python_host_kwargs(self.launch_context.kwargs)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ class OCIOEnvHook(PreLaunchHook):
|
|||
"hiero",
|
||||
"resolve"
|
||||
]
|
||||
launch_types = set()
|
||||
|
||||
def execute(self):
|
||||
"""Hook entry method."""
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from pathlib import Path
|
||||
|
||||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class AddPythonScriptToLaunchArgs(PreLaunchHook):
|
||||
|
|
@ -8,9 +8,8 @@ class AddPythonScriptToLaunchArgs(PreLaunchHook):
|
|||
|
||||
# Append after file argument
|
||||
order = 15
|
||||
app_groups = [
|
||||
"blender",
|
||||
]
|
||||
app_groups = {"blender"}
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
if not self.launch_context.data.get("python_scripts"):
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import os
|
|||
import re
|
||||
import subprocess
|
||||
from platform import system
|
||||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class InstallPySideToBlender(PreLaunchHook):
|
||||
|
|
@ -16,7 +16,8 @@ class InstallPySideToBlender(PreLaunchHook):
|
|||
blender's python packages.
|
||||
"""
|
||||
|
||||
app_groups = ["blender"]
|
||||
app_groups = {"blender"}
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
# Prelaunch hook is not crucial
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import subprocess
|
||||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class BlenderConsoleWindows(PreLaunchHook):
|
||||
|
|
@ -15,6 +15,7 @@ class BlenderConsoleWindows(PreLaunchHook):
|
|||
order = 1000
|
||||
app_groups = ["blender"]
|
||||
platforms = ["windows"]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
# Change `creationflags` to CREATE_NEW_CONSOLE
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ import os
|
|||
import shutil
|
||||
import winreg
|
||||
import subprocess
|
||||
from openpype.lib import PreLaunchHook, get_openpype_execute_args
|
||||
from openpype.lib import get_openpype_execute_args
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
from openpype.hosts.celaction import scripts
|
||||
|
||||
CELACTION_SCRIPTS_DIR = os.path.dirname(
|
||||
|
|
@ -16,6 +17,7 @@ class CelactionPrelaunchHook(PreLaunchHook):
|
|||
"""
|
||||
app_groups = ["celaction"]
|
||||
platforms = ["windows"]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
asset_doc = self.data["asset_doc"]
|
||||
|
|
|
|||
|
|
@ -6,13 +6,10 @@ import socket
|
|||
from pprint import pformat
|
||||
|
||||
from openpype.lib import (
|
||||
PreLaunchHook,
|
||||
get_openpype_username,
|
||||
run_subprocess,
|
||||
)
|
||||
from openpype.lib.applications import (
|
||||
ApplicationLaunchFailed
|
||||
)
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
from openpype.hosts import flame as opflame
|
||||
|
||||
|
||||
|
|
@ -27,6 +24,7 @@ class FlamePrelaunch(PreLaunchHook):
|
|||
|
||||
wtc_script_path = os.path.join(
|
||||
opflame.HOST_DIR, "api", "scripts", "wiretap_com.py")
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -2,12 +2,16 @@ import os
|
|||
import shutil
|
||||
import platform
|
||||
from pathlib import Path
|
||||
from openpype.lib import PreLaunchHook, ApplicationLaunchFailed
|
||||
from openpype.hosts.fusion import (
|
||||
FUSION_HOST_DIR,
|
||||
FUSION_VERSIONS_DICT,
|
||||
get_fusion_version,
|
||||
)
|
||||
from openpype.lib.applications import (
|
||||
PreLaunchHook,
|
||||
LaunchTypes,
|
||||
ApplicationLaunchFailed,
|
||||
)
|
||||
|
||||
|
||||
class FusionCopyPrefsPrelaunch(PreLaunchHook):
|
||||
|
|
@ -23,6 +27,7 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook):
|
|||
|
||||
app_groups = ["fusion"]
|
||||
order = 2
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def get_fusion_profile_name(self, profile_version) -> str:
|
||||
# Returns 'Default', unless FUSION16_PROFILE is set
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import os
|
||||
from openpype.lib import PreLaunchHook, ApplicationLaunchFailed
|
||||
from openpype.lib.applications import (
|
||||
PreLaunchHook,
|
||||
LaunchTypes,
|
||||
ApplicationLaunchFailed,
|
||||
)
|
||||
from openpype.hosts.fusion import (
|
||||
FUSION_HOST_DIR,
|
||||
FUSION_VERSIONS_DICT,
|
||||
|
|
@ -19,6 +23,7 @@ class FusionPrelaunch(PreLaunchHook):
|
|||
|
||||
app_groups = ["fusion"]
|
||||
order = 1
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
# making sure python 3 is installed at provided path
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class SetPath(PreLaunchHook):
|
||||
|
|
@ -7,6 +7,7 @@ class SetPath(PreLaunchHook):
|
|||
Hook `GlobalHostDataHook` must be executed before this hook.
|
||||
"""
|
||||
app_groups = ["houdini"]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
workdir = self.launch_context.env.get("AVALON_WORKDIR", "")
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Pre-launch to force 3ds max startup script."""
|
||||
from openpype.lib import PreLaunchHook
|
||||
import os
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class ForceStartupScript(PreLaunchHook):
|
||||
|
|
@ -15,6 +15,7 @@ class ForceStartupScript(PreLaunchHook):
|
|||
"""
|
||||
app_groups = ["3dsmax"]
|
||||
order = 11
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
startup_args = [
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Pre-launch hook to inject python environment."""
|
||||
from openpype.lib import PreLaunchHook
|
||||
import os
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class InjectPythonPath(PreLaunchHook):
|
||||
|
|
@ -14,6 +14,7 @@ class InjectPythonPath(PreLaunchHook):
|
|||
Hook `GlobalHostDataHook` must be executed before this hook.
|
||||
"""
|
||||
app_groups = ["3dsmax"]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
self.launch_context.env["MAX_PYTHONPATH"] = os.environ["PYTHONPATH"]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class SetPath(PreLaunchHook):
|
||||
|
|
@ -7,6 +7,7 @@ class SetPath(PreLaunchHook):
|
|||
Hook `GlobalHostDataHook` must be executed before this hook.
|
||||
"""
|
||||
app_groups = ["max"]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
workdir = self.launch_context.env.get("AVALON_WORKDIR", "")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class MayaPreAutoLoadPlugins(PreLaunchHook):
|
||||
|
|
@ -7,6 +7,7 @@ class MayaPreAutoLoadPlugins(PreLaunchHook):
|
|||
# Before AddLastWorkfileToLaunchArgs
|
||||
order = 9
|
||||
app_groups = ["maya"]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
from openpype.hosts.maya.lib import create_workspace_mel
|
||||
|
||||
|
||||
|
|
@ -8,6 +8,7 @@ class PreCopyMel(PreLaunchHook):
|
|||
Hook `GlobalHostDataHook` must be executed before this hook.
|
||||
"""
|
||||
app_groups = ["maya"]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
project_doc = self.data["project_doc"]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class MayaPreOpenWorkfilePostInitialization(PreLaunchHook):
|
||||
|
|
@ -7,6 +7,7 @@ class MayaPreOpenWorkfilePostInitialization(PreLaunchHook):
|
|||
# Before AddLastWorkfileToLaunchArgs.
|
||||
order = 9
|
||||
app_groups = ["maya"]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook
|
||||
|
||||
|
||||
class PrelaunchNukeAssistHook(PreLaunchHook):
|
||||
|
|
@ -6,6 +6,7 @@ class PrelaunchNukeAssistHook(PreLaunchHook):
|
|||
Adding flag when nukeassist
|
||||
"""
|
||||
app_groups = ["nukeassist"]
|
||||
launch_types = set()
|
||||
|
||||
def execute(self):
|
||||
self.launch_context.env["NUKEASSIST"] = "1"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import os
|
||||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class PreLaunchResolveLastWorkfile(PreLaunchHook):
|
||||
|
|
@ -10,6 +10,7 @@ class PreLaunchResolveLastWorkfile(PreLaunchHook):
|
|||
"""
|
||||
order = 10
|
||||
app_groups = ["resolve"]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
if not self.data.get("start_last_workfile"):
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import os
|
||||
from pathlib import Path
|
||||
import platform
|
||||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
from openpype.hosts.resolve.utils import setup
|
||||
|
||||
|
||||
|
|
@ -31,6 +31,7 @@ class PreLaunchResolveSetup(PreLaunchHook):
|
|||
"""
|
||||
|
||||
app_groups = ["resolve"]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
current_platform = platform.system().lower()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import os
|
||||
|
||||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
import openpype.hosts.resolve
|
||||
|
||||
|
||||
|
|
@ -10,6 +10,7 @@ class PreLaunchResolveStartup(PreLaunchHook):
|
|||
"""
|
||||
order = 11
|
||||
app_groups = ["resolve"]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
# Set the openpype prelaunch startup script path for easy access
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
from openpype.lib import (
|
||||
PreLaunchHook,
|
||||
get_openpype_execute_args
|
||||
)
|
||||
from openpype.lib import get_openpype_execute_args
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class TvpaintPrelaunchHook(PreLaunchHook):
|
||||
|
|
@ -14,6 +12,7 @@ class TvpaintPrelaunchHook(PreLaunchHook):
|
|||
to copy templated workfile from predefined path.
|
||||
"""
|
||||
app_groups = ["tvpaint"]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
# Pop tvpaint executable
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@ from pathlib import Path
|
|||
from qtpy import QtCore
|
||||
|
||||
from openpype import resources
|
||||
from openpype.lib import (
|
||||
from openpype.lib.applications import (
|
||||
PreLaunchHook,
|
||||
ApplicationLaunchFailed,
|
||||
LaunchTypes,
|
||||
)
|
||||
from openpype.pipeline.workfile import get_workfile_template_key
|
||||
import openpype.hosts.unreal.lib as unreal_lib
|
||||
|
|
@ -29,6 +30,8 @@ class UnrealPrelaunchHook(PreLaunchHook):
|
|||
shell script.
|
||||
|
||||
"""
|
||||
app_groups = {"unreal"}
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import pyblish.util
|
|||
from openpype.lib import Logger
|
||||
from openpype.lib.applications import (
|
||||
ApplicationManager,
|
||||
get_app_environments_for_context,
|
||||
LaunchTypes,
|
||||
)
|
||||
from openpype.pipeline import install_host
|
||||
from openpype.hosts.webpublisher.api import WebpublisherHost
|
||||
|
|
@ -156,22 +156,31 @@ def cli_publish_from_app(
|
|||
found_variant_key = find_variant_key(application_manager, host_name)
|
||||
app_name = "{}/{}".format(host_name, found_variant_key)
|
||||
|
||||
data = {
|
||||
"last_workfile_path": workfile_path,
|
||||
"start_last_workfile": True,
|
||||
"project_name": project_name,
|
||||
"asset_name": asset_name,
|
||||
"task_name": task_name,
|
||||
"launch_type": LaunchTypes.automated,
|
||||
}
|
||||
launch_context = application_manager.create_launch_context(
|
||||
app_name, **data)
|
||||
launch_context.run_prelaunch_hooks()
|
||||
|
||||
# must have for proper launch of app
|
||||
env = get_app_environments_for_context(
|
||||
project_name,
|
||||
asset_name,
|
||||
task_name,
|
||||
app_name
|
||||
)
|
||||
env = launch_context.env
|
||||
print("env:: {}".format(env))
|
||||
env["OPENPYPE_PUBLISH_DATA"] = batch_path
|
||||
# must pass identifier to update log lines for a batch
|
||||
env["BATCH_LOG_ID"] = str(_id)
|
||||
env["HEADLESS_PUBLISH"] = 'true' # to use in app lib
|
||||
env["USER_EMAIL"] = user_email
|
||||
|
||||
os.environ.update(env)
|
||||
|
||||
os.environ["OPENPYPE_PUBLISH_DATA"] = batch_path
|
||||
# must pass identifier to update log lines for a batch
|
||||
os.environ["BATCH_LOG_ID"] = str(_id)
|
||||
os.environ["HEADLESS_PUBLISH"] = 'true' # to use in app lib
|
||||
os.environ["USER_EMAIL"] = user_email
|
||||
|
||||
# Why is this here? Registered host in this process does not affect
|
||||
# regitered host in launched process.
|
||||
pyblish.api.register_host(host_name)
|
||||
if targets:
|
||||
if isinstance(targets, str):
|
||||
|
|
@ -184,15 +193,7 @@ def cli_publish_from_app(
|
|||
os.environ["PYBLISH_TARGETS"] = os.pathsep.join(
|
||||
set(current_targets))
|
||||
|
||||
data = {
|
||||
"last_workfile_path": workfile_path,
|
||||
"start_last_workfile": True,
|
||||
"project_name": project_name,
|
||||
"asset_name": asset_name,
|
||||
"task_name": task_name
|
||||
}
|
||||
|
||||
launched_app = application_manager.launch(app_name, **data)
|
||||
launched_app = application_manager.launch_with_context(launch_context)
|
||||
|
||||
timeout = get_timeout(project_name, host_name, task_type)
|
||||
|
||||
|
|
|
|||
|
|
@ -12,10 +12,6 @@ from abc import ABCMeta, abstractmethod
|
|||
import six
|
||||
|
||||
from openpype import AYON_SERVER_ENABLED, PACKAGE_DIR
|
||||
from openpype.client import (
|
||||
get_project,
|
||||
get_asset_by_name,
|
||||
)
|
||||
from openpype.settings import (
|
||||
get_system_settings,
|
||||
get_project_settings,
|
||||
|
|
@ -47,6 +43,25 @@ CUSTOM_LAUNCH_APP_GROUPS = {
|
|||
}
|
||||
|
||||
|
||||
class LaunchTypes:
|
||||
"""Launch types are filters for pre/post-launch hooks.
|
||||
|
||||
Please use these variables in case they'll change values.
|
||||
"""
|
||||
|
||||
# Local launch - application is launched on local machine
|
||||
local = "local"
|
||||
# Farm render job - application is on farm
|
||||
farm_render = "farm-render"
|
||||
# Farm publish job - integration post-render job
|
||||
farm_publish = "farm-publish"
|
||||
# Remote launch - application is launched on remote machine from which
|
||||
# can be started publishing
|
||||
remote = "remote"
|
||||
# Automated launch - application is launched with automated publishing
|
||||
automated = "automated"
|
||||
|
||||
|
||||
def parse_environments(env_data, env_group=None, platform_name=None):
|
||||
"""Parse environment values from settings byt group and platform.
|
||||
|
||||
|
|
@ -483,6 +498,42 @@ class ApplicationManager:
|
|||
break
|
||||
return output
|
||||
|
||||
def create_launch_context(self, app_name, **data):
|
||||
"""Prepare launch context for application.
|
||||
|
||||
Args:
|
||||
app_name (str): Name of application that should be launched.
|
||||
**data (Any): Any additional data. Data may be used during
|
||||
|
||||
Returns:
|
||||
ApplicationLaunchContext: Launch context for application.
|
||||
|
||||
Raises:
|
||||
ApplicationNotFound: Application was not found by entered name.
|
||||
"""
|
||||
|
||||
app = self.applications.get(app_name)
|
||||
if not app:
|
||||
raise ApplicationNotFound(app_name)
|
||||
|
||||
executable = app.find_executable()
|
||||
|
||||
return ApplicationLaunchContext(
|
||||
app, executable, **data
|
||||
)
|
||||
|
||||
def launch_with_context(self, launch_context):
|
||||
"""Launch application using existing launch context.
|
||||
|
||||
Args:
|
||||
launch_context (ApplicationLaunchContext): Prepared launch
|
||||
context.
|
||||
"""
|
||||
|
||||
if not launch_context.executable:
|
||||
raise ApplictionExecutableNotFound(launch_context.application)
|
||||
return launch_context.launch()
|
||||
|
||||
def launch(self, app_name, **data):
|
||||
"""Launch procedure.
|
||||
|
||||
|
|
@ -503,18 +554,10 @@ class ApplicationManager:
|
|||
failed. Exception should contain explanation message,
|
||||
traceback should not be needed.
|
||||
"""
|
||||
app = self.applications.get(app_name)
|
||||
if not app:
|
||||
raise ApplicationNotFound(app_name)
|
||||
|
||||
executable = app.find_executable()
|
||||
if not executable:
|
||||
raise ApplictionExecutableNotFound(app)
|
||||
context = self.create_launch_context(app_name, **data)
|
||||
return self.launch_with_context(context)
|
||||
|
||||
context = ApplicationLaunchContext(
|
||||
app, executable, **data
|
||||
)
|
||||
return context.launch()
|
||||
|
||||
|
||||
class EnvironmentToolGroup:
|
||||
|
|
@ -736,13 +779,17 @@ class LaunchHook:
|
|||
# Order of prelaunch hook, will be executed as last if set to None.
|
||||
order = None
|
||||
# List of host implementations, skipped if empty.
|
||||
hosts = []
|
||||
# List of application groups
|
||||
app_groups = []
|
||||
# List of specific application names
|
||||
app_names = []
|
||||
# List of platform availability, skipped if empty.
|
||||
platforms = []
|
||||
hosts = set()
|
||||
# Set of application groups
|
||||
app_groups = set()
|
||||
# Set of specific application names
|
||||
app_names = set()
|
||||
# Set of platform availability
|
||||
platforms = set()
|
||||
# Set of launch types for which is available
|
||||
# - if empty then is available for all launch types
|
||||
# - by default has 'local' which is most common reason for launc hooks
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def __init__(self, launch_context):
|
||||
"""Constructor of launch hook.
|
||||
|
|
@ -790,6 +837,10 @@ class LaunchHook:
|
|||
if launch_context.app_name not in cls.app_names:
|
||||
return False
|
||||
|
||||
if cls.launch_types:
|
||||
if launch_context.launch_type not in cls.launch_types:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@property
|
||||
|
|
@ -859,9 +910,9 @@ class PostLaunchHook(LaunchHook):
|
|||
class ApplicationLaunchContext:
|
||||
"""Context of launching application.
|
||||
|
||||
Main purpose of context is to prepare launch arguments and keyword arguments
|
||||
for new process. Most important part of keyword arguments preparations
|
||||
are environment variables.
|
||||
Main purpose of context is to prepare launch arguments and keyword
|
||||
arguments for new process. Most important part of keyword arguments
|
||||
preparations are environment variables.
|
||||
|
||||
During the whole process is possible to use `data` attribute to store
|
||||
object usable in multiple places.
|
||||
|
|
@ -874,14 +925,30 @@ class ApplicationLaunchContext:
|
|||
insert argument between `nuke.exe` and `--NukeX`. To keep them together
|
||||
it is better to wrap them in another list: `[["nuke.exe", "--NukeX"]]`.
|
||||
|
||||
Notes:
|
||||
It is possible to use launch context only to prepare environment
|
||||
variables. In that case `executable` may be None and can be used
|
||||
'run_prelaunch_hooks' method to run prelaunch hooks which prepare
|
||||
them.
|
||||
|
||||
Args:
|
||||
application (Application): Application definition.
|
||||
executable (ApplicationExecutable): Object with path to executable.
|
||||
env_group (Optional[str]): Environment variable group. If not set
|
||||
'DEFAULT_ENV_SUBGROUP' is used.
|
||||
launch_type (Optional[str]): Launch type. If not set 'local' is used.
|
||||
**data (dict): Any additional data. Data may be used during
|
||||
preparation to store objects usable in multiple places.
|
||||
"""
|
||||
|
||||
def __init__(self, application, executable, env_group=None, **data):
|
||||
def __init__(
|
||||
self,
|
||||
application,
|
||||
executable,
|
||||
env_group=None,
|
||||
launch_type=None,
|
||||
**data
|
||||
):
|
||||
from openpype.modules import ModulesManager
|
||||
|
||||
# Application object
|
||||
|
|
@ -896,6 +963,10 @@ class ApplicationLaunchContext:
|
|||
|
||||
self.executable = executable
|
||||
|
||||
if launch_type is None:
|
||||
launch_type = LaunchTypes.local
|
||||
self.launch_type = launch_type
|
||||
|
||||
if env_group is None:
|
||||
env_group = DEFAULT_ENV_SUBGROUP
|
||||
|
||||
|
|
@ -903,8 +974,11 @@ class ApplicationLaunchContext:
|
|||
|
||||
self.data = dict(data)
|
||||
|
||||
launch_args = []
|
||||
if executable is not None:
|
||||
launch_args = executable.as_args()
|
||||
# subprocess.Popen launch arguments (first argument in constructor)
|
||||
self.launch_args = executable.as_args()
|
||||
self.launch_args = launch_args
|
||||
self.launch_args.extend(application.arguments)
|
||||
if self.data.get("app_args"):
|
||||
self.launch_args.extend(self.data.pop("app_args"))
|
||||
|
|
@ -946,6 +1020,7 @@ class ApplicationLaunchContext:
|
|||
self.postlaunch_hooks = None
|
||||
|
||||
self.process = None
|
||||
self._prelaunch_hooks_executed = False
|
||||
|
||||
@property
|
||||
def env(self):
|
||||
|
|
@ -1215,6 +1290,27 @@ class ApplicationLaunchContext:
|
|||
# Return process which is already terminated
|
||||
return process
|
||||
|
||||
def run_prelaunch_hooks(self):
|
||||
"""Run prelaunch hooks.
|
||||
|
||||
This method will be executed only once, any future calls will skip
|
||||
the processing.
|
||||
"""
|
||||
|
||||
if self._prelaunch_hooks_executed:
|
||||
self.log.warning("Prelaunch hooks were already executed.")
|
||||
return
|
||||
# Discover launch hooks
|
||||
self.discover_launch_hooks()
|
||||
|
||||
# Execute prelaunch hooks
|
||||
for prelaunch_hook in self.prelaunch_hooks:
|
||||
self.log.debug("Executing prelaunch hook: {}".format(
|
||||
str(prelaunch_hook.__class__.__name__)
|
||||
))
|
||||
prelaunch_hook.execute()
|
||||
self._prelaunch_hooks_executed = True
|
||||
|
||||
def launch(self):
|
||||
"""Collect data for new process and then create it.
|
||||
|
||||
|
|
@ -1227,15 +1323,8 @@ class ApplicationLaunchContext:
|
|||
self.log.warning("Application was already launched.")
|
||||
return
|
||||
|
||||
# Discover launch hooks
|
||||
self.discover_launch_hooks()
|
||||
|
||||
# Execute prelaunch hooks
|
||||
for prelaunch_hook in self.prelaunch_hooks:
|
||||
self.log.debug("Executing prelaunch hook: {}".format(
|
||||
str(prelaunch_hook.__class__.__name__)
|
||||
))
|
||||
prelaunch_hook.execute()
|
||||
if not self._prelaunch_hooks_executed:
|
||||
self.run_prelaunch_hooks()
|
||||
|
||||
self.log.debug("All prelaunch hook executed. Starting new process.")
|
||||
|
||||
|
|
@ -1353,6 +1442,7 @@ def get_app_environments_for_context(
|
|||
task_name,
|
||||
app_name,
|
||||
env_group=None,
|
||||
launch_type=None,
|
||||
env=None,
|
||||
modules_manager=None
|
||||
):
|
||||
|
|
@ -1363,54 +1453,33 @@ def get_app_environments_for_context(
|
|||
task_name (str): Name of task.
|
||||
app_name (str): Name of application that is launched and can be found
|
||||
by ApplicationManager.
|
||||
env (dict): Initial environment variables. `os.environ` is used when
|
||||
not passed.
|
||||
modules_manager (ModulesManager): Initialized modules manager.
|
||||
env_group (Optional[str]): Name of environment group. If not passed
|
||||
default group is used.
|
||||
launch_type (Optional[str]): Type for which prelaunch hooks are
|
||||
executed.
|
||||
env (Optional[dict[str, str]]): Initial environment variables.
|
||||
`os.environ` is used when not passed.
|
||||
modules_manager (Optional[ModulesManager]): Initialized modules
|
||||
manager.
|
||||
|
||||
Returns:
|
||||
dict: Environments for passed context and application.
|
||||
"""
|
||||
|
||||
from openpype.modules import ModulesManager
|
||||
from openpype.pipeline import Anatomy
|
||||
from openpype.lib.openpype_version import is_running_staging
|
||||
|
||||
# Project document
|
||||
project_doc = get_project(project_name)
|
||||
asset_doc = get_asset_by_name(project_name, asset_name)
|
||||
|
||||
if modules_manager is None:
|
||||
modules_manager = ModulesManager()
|
||||
|
||||
# Prepare app object which can be obtained only from ApplciationManager
|
||||
# Prepare app object which can be obtained only from ApplicationManager
|
||||
app_manager = ApplicationManager()
|
||||
app = app_manager.applications[app_name]
|
||||
|
||||
# Project's anatomy
|
||||
anatomy = Anatomy(project_name)
|
||||
|
||||
data = EnvironmentPrepData({
|
||||
"project_name": project_name,
|
||||
"asset_name": asset_name,
|
||||
"task_name": task_name,
|
||||
|
||||
"app": app,
|
||||
|
||||
"project_doc": project_doc,
|
||||
"asset_doc": asset_doc,
|
||||
|
||||
"anatomy": anatomy,
|
||||
|
||||
"env": env
|
||||
})
|
||||
data["env"].update(anatomy.root_environments())
|
||||
if is_running_staging():
|
||||
data["env"]["OPENPYPE_IS_STAGING"] = "1"
|
||||
|
||||
prepare_app_environments(data, env_group, modules_manager)
|
||||
prepare_context_environments(data, env_group, modules_manager)
|
||||
|
||||
return data["env"]
|
||||
context = app_manager.create_launch_context(
|
||||
app_name,
|
||||
project_name=project_name,
|
||||
asset_name=asset_name,
|
||||
task_name=task_name,
|
||||
env_group=env_group,
|
||||
launch_type=launch_type,
|
||||
env=env,
|
||||
modules_manager=modules_manager,
|
||||
)
|
||||
context.run_prelaunch_hooks()
|
||||
return context.env
|
||||
|
||||
|
||||
def _merge_env(env, current_env):
|
||||
|
|
|
|||
|
|
@ -2,11 +2,12 @@ import os
|
|||
|
||||
import ftrack_api
|
||||
from openpype.settings import get_project_settings
|
||||
from openpype.lib import PostLaunchHook
|
||||
from openpype.lib.applications import PostLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class PostFtrackHook(PostLaunchHook):
|
||||
order = None
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
project_name = self.data.get("project_name")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import os
|
||||
from openpype.lib import PreLaunchHook
|
||||
from openpype.lib.applications import PreLaunchHook
|
||||
from openpype_modules.slack import SLACK_MODULE_DIR
|
||||
|
||||
|
||||
|
|
@ -8,6 +8,7 @@ class PrePython2Support(PreLaunchHook):
|
|||
|
||||
Path to vendor modules is added to the beginning of PYTHONPATH.
|
||||
"""
|
||||
launch_types = set()
|
||||
|
||||
def execute(self):
|
||||
if not self.application.use_python_2:
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
import os
|
||||
import shutil
|
||||
|
||||
from openpype.client.entities import (
|
||||
get_representations,
|
||||
get_project
|
||||
)
|
||||
|
||||
from openpype.lib import PreLaunchHook
|
||||
from openpype.client.entities import get_representations
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
from openpype.lib.profiles_filtering import filter_profiles
|
||||
from openpype.modules.sync_server.sync_server import (
|
||||
download_last_published_workfile,
|
||||
|
|
@ -32,6 +28,7 @@ class CopyLastPublishedWorkfile(PreLaunchHook):
|
|||
"nuke", "nukeassist", "nukex", "hiero", "nukestudio",
|
||||
"maya", "harmony", "celaction", "flame", "fusion",
|
||||
"houdini", "tvpaint"]
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
"""Check if local workfile doesn't exist, else copy it.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from openpype.lib import PostLaunchHook
|
||||
from openpype.lib.applications import PostLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class PostStartTimerHook(PostLaunchHook):
|
||||
|
|
@ -7,6 +7,7 @@ class PostStartTimerHook(PostLaunchHook):
|
|||
This module requires enabled TimerManager module.
|
||||
"""
|
||||
order = None
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
project_name = self.data.get("project_name")
|
||||
|
|
|
|||
|
|
@ -88,7 +88,10 @@ class PypeCommands:
|
|||
"""
|
||||
|
||||
from openpype.lib import Logger
|
||||
from openpype.lib.applications import get_app_environments_for_context
|
||||
from openpype.lib.applications import (
|
||||
get_app_environments_for_context,
|
||||
LaunchTypes,
|
||||
)
|
||||
from openpype.modules import ModulesManager
|
||||
from openpype.pipeline import (
|
||||
install_openpype_plugins,
|
||||
|
|
@ -122,7 +125,8 @@ class PypeCommands:
|
|||
context["project_name"],
|
||||
context["asset_name"],
|
||||
context["task_name"],
|
||||
app_full_name
|
||||
app_full_name,
|
||||
launch_type=LaunchTypes.farm_publish,
|
||||
)
|
||||
os.environ.update(env)
|
||||
|
||||
|
|
@ -237,11 +241,19 @@ class PypeCommands:
|
|||
Called by Deadline plugin to propagate environment into render jobs.
|
||||
"""
|
||||
|
||||
from openpype.lib.applications import get_app_environments_for_context
|
||||
from openpype.lib.applications import (
|
||||
get_app_environments_for_context,
|
||||
LaunchTypes,
|
||||
)
|
||||
|
||||
if all((project, asset, task, app)):
|
||||
env = get_app_environments_for_context(
|
||||
project, asset, task, app, env_group
|
||||
project,
|
||||
asset,
|
||||
task,
|
||||
app,
|
||||
env_group=env_group,
|
||||
launch_type=LaunchTypes.farm_render,
|
||||
)
|
||||
else:
|
||||
env = os.environ.copy()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue