11import logging
22import sys
3- from typing import Any , Dict , Optional
3+ from typing import TYPE_CHECKING , Any , Dict , List , Optional
44
55from dagster import _check as check
66from dagster ._cli .api import ExecuteRunArgs # type: ignore
1212from dagster ._grpc .types import ResumeRunArgs
1313from dagster ._serdes import ConfigurableClass , ConfigurableClassData
1414from dagster ._utils .error import serializable_error_info_from_exc_info
15+ from pydantic import Field
1516
1617from dagster_ray .config import RayExecutionConfig , RayJobSubmissionClientConfig
18+ from dagster_ray .utils import resolve_env_vars_list
19+
20+ if TYPE_CHECKING :
21+ from ray .job_submission import JobSubmissionClient
1722
1823
1924def get_job_submission_id_from_run_id (run_id : str , resume_attempt_number = None ):
2025 return f"dagster-run-{ run_id } " + ("" if not resume_attempt_number else f"-{ resume_attempt_number } " )
2126
2227
23- class RayLauncherConfig (RayExecutionConfig , RayJobSubmissionClientConfig ): ...
28+ class RayLauncherConfig (RayExecutionConfig , RayJobSubmissionClientConfig ):
29+ env_vars : Optional [List [str ]] = Field (
30+ default = None ,
31+ description = "A list of environment variables to inject into the Job. Each can be of the form KEY=VALUE or just KEY (in which case the value will be pulled from the current process)." ,
32+ )
2433
2534
2635class RayRunLauncher (RunLauncher , ConfigurableClass ):
@@ -30,6 +39,7 @@ def __init__(
3039 metadata : Optional [Dict [str , Any ]] = None ,
3140 headers : Optional [Dict [str , Any ]] = None ,
3241 cookies : Optional [Dict [str , Any ]] = None ,
42+ env_vars : Optional [List [str ]] = None ,
3343 runtime_env : Optional [Dict [str , Any ]] = None ,
3444 num_cpus : Optional [int ] = None ,
3545 num_gpus : Optional [int ] = None ,
@@ -55,17 +65,13 @@ def __init__(
5565 Fields such as `num_cpus` set via `dagster-ray/config` Run tag will override the yaml configuration.
5666
5767 """
58-
59- from ray .job_submission import JobSubmissionClient
60-
6168 self ._inst_data = check .opt_inst_param (inst_data , "inst_data" , ConfigurableClassData )
6269
63- self .client = JobSubmissionClient (address , metadata = metadata , headers = headers , cookies = cookies )
64-
6570 self .address = address
6671 self .metadata = metadata
6772 self .headers = headers
6873 self .cookies = cookies
74+ self .env_vars = env_vars
6975 self .runtime_env = runtime_env
7076 self .num_cpus = num_cpus
7177 self .num_gpus = num_gpus
@@ -74,17 +80,23 @@ def __init__(
7480
7581 super ().__init__ ()
7682
83+ @property
84+ def client (self ) -> "JobSubmissionClient" : # note: this must be a property
85+ from ray .job_submission import JobSubmissionClient
86+
87+ return JobSubmissionClient (self .address , metadata = self .metadata , headers = self .headers , cookies = self .cookies )
88+
7789 @property
7890 def inst_data (self ) -> Optional [ConfigurableClassData ]:
7991 return self ._inst_data
8092
8193 @classmethod
8294 def config_type (cls ) -> UserConfigSchema :
83- return RayLauncherConfig .to_fields_dict ()
95+ return { "ray" : RayLauncherConfig .to_config_schema (). as_field ()}
8496
8597 @classmethod
8698 def from_config_value (cls , inst_data , config_value ):
87- return cls (inst_data = inst_data , ** config_value )
99+ return cls (inst_data = inst_data , ** config_value [ "ray" ] )
88100
89101 @property
90102 def supports_resume_run (self ):
@@ -132,13 +144,16 @@ def _launch_ray_job(self, submission_id: str, entrypoint: str, run: DagsterRun):
132144
133145 cfg_from_tags = RayLauncherConfig .from_tags (run .tags )
134146
135- runtime_env = cfg_from_tags .runtime_env or self .runtime_env or {}
147+ env_vars = cfg_from_tags .env_vars or self .env_vars or []
148+ # note! ray modifies the user-provided runtime_env, so we copy it
149+ runtime_env = (cfg_from_tags .runtime_env or self .runtime_env or {}).copy ()
136150 num_cpus = cfg_from_tags .num_cpus or self .num_cpus
137151 num_gpus = cfg_from_tags .num_gpus or self .num_gpus
138152 memory = cfg_from_tags .memory or self .memory
139153 resources = cfg_from_tags .resources or self .resources
140154
141155 runtime_env ["env_vars" ] = runtime_env .get ("env_vars" , {})
156+ runtime_env ["env_vars" ].update (resolve_env_vars_list (env_vars ))
142157 runtime_env ["env_vars" ].update (
143158 {
144159 "DAGSTER_RUN_JOB_NAME" : job_origin .job_name ,
0 commit comments