class_docstr: This class is used to define a runtime environment for a job, task,
  or actor.
  
  See :ref:`runtime-environments` for detailed documentation.
  
  This class can be used interchangeably with an unstructured dictionary
  in the relevant API calls.
  
  Can specify a runtime environment whole job, whether running a script
  directly on the cluster, using Ray Job submission, or using Ray Client:
  
  .. code-block:: python
  
      from ray.runtime_env import RuntimeEnv
      # Starting a single-node local Ray cluster
      ray.init(runtime_env=RuntimeEnv(...))
  
  .. code-block:: python
  
      from ray.runtime_env import RuntimeEnv
      # Connecting to remote cluster using Ray Client
      ray.init("ray://123.456.7.89:10001", runtime_env=RuntimeEnv(...))
  
  Can specify different runtime environments per-actor or per-task using
  ``.options()`` or the ``@ray.remote`` decorator:
  
  .. code-block:: python
  
      from ray.runtime_env import RuntimeEnv
      # Invoke a remote task that will run in a specified runtime environment.
      f.options(runtime_env=RuntimeEnv(...)).remote()
  
      # Instantiate an actor that will run in a specified runtime environment.
      actor = SomeClass.options(runtime_env=RuntimeEnv(...)).remote()
  
      # Specify a runtime environment in the task definition. Future invocations via
      # `g.remote()` will use this runtime environment unless overridden by using
      # `.options()` as above.
      @ray.remote(runtime_env=RuntimeEnv(...))
      def g():
          pass
  
      # Specify a runtime environment in the actor definition. Future instantiations
      # via `MyClass.remote()` will use this runtime environment unless overridden by
      # using `.options()` as above.
      @ray.remote(runtime_env=RuntimeEnv(...))
      class MyClass:
          pass
  
  Here are some examples of RuntimeEnv initialization:
  
  .. code-block:: python
  
      # Example for using conda
      RuntimeEnv(conda={
          "channels": ["defaults"], "dependencies": ["codecov"]})
      RuntimeEnv(conda="pytorch_p36")   # Found on DLAMIs
  
      # Example for using container
      RuntimeEnv(
          container={"image": "anyscale/ray-ml:nightly-py38-cpu",
          "worker_path": "/root/python/ray/_private/workers/default_worker.py",
          "run_options": ["--cap-drop SYS_ADMIN","--log-level=debug"]})
  
      # Example for set env_vars
      RuntimeEnv(env_vars={"OMP_NUM_THREADS": "32", "TF_WARNINGS": "none"})
  
      # Example for set pip
      RuntimeEnv(
          pip={"packages":["tensorflow", "requests"], "pip_check": False,
          "pip_version": "==22.0.2;python_version=='3.8.11'"})
  
  Args:
      py_modules: List of URIs (either in the GCS or external
          storage), each of which is a zip file that will be unpacked and
          inserted into the PYTHONPATH of the workers.
      working_dir: URI (either in the GCS or external storage) of a zip
          file that will be unpacked in the directory of each task/actor.
      pip: Either a list of pip packages, a string
          containing the path to a pip requirements.txt file, or a python
          dictionary that has three fields: 1) ``packages`` (required, List[str]): a
          list of pip packages, 2) ``pip_check`` (optional, bool): whether enable
          pip check at the end of pip install, defaults to False.
          3) ``pip_version`` (optional, str): the version of pip, Ray will spell
          the package name "pip" in front of the ``pip_version`` to form the final
          requirement string, the syntax of a requirement specifier is defined in
          full in PEP 508.
      conda: Either the conda YAML config, the name of a
          local conda env (e.g., "pytorch_p36"), or the path to a conda
          environment.yaml file.
          The Ray dependency will be automatically injected into the conda
          env to ensure compatibility with the cluster Ray. The conda name
          may be mangled automatically to avoid conflicts between runtime
          envs.
          This field cannot be specified at the same time as the 'pip' field.
          To use pip with conda, please specify your pip dependencies within
          the conda YAML config:
          https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#create-env-file-manually
      container: Require a given (Docker) container image,
          The Ray worker process will run in a container with this image.
          The `worker_path` is the default_worker.py path.
          The `run_options` list spec is here:
          https://docs.docker.com/engine/reference/run/
      env_vars: Environment variables to set.
      worker_process_setup_hook: (Experimental) The setup hook that's
          called after workers start and before Tasks and Actors are scheduled.
          A module name (string type) or callable (function) can be passed.
          When a module name is passed, Ray worker should be able to access the
          module name. When a callable is passed, callable should be serializable.
          When a runtime env is specified by job submission API,
          only a module name (string) is allowed.
      nsight: Dictionary mapping nsight profile option name to it's value.
      config: config for runtime environment. Either
          a dict or a RuntimeEnvConfig. Field: (1) setup_timeout_seconds, the
          timeout of runtime environment creation,  timeout is in seconds.
class_docstr_tok: ["This","class","is","used","to","define","a","runtime","environment","for","a","job",",","task",",","or","actor",".","See",":","ref",":","`","runtime-environments","`","for","detailed","documentation",".","This","class","can","be","used","interchangeably","with","an","unstructured","dictionary","in","the","relevant","API","calls",".","Can","specify","a","runtime","environment","whole","job",",","whether","running","a","script","directly","on","the","cluster",",","using","Ray","Job","submission",",","or","using","Ray","Client",":","..","code-block",":",":","python","from","ray.runtime_env","import","RuntimeEnv","#","Starting","a","single-node","local","Ray","cluster","ray.init","(","runtime_env=RuntimeEnv","(","...",")",")","..","code-block",":",":","python","from","ray.runtime_env","import","RuntimeEnv","#","Connecting","to","remote","cluster","using","Ray","Client","ray.init","(","``","ray",":","\/\/123.456.7.89:10001","''",",","runtime_env=RuntimeEnv","(","...",")",")","Can","specify","different","runtime","environments","per-actor","or","per-task","using","``",".options","(",")","``","or","the","``","@","ray.remote","``","decorator",":","..","code-block",":",":","python","from","ray.runtime_env","import","RuntimeEnv","#","Invoke","a","remote","task","that","will","run","in","a","specified","runtime","environment",".","f.options","(","runtime_env=RuntimeEnv","(","...",")",")",".remote","(",")","#","Instantiate","an","actor","that","will","run","in","a","specified","runtime","environment",".","actor","=","SomeClass.options","(","runtime_env=RuntimeEnv","(","...",")",")",".remote","(",")","#","Specify","a","runtime","environment","in","the","task","definition",".","Future","invocations","via","#","`","g.remote","(",")","`","will","use","this","runtime","environment","unless","overridden","by","using","#","`",".options","(",")","`","as","above",".","@","ray.remote","(","runtime_env=RuntimeEnv","(","...",")",")","def","g","(",")",":","pass","#","Specify","a","runtime","environment","in","the","actor","definition",".","Future","instantiations","#","via","`","MyClass.remote","(",")","`","will","use","this","runtime","environment","unless","overridden","by","#","using","`",".options","(",")","`","as","above",".","@","ray.remote","(","runtime_env=RuntimeEnv","(","...",")",")","class","MyClass",":","pass","Here","are","some","examples","of","RuntimeEnv","initialization",":","..","code-block",":",":","python","#","Example","for","using","conda","RuntimeEnv","(","conda=","{","``","channels","''",":","[","``","defaults","''","]",",","``","dependencies","''",":","[","``","codecov","''","]","}",")","RuntimeEnv","(","conda=","''","pytorch_p36","''",")","#","Found","on","DLAMIs","#","Example","for","using","container","RuntimeEnv","(","container=","{","``","image","''",":","``","anyscale\/ray-ml",":","nightly-py38-cpu","''",",","``","worker_path","''",":","``","\/root\/python\/ray\/_private\/workers\/default_worker.py","''",",","``","run_options","''",":","[","``","--","cap-drop","SYS_ADMIN","''",",","''","--","log-level=debug","''","]","}",")","#","Example","for","set","env_vars","RuntimeEnv","(","env_vars=","{","``","OMP_NUM_THREADS","''",":","``","32","''",",","``","TF_WARNINGS","''",":","``","none","''","}",")","#","Example","for","set","pip","RuntimeEnv","(","pip=","{","``","packages","''",":","[","``","tensorflow","''",",","``","requests","''","]",",","``","pip_check","''",":","False",",","``","pip_version","''",":","``","==22.0.2",";","python_version==","'","3.8.11","'","''","}",")","Args",":","py_modules",":","List","of","URIs","(","either","in","the","GCS","or","external","storage",")",",","each","of","which","is","a","zip","file","that","will","be","unpacked","and","inserted","into","the","PYTHONPATH","of","the","workers",".","working_dir",":","URI","(","either","in","the","GCS","or","external","storage",")","of","a","zip","file","that","will","be","unpacked","in","the","directory","of","each","task\/actor",".","pip",":","Either","a","list","of","pip","packages",",","a","string","containing","the","path","to","a","pip","requirements.txt","file",",","or","a","python","dictionary","that","has","three","fields",":","1",")","``","packages","``","(","required",",","List","[","str","]",")",":","a","list","of","pip","packages",",","2",")","``","pip_check","``","(","optional",",","bool",")",":","whether","enable","pip","check","at","the","end","of","pip","install",",","defaults","to","False",".","3",")","``","pip_version","``","(","optional",",","str",")",":","the","version","of","pip",",","Ray","will","spell","the","package","name","``","pip","''","in","front","of","the","``","pip_version","``","to","form","the","final","requirement","string",",","the","syntax","of","a","requirement","specifier","is","defined","in","full","in","PEP","508.","conda",":","Either","the","conda","YAML","config",",","the","name","of","a","local","conda","env","(","e.g.",",","``","pytorch_p36","''",")",",","or","the","path","to","a","conda","environment.yaml","file",".","The","Ray","dependency","will","be","automatically","injected","into","the","conda","env","to","ensure","compatibility","with","the","cluster","Ray",".","The","conda","name","may","be","mangled","automatically","to","avoid","conflicts","between","runtime","envs",".","This","field","can","not","be","specified","at","the","same","time","as","the","'pip","'","field",".","To","use","pip","with","conda",",","please","specify","your","pip","dependencies","within","the","conda","YAML","config",":","https",":","\/\/conda.io\/projects\/conda\/en\/latest\/user-guide\/tasks\/manage-environments.html","#","create-env-file-manually","container",":","Require","a","given","(","Docker",")","container","image",",","The","Ray","worker","process","will","run","in","a","container","with","this","image",".","The","`","worker_path","`","is","the","default_worker.py","path",".","The","`","run_options","`","list","spec","is","here",":","https",":","\/\/docs.docker.com\/engine\/reference\/run\/","env_vars",":","Environment","variables","to","set",".","worker_process_setup_hook",":","(","Experimental",")","The","setup","hook","that's","called","after","workers","start","and","before","Tasks","and","Actors","are","scheduled",".","A","module","name","(","string","type",")","or","callable","(","function",")","can","be","passed",".","When","a","module","name","is","passed",",","Ray","worker","should","be","able","to","access","the","module","name",".","When","a","callable","is","passed",",","callable","should","be","serializable",".","When","a","runtime","env","is","specified","by","job","submission","API",",","only","a","module","name","(","string",")","is","allowed",".","nsight",":","Dictionary","mapping","nsight","profile","option","name","to","it","'s","value",".","config",":","config","for","runtime","environment",".","Either","a","dict","or","a","RuntimeEnvConfig",".","Field",":","(","1",")","setup_timeout_seconds",",","the","timeout","of","runtime","environment","creation",",","timeout","is","in","seconds","."]
code: def __init__(
      self,
      *,
      py_modules: Optional[List[str]] = None,
      working_dir: Optional[str] = None,
      pip: Optional[List[str]] = None,
      conda: Optional[Union[Dict[str, str], str]] = None,
      container: Optional[Dict[str, str]] = None,
      env_vars: Optional[Dict[str, str]] = None,
      worker_process_setup_hook: Optional[Union[Callable, str]] = None,
      nsight: Optional[Union[str, Dict[str, str]]] = None,
      config: Optional[Union[Dict, RuntimeEnvConfig]] = None,
      _validate: bool = True,
      mpi: Optional[Dict] = None,
      **kwargs,
  ):
      super().__init__()
  
      runtime_env = kwargs
      if py_modules is not None:
          runtime_env["py_modules"] = py_modules
      if working_dir is not None:
          runtime_env["working_dir"] = working_dir
      if pip is not None:
          runtime_env["pip"] = pip
      if conda is not None:
          runtime_env["conda"] = conda
      if nsight is not None:
          runtime_env["_nsight"] = nsight
      if container is not None:
          runtime_env["container"] = container
      if env_vars is not None:
          runtime_env["env_vars"] = env_vars
      if config is not None:
          runtime_env["config"] = config
      if worker_process_setup_hook is not None:
          runtime_env[
              "worker_process_setup_hook"
          ] = worker_process_setup_hook
      if mpi is not None:
          runtime_env["mpi"] = mpi
      if runtime_env.get("java_jars"):
          runtime_env["java_jars"] = runtime_env.get("java_jars")
  
      self.update(runtime_env)
  
      # Blindly trust that the runtime_env has already been validated.
      # This is dangerous and should only be used internally (e.g., on the
      # deserialization codepath.
      if not _validate:
          return
  
      if self.get("conda") and self.get("pip"):
          raise ValueError(
              "The 'pip' field and 'conda' field of "
              "runtime_env cannot both be specified.\n"
              f"specified pip field: {self['pip']}\n"
              f"specified conda field: {self['conda']}\n"
              "To use pip with conda, please only set the 'conda' "
              "field, and specify your pip dependencies "
              "within the conda YAML config dict: see "
              "https://conda.io/projects/conda/en/latest/"
              "user-guide/tasks/manage-environments.html"
              "#create-env-file-manually"
          )
  
      if self.get("container"):
          if len(runtime_env) > 1:
              raise ValueError(
                  "The 'container' field currently cannot be used "
                  "together with other fields of runtime_env. "
                  f"Specified fields: {runtime_env.keys()}"
              )
  
      for option, validate_fn in OPTION_TO_VALIDATION_FN.items():
          option_val = self.get(option)
          if option_val is not None:
              del self[option]
              self[option] = option_val
  
      if "_ray_commit" not in self:
          if self.get("pip") or self.get("conda"):
              self["_ray_commit"] = ray.__commit__
  
      # Used for testing wheels that have not yet been merged into master.
      # If this is set to True, then we do not inject Ray into the conda
      # or pip dependencies.
      if "_inject_current_ray" not in self:
          if "RAY_RUNTIME_ENV_LOCAL_DEV_MODE" in os.environ:
              self["_inject_current_ray"] = True
  
      # NOTE(architkulkarni): This allows worker caching code in C++ to check
      # if a runtime env is empty without deserializing it.  This is a catch-
      # all; for validated inputs we won't set the key if the value is None.
      if all(val is None for val in self.values()):
          self.clear()
  
imports: import json
  import logging
  import os
  from copy import deepcopy
  from dataclasses import asdict, is_dataclass
  from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union
  import ray
  from ray._private.ray_constants import DEFAULT_RUNTIME_ENV_TIMEOUT_SECONDS
  from ray._private.runtime_env.conda import get_uri
  from ray._private.runtime_env.pip import get_uri
  from ray._private.runtime_env.plugin_schema_manager import RuntimeEnvPluginSchemaManager
  from ray._private.runtime_env.validation import OPTION_TO_VALIDATION_FN
  from ray._private.thirdparty.dacite import from_dict
  from ray.core.generated.runtime_env_common_pb2 import RuntimeEnvConfig
  from ray.util.annotations import PublicAPI
label_desc: Use image node_id 1 to create a new RuntimeEnv object from inherited base classes: dict with example: obj = RuntimeEnv()