runnable 0.12.3__py3-none-any.whl → 0.14.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- runnable/__init__.py +0 -11
 - runnable/catalog.py +27 -5
 - runnable/cli.py +122 -26
 - runnable/datastore.py +71 -35
 - runnable/defaults.py +0 -1
 - runnable/entrypoints.py +107 -32
 - runnable/exceptions.py +6 -2
 - runnable/executor.py +28 -9
 - runnable/graph.py +37 -12
 - runnable/integration.py +7 -2
 - runnable/nodes.py +15 -17
 - runnable/parameters.py +27 -8
 - runnable/pickler.py +1 -1
 - runnable/sdk.py +101 -33
 - runnable/secrets.py +3 -1
 - runnable/tasks.py +246 -34
 - runnable/utils.py +41 -13
 - {runnable-0.12.3.dist-info → runnable-0.14.0.dist-info}/METADATA +25 -31
 - runnable-0.14.0.dist-info/RECORD +24 -0
 - {runnable-0.12.3.dist-info → runnable-0.14.0.dist-info}/WHEEL +1 -1
 - runnable-0.14.0.dist-info/entry_points.txt +40 -0
 - runnable/extensions/__init__.py +0 -0
 - runnable/extensions/catalog/__init__.py +0 -21
 - runnable/extensions/catalog/file_system/__init__.py +0 -0
 - runnable/extensions/catalog/file_system/implementation.py +0 -234
 - runnable/extensions/catalog/k8s_pvc/__init__.py +0 -0
 - runnable/extensions/catalog/k8s_pvc/implementation.py +0 -16
 - runnable/extensions/catalog/k8s_pvc/integration.py +0 -59
 - runnable/extensions/executor/__init__.py +0 -649
 - runnable/extensions/executor/argo/__init__.py +0 -0
 - runnable/extensions/executor/argo/implementation.py +0 -1194
 - runnable/extensions/executor/argo/specification.yaml +0 -51
 - runnable/extensions/executor/k8s_job/__init__.py +0 -0
 - runnable/extensions/executor/k8s_job/implementation_FF.py +0 -259
 - runnable/extensions/executor/k8s_job/integration_FF.py +0 -69
 - runnable/extensions/executor/local/__init__.py +0 -0
 - runnable/extensions/executor/local/implementation.py +0 -71
 - runnable/extensions/executor/local_container/__init__.py +0 -0
 - runnable/extensions/executor/local_container/implementation.py +0 -446
 - runnable/extensions/executor/mocked/__init__.py +0 -0
 - runnable/extensions/executor/mocked/implementation.py +0 -154
 - runnable/extensions/executor/retry/__init__.py +0 -0
 - runnable/extensions/executor/retry/implementation.py +0 -168
 - runnable/extensions/nodes.py +0 -855
 - runnable/extensions/run_log_store/__init__.py +0 -0
 - runnable/extensions/run_log_store/chunked_file_system/__init__.py +0 -0
 - runnable/extensions/run_log_store/chunked_file_system/implementation.py +0 -111
 - runnable/extensions/run_log_store/chunked_k8s_pvc/__init__.py +0 -0
 - runnable/extensions/run_log_store/chunked_k8s_pvc/implementation.py +0 -21
 - runnable/extensions/run_log_store/chunked_k8s_pvc/integration.py +0 -61
 - runnable/extensions/run_log_store/db/implementation_FF.py +0 -157
 - runnable/extensions/run_log_store/db/integration_FF.py +0 -0
 - runnable/extensions/run_log_store/file_system/__init__.py +0 -0
 - runnable/extensions/run_log_store/file_system/implementation.py +0 -140
 - runnable/extensions/run_log_store/generic_chunked.py +0 -557
 - runnable/extensions/run_log_store/k8s_pvc/__init__.py +0 -0
 - runnable/extensions/run_log_store/k8s_pvc/implementation.py +0 -21
 - runnable/extensions/run_log_store/k8s_pvc/integration.py +0 -56
 - runnable/extensions/secrets/__init__.py +0 -0
 - runnable/extensions/secrets/dotenv/__init__.py +0 -0
 - runnable/extensions/secrets/dotenv/implementation.py +0 -100
 - runnable-0.12.3.dist-info/RECORD +0 -64
 - runnable-0.12.3.dist-info/entry_points.txt +0 -41
 - {runnable-0.12.3.dist-info → runnable-0.14.0.dist-info/licenses}/LICENSE +0 -0
 
| 
         @@ -1,51 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            apiVersion: argoproj.io/v1alpha1
         
     | 
| 
       2 
     | 
    
         
            -
            kind: Workflow
         
     | 
| 
       3 
     | 
    
         
            -
            metadata:
         
     | 
| 
       4 
     | 
    
         
            -
              generateName: runnable-dag
         
     | 
| 
       5 
     | 
    
         
            -
            spec:
         
     | 
| 
       6 
     | 
    
         
            -
              activeDeadlineSeconds: int # max run time of the workflow
         
     | 
| 
       7 
     | 
    
         
            -
              entrypoint: str
         
     | 
| 
       8 
     | 
    
         
            -
              nodeSelector: Dict[str, str] # global node selector
         
     | 
| 
       9 
     | 
    
         
            -
              parallelism: # global level
         
     | 
| 
       10 
     | 
    
         
            -
              podGC: OnPodCompletion
         
     | 
| 
       11 
     | 
    
         
            -
              resources: # Should be converted to podSpecPath
         
     | 
| 
       12 
     | 
    
         
            -
                limits:
         
     | 
| 
       13 
     | 
    
         
            -
                requests:
         
     | 
| 
       14 
     | 
    
         
            -
              podSpecPatch: json str representation of resources for defaults
         
     | 
| 
       15 
     | 
    
         
            -
              retryStrategy: # global level for all templates
         
     | 
| 
       16 
     | 
    
         
            -
                limit: int
         
     | 
| 
       17 
     | 
    
         
            -
                retryPolicy: # global level for all templates
         
     | 
| 
       18 
     | 
    
         
            -
                backoff:
         
     | 
| 
       19 
     | 
    
         
            -
                  duration: str
         
     | 
| 
       20 
     | 
    
         
            -
                  factor: int
         
     | 
| 
       21 
     | 
    
         
            -
                  maxDuration: str
         
     | 
| 
       22 
     | 
    
         
            -
              serviceAccountName: str # Optionally required
         
     | 
| 
       23 
     | 
    
         
            -
              templateDefaults:
         
     | 
| 
       24 
     | 
    
         
            -
                activeDeadlineSeconds: int, for a template
         
     | 
| 
       25 
     | 
    
         
            -
                timeout: str # max time including the wait time
         
     | 
| 
       26 
     | 
    
         
            -
                failFast: true
         
     | 
| 
       27 
     | 
    
         
            -
                volumes:
         
     | 
| 
       28 
     | 
    
         
            -
              templates:
         
     | 
| 
       29 
     | 
    
         
            -
                activeDeadlineSeconds: # override
         
     | 
| 
       30 
     | 
    
         
            -
                nodeSelector: # override
         
     | 
| 
       31 
     | 
    
         
            -
                retryStrategy: # override
         
     | 
| 
       32 
     | 
    
         
            -
                tolerations: # override
         
     | 
| 
       33 
     | 
    
         
            -
                container:
         
     | 
| 
       34 
     | 
    
         
            -
                  command:
         
     | 
| 
       35 
     | 
    
         
            -
                  env:
         
     | 
| 
       36 
     | 
    
         
            -
                  image:
         
     | 
| 
       37 
     | 
    
         
            -
                  imagePullPolicy:
         
     | 
| 
       38 
     | 
    
         
            -
                  volumeMounts:
         
     | 
| 
       39 
     | 
    
         
            -
                  resources:
         
     | 
| 
       40 
     | 
    
         
            -
                    limits:
         
     | 
| 
       41 
     | 
    
         
            -
                    requests:
         
     | 
| 
       42 
     | 
    
         
            -
                dag:
         
     | 
| 
       43 
     | 
    
         
            -
                  tasks:
         
     | 
| 
       44 
     | 
    
         
            -
                    depends:
         
     | 
| 
       45 
     | 
    
         
            -
                    continueOn:
         
     | 
| 
       46 
     | 
    
         
            -
              tolerations: # global level for all templates
         
     | 
| 
       47 
     | 
    
         
            -
                effect: str
         
     | 
| 
       48 
     | 
    
         
            -
                key: str
         
     | 
| 
       49 
     | 
    
         
            -
                operator: str
         
     | 
| 
       50 
     | 
    
         
            -
                value: str
         
     | 
| 
       51 
     | 
    
         
            -
              volumes:
         
     | 
| 
         
            File without changes
         
     | 
| 
         @@ -1,259 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # import logging
         
     | 
| 
       2 
     | 
    
         
            -
            # import shlex
         
     | 
| 
       3 
     | 
    
         
            -
            # from typing import Dict, List, Optional
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            # from pydantic import BaseModel
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
            # from runnable import defaults, integration, utils
         
     | 
| 
       8 
     | 
    
         
            -
            # from runnable.executor import BaseExecutor
         
     | 
| 
       9 
     | 
    
         
            -
            # from runnable.graph import Graph
         
     | 
| 
       10 
     | 
    
         
            -
            # from runnable.nodes import BaseNode
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
            # logger = logging.getLogger(defaults.NAME)
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
            # try:
         
     | 
| 
       15 
     | 
    
         
            -
            #     from kubernetes import client
         
     | 
| 
       16 
     | 
    
         
            -
            #     from kubernetes.client import V1EnvVar, V1EnvVarSource, V1PersistentVolumeClaimVolumeSource, V1SecretKeySelector
         
     | 
| 
       17 
     | 
    
         
            -
            # except ImportError as _e:
         
     | 
| 
       18 
     | 
    
         
            -
            #     msg = "Kubernetes Dependencies have not been installed!!"
         
     | 
| 
       19 
     | 
    
         
            -
            #     # raise Exception(msg) from _e
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
            # class Toleration(BaseModel):
         
     | 
| 
       23 
     | 
    
         
            -
            #     effect: str
         
     | 
| 
       24 
     | 
    
         
            -
            #     key: str
         
     | 
| 
       25 
     | 
    
         
            -
            #     operator: str
         
     | 
| 
       26 
     | 
    
         
            -
            #     value: str
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
            # class K8sJobExecutor(BaseExecutor):
         
     | 
| 
       30 
     | 
    
         
            -
            #     service_name = "k8s-job"
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
            #     # TODO: move this to K8's style config.
         
     | 
| 
       33 
     | 
    
         
            -
            #     class ContextConfig(BaseModel):
         
     | 
| 
       34 
     | 
    
         
            -
            #         docker_image: str
         
     | 
| 
       35 
     | 
    
         
            -
            #         config_path: str = ""  # Let the client decide on the path to the config file.
         
     | 
| 
       36 
     | 
    
         
            -
            #         namespace: str = "default"
         
     | 
| 
       37 
     | 
    
         
            -
            #         cpu_limit: str = "250m"
         
     | 
| 
       38 
     | 
    
         
            -
            #         memory_limit: str = "1G"
         
     | 
| 
       39 
     | 
    
         
            -
            #         gpu_limit: int = 0
         
     | 
| 
       40 
     | 
    
         
            -
            #         gpu_vendor: str = "nvidia.com/gpu"
         
     | 
| 
       41 
     | 
    
         
            -
            #         cpu_request: str = ""
         
     | 
| 
       42 
     | 
    
         
            -
            #         memory_request: str = ""
         
     | 
| 
       43 
     | 
    
         
            -
            #         active_deadline_seconds: int = 60 * 60 * 2  # 2 hours
         
     | 
| 
       44 
     | 
    
         
            -
            #         ttl_seconds_after_finished: int = 60  #  1 minute
         
     | 
| 
       45 
     | 
    
         
            -
            #         image_pull_policy: str = "Always"
         
     | 
| 
       46 
     | 
    
         
            -
            #         secrets_from_k8s: dict = {}  # EnvVar=SecretName:Key
         
     | 
| 
       47 
     | 
    
         
            -
            #         persistent_volumes: dict = {}  # volume-name:mount_path
         
     | 
| 
       48 
     | 
    
         
            -
            #         node_selector: Dict[str, str] = {}
         
     | 
| 
       49 
     | 
    
         
            -
            #         tolerations: List[Toleration] = []
         
     | 
| 
       50 
     | 
    
         
            -
            #         labels: Dict[str, str] = {}
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
            #     def __init__(self, config: Optional[dict] = None):
         
     | 
| 
       53 
     | 
    
         
            -
            #         self.config = self.ContextConfig(**(config or {}))
         
     | 
| 
       54 
     | 
    
         
            -
            #         self.persistent_volumes = {}
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
            #         for i, (claim, mount_path) in enumerate(self.config.persistent_volumes.items()):
         
     | 
| 
       57 
     | 
    
         
            -
            #             self.persistent_volumes[f"executor-{i}"] = (claim, mount_path)
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
            #     def prepare_for_graph_execution(self):
         
     | 
| 
       60 
     | 
    
         
            -
            #         """
         
     | 
| 
       61 
     | 
    
         
            -
            #         This method would be called prior to calling execute_graph.
         
     | 
| 
       62 
     | 
    
         
            -
            #         Perform any steps required before doing the graph execution.
         
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
            #         The most common implementation is to prepare a run log for the run if the run uses local interactive compute.
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
            #         But in cases of actual rendering the job specs (eg: AWS step functions, K8's) we need not do anything.
         
     | 
| 
       67 
     | 
    
         
            -
            #         """
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
            #         integration.validate(self, self.run_log_store)
         
     | 
| 
       70 
     | 
    
         
            -
            #         integration.configure_for_traversal(self, self.run_log_store)
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
            #         integration.validate(self, self.catalog_handler)
         
     | 
| 
       73 
     | 
    
         
            -
            #         integration.configure_for_traversal(self, self.catalog_handler)
         
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
            #         integration.validate(self, self.secrets_handler)
         
     | 
| 
       76 
     | 
    
         
            -
            #         integration.configure_for_traversal(self, self.secrets_handler)
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
            #         integration.validate(self, self.experiment_tracker)
         
     | 
| 
       79 
     | 
    
         
            -
            #         integration.configure_for_traversal(self, self.experiment_tracker)
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
            #     def prepare_for_node_execution(self):
         
     | 
| 
       82 
     | 
    
         
            -
            #         """
         
     | 
| 
       83 
     | 
    
         
            -
            #         Perform any modifications to the services prior to execution of the node.
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
            #         Args:
         
     | 
| 
       86 
     | 
    
         
            -
            #             node (Node): [description]
         
     | 
| 
       87 
     | 
    
         
            -
            #             map_variable (dict, optional): [description]. Defaults to None.
         
     | 
| 
       88 
     | 
    
         
            -
            #         """
         
     | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
            #         integration.validate(self, self.run_log_store)
         
     | 
| 
       91 
     | 
    
         
            -
            #         integration.configure_for_execution(self, self.run_log_store)
         
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
            #         integration.validate(self, self.catalog_handler)
         
     | 
| 
       94 
     | 
    
         
            -
            #         integration.configure_for_execution(self, self.catalog_handler)
         
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
            #         integration.validate(self, self.secrets_handler)
         
     | 
| 
       97 
     | 
    
         
            -
            #         integration.configure_for_execution(self, self.secrets_handler)
         
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
       99 
     | 
    
         
            -
            #         integration.validate(self, self.experiment_tracker)
         
     | 
| 
       100 
     | 
    
         
            -
            #         integration.configure_for_execution(self, self.experiment_tracker)
         
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
     | 
    
         
            -
            #         self._set_up_run_log(exists_ok=True)
         
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
            #     @property
         
     | 
| 
       105 
     | 
    
         
            -
            #     def _client(self):
         
     | 
| 
       106 
     | 
    
         
            -
            #         from kubernetes import config as k8s_config
         
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
            #         if self.config.config_path:
         
     | 
| 
       109 
     | 
    
         
            -
            #             k8s_config.load_kube_config(kube_config_path=self.config.config_path)
         
     | 
| 
       110 
     | 
    
         
            -
            #         else:
         
     | 
| 
       111 
     | 
    
         
            -
            #             # https://github.com/kubernetes-client/python/blob/master/kubernetes/base/config/__init__.py
         
     | 
| 
       112 
     | 
    
         
            -
            #             k8s_config.load_config()
         
     | 
| 
       113 
     | 
    
         
            -
            #         return client
         
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
            #     @property
         
     | 
| 
       116 
     | 
    
         
            -
            #     def tolerations(self):
         
     | 
| 
       117 
     | 
    
         
            -
            #         return [toleration.dict() for toleration in self.config.tolerations]
         
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
            #     def execute_job(self, node: BaseNode):
         
     | 
| 
       120 
     | 
    
         
            -
            #         command = utils.get_job_execution_command(self, node)
         
     | 
| 
       121 
     | 
    
         
            -
            #         logger.info(f"Triggering a kubernetes job with : {command}")
         
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
            #         self.config.labels["job_name"] = self.run_id
         
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
       125 
     | 
    
         
            -
            #         k8s_batch = self._client.BatchV1Api()
         
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
            #         cpu_limit = self.config.cpu_limit
         
     | 
| 
       128 
     | 
    
         
            -
            #         memory_limit = self.config.memory_limit
         
     | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
            #         cpu_request = self.config.cpu_request or cpu_limit
         
     | 
| 
       131 
     | 
    
         
            -
            #         memory_request = self.config.memory_request or memory_limit
         
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
            #         gpu_limit = str(self.config.gpu_limit)  # Should be something like nvidia -etc
         
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
            #         limits = {
         
     | 
| 
       136 
     | 
    
         
            -
            #             "cpu": cpu_limit,
         
     | 
| 
       137 
     | 
    
         
            -
            #             "memory": memory_limit,
         
     | 
| 
       138 
     | 
    
         
            -
            #             self.config.gpu_vendor: gpu_limit,
         
     | 
| 
       139 
     | 
    
         
            -
            #         }
         
     | 
| 
       140 
     | 
    
         
            -
            #         requests = {"cpu": cpu_request, "memory": memory_request}
         
     | 
| 
       141 
     | 
    
         
            -
            #         resources = {"limits": limits, "requests": requests}
         
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
            #         environment_variables = []
         
     | 
| 
       144 
     | 
    
         
            -
            #         for secret_env, k8_secret in self.config.secrets_from_k8s.items():
         
     | 
| 
       145 
     | 
    
         
            -
            #             try:
         
     | 
| 
       146 
     | 
    
         
            -
            #                 secret_name, key = k8_secret.split(":")
         
     | 
| 
       147 
     | 
    
         
            -
            #             except Exception as _e:
         
     | 
| 
       148 
     | 
    
         
            -
            #                 msg = "K8's secret should be of format EnvVar=SecretName:Key"
         
     | 
| 
       149 
     | 
    
         
            -
            #                 raise Exception(msg) from _e
         
     | 
| 
       150 
     | 
    
         
            -
            #             secret_as_env = V1EnvVar(
         
     | 
| 
       151 
     | 
    
         
            -
            #                 name=secret_env,
         
     | 
| 
       152 
     | 
    
         
            -
            #                 value_from=V1EnvVarSource(secret_key_ref=V1SecretKeySelector(name=secret_name, key=key)),
         
     | 
| 
       153 
     | 
    
         
            -
            #             )
         
     | 
| 
       154 
     | 
    
         
            -
            #             environment_variables.append(secret_as_env)
         
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
            #         overridden_params = utils.get_user_set_parameters()
         
     | 
| 
       157 
     | 
    
         
            -
            #         # The parameters present in the environment override the parameters present in the parameters file
         
     | 
| 
       158 
     | 
    
         
            -
            #         # The values are coerced to be strings, hopefully they will be fine on the other side.
         
     | 
| 
       159 
     | 
    
         
            -
            #         for k, v in overridden_params.items():
         
     | 
| 
       160 
     | 
    
         
            -
            #             environment_variables.append(V1EnvVar(name=defaults.PARAMETER_PREFIX + k, value=str(v)))
         
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       162 
     | 
    
         
            -
            #         pod_volumes = []
         
     | 
| 
       163 
     | 
    
         
            -
            #         volume_mounts = []
         
     | 
| 
       164 
     | 
    
         
            -
            #         for claim_name, (claim, mount_path) in self.persistent_volumes.items():
         
     | 
| 
       165 
     | 
    
         
            -
            #             pod_volumes.append(
         
     | 
| 
       166 
     | 
    
         
            -
            #                 self._client.V1Volume(
         
     | 
| 
       167 
     | 
    
         
            -
            #                     name=claim_name,
         
     | 
| 
       168 
     | 
    
         
            -
            #                     persistent_volume_claim=V1PersistentVolumeClaimVolumeSource(claim_name=claim),
         
     | 
| 
       169 
     | 
    
         
            -
            #                 )
         
     | 
| 
       170 
     | 
    
         
            -
            #             )
         
     | 
| 
       171 
     | 
    
         
            -
            #             volume_mounts.append(self._client.V1VolumeMount(name=claim_name, mount_path=mount_path))
         
     | 
| 
       172 
     | 
    
         
            -
             
     | 
| 
       173 
     | 
    
         
            -
            #         base_container = self._client.V1Container(
         
     | 
| 
       174 
     | 
    
         
            -
            #             name=self.run_id,
         
     | 
| 
       175 
     | 
    
         
            -
            #             image=self.config.docker_image,
         
     | 
| 
       176 
     | 
    
         
            -
            #             command=shlex.split(command),
         
     | 
| 
       177 
     | 
    
         
            -
            #             resources=resources,
         
     | 
| 
       178 
     | 
    
         
            -
            #             env=environment_variables,
         
     | 
| 
       179 
     | 
    
         
            -
            #             image_pull_policy="Always",
         
     | 
| 
       180 
     | 
    
         
            -
            #             volume_mounts=volume_mounts or None,
         
     | 
| 
       181 
     | 
    
         
            -
            #         )
         
     | 
| 
       182 
     | 
    
         
            -
             
     | 
| 
       183 
     | 
    
         
            -
            #         pod_spec = self._client.V1PodSpec(
         
     | 
| 
       184 
     | 
    
         
            -
            #             volumes=pod_volumes or None,
         
     | 
| 
       185 
     | 
    
         
            -
            #             restart_policy="Never",
         
     | 
| 
       186 
     | 
    
         
            -
            #             containers=[base_container],
         
     | 
| 
       187 
     | 
    
         
            -
            #             node_selector=self.config.node_selector,
         
     | 
| 
       188 
     | 
    
         
            -
            #             tolerations=self.tolerations,
         
     | 
| 
       189 
     | 
    
         
            -
            #         )
         
     | 
| 
       190 
     | 
    
         
            -
             
     | 
| 
       191 
     | 
    
         
            -
            #         pod_template = self._client.V1PodTemplateSpec(
         
     | 
| 
       192 
     | 
    
         
            -
            #             metadata=client.V1ObjectMeta(
         
     | 
| 
       193 
     | 
    
         
            -
            #                 labels=self.config.labels,
         
     | 
| 
       194 
     | 
    
         
            -
            #                 annotations={"sidecar.istio.io/inject": "false"},
         
     | 
| 
       195 
     | 
    
         
            -
            #             ),
         
     | 
| 
       196 
     | 
    
         
            -
            #             spec=pod_spec,
         
     | 
| 
       197 
     | 
    
         
            -
            #         )
         
     | 
| 
       198 
     | 
    
         
            -
             
     | 
| 
       199 
     | 
    
         
            -
            #         job_spec = client.V1JobSpec(
         
     | 
| 
       200 
     | 
    
         
            -
            #             template=pod_template,
         
     | 
| 
       201 
     | 
    
         
            -
            #             backoff_limit=2,
         
     | 
| 
       202 
     | 
    
         
            -
            #             ttl_seconds_after_finished=self.config.ttl_seconds_after_finished,
         
     | 
| 
       203 
     | 
    
         
            -
            #         )
         
     | 
| 
       204 
     | 
    
         
            -
            #         job_spec.active_deadline_seconds = self.config.active_deadline_seconds
         
     | 
| 
       205 
     | 
    
         
            -
             
     | 
| 
       206 
     | 
    
         
            -
            #         job = client.V1Job(
         
     | 
| 
       207 
     | 
    
         
            -
            #             api_version="batch/v1",
         
     | 
| 
       208 
     | 
    
         
            -
            #             kind="Job",
         
     | 
| 
       209 
     | 
    
         
            -
            #             metadata=client.V1ObjectMeta(name=self.run_id),
         
     | 
| 
       210 
     | 
    
         
            -
            #             spec=job_spec,
         
     | 
| 
       211 
     | 
    
         
            -
            #         )
         
     | 
| 
       212 
     | 
    
         
            -
             
     | 
| 
       213 
     | 
    
         
            -
            #         logger.debug(f"Submitting kubernetes job: {job}")
         
     | 
| 
       214 
     | 
    
         
            -
             
     | 
| 
       215 
     | 
    
         
            -
            #         try:
         
     | 
| 
       216 
     | 
    
         
            -
            #             response = k8s_batch.create_namespaced_job(
         
     | 
| 
       217 
     | 
    
         
            -
            #                 body=job,
         
     | 
| 
       218 
     | 
    
         
            -
            #                 namespace=self.config.namespace,
         
     | 
| 
       219 
     | 
    
         
            -
            #                 _preload_content=False,
         
     | 
| 
       220 
     | 
    
         
            -
            #                 pretty=True,
         
     | 
| 
       221 
     | 
    
         
            -
            #             )
         
     | 
| 
       222 
     | 
    
         
            -
            #             print(f"Kubernetes job {self.run_id} created")
         
     | 
| 
       223 
     | 
    
         
            -
            #             logger.debug(f"Kubernetes job response: {response}")
         
     | 
| 
       224 
     | 
    
         
            -
            #         except Exception as e:
         
     | 
| 
       225 
     | 
    
         
            -
            #             logger.exception(e)
         
     | 
| 
       226 
     | 
    
         
            -
            #             raise
         
     | 
| 
       227 
     | 
    
         
            -
             
     | 
| 
       228 
     | 
    
         
            -
            #     def execute_node(self, node: BaseNode, map_variable: Optional[dict] = None, **kwargs):
         
     | 
| 
       229 
     | 
    
         
            -
            #         step_log = self.run_log_store.create_step_log(node.name, node._get_step_log_name(map_variable))
         
     | 
| 
       230 
     | 
    
         
            -
             
     | 
| 
       231 
     | 
    
         
            -
            #         self.add_code_identities(node=node, step_log=step_log)
         
     | 
| 
       232 
     | 
    
         
            -
             
     | 
| 
       233 
     | 
    
         
            -
            #         step_log.step_type = node.node_type
         
     | 
| 
       234 
     | 
    
         
            -
            #         step_log.status = defaults.PROCESSING
         
     | 
| 
       235 
     | 
    
         
            -
            #         self.run_log_store.add_step_log(step_log, self.run_id)
         
     | 
| 
       236 
     | 
    
         
            -
             
     | 
| 
       237 
     | 
    
         
            -
            #         super()._execute_node(node, map_variable=map_variable, **kwargs)
         
     | 
| 
       238 
     | 
    
         
            -
             
     | 
| 
       239 
     | 
    
         
            -
            #         step_log = self.run_log_store.get_step_log(node._get_step_log_name(map_variable), self.run_id)
         
     | 
| 
       240 
     | 
    
         
            -
            #         if step_log.status == defaults.FAIL:
         
     | 
| 
       241 
     | 
    
         
            -
            #             raise Exception(f"Step {node.name} failed")
         
     | 
| 
       242 
     | 
    
         
            -
             
     | 
| 
       243 
     | 
    
         
            -
            #     def execute_graph(self, dag: Graph, map_variable: Optional[dict] = None, **kwargs):
         
     | 
| 
       244 
     | 
    
         
            -
            #         msg = "This executor is not supported to execute any graphs but only jobs (functions or notebooks)"
         
     | 
| 
       245 
     | 
    
         
            -
            #         raise NotImplementedError(msg)
         
     | 
| 
       246 
     | 
    
         
            -
             
     | 
| 
       247 
     | 
    
         
            -
            #     def send_return_code(self, stage="traversal"):
         
     | 
| 
       248 
     | 
    
         
            -
            #         """
         
     | 
| 
       249 
     | 
    
         
            -
            #         Convenience function used by pipeline to send return code to the caller of the cli
         
     | 
| 
       250 
     | 
    
         
            -
             
     | 
| 
       251 
     | 
    
         
            -
            #         Raises:
         
     | 
| 
       252 
     | 
    
         
            -
            #             Exception: If the pipeline execution failed
         
     | 
| 
       253 
     | 
    
         
            -
            #         """
         
     | 
| 
       254 
     | 
    
         
            -
            #         if stage != "traversal":  # traversal does no actual execution, so return code is pointless
         
     | 
| 
       255 
     | 
    
         
            -
            #             run_id = self.run_id
         
     | 
| 
       256 
     | 
    
         
            -
             
     | 
| 
       257 
     | 
    
         
            -
            #             run_log = self.run_log_store.get_run_log_by_id(run_id=run_id, full=False)
         
     | 
| 
       258 
     | 
    
         
            -
            #             if run_log.status == defaults.FAIL:
         
     | 
| 
       259 
     | 
    
         
            -
            #                 raise Exception("Pipeline execution failed")
         
     | 
| 
         @@ -1,69 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            import logging
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            from runnable import defaults
         
     | 
| 
       4 
     | 
    
         
            -
            from runnable.integration import BaseIntegration
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
            logger = logging.getLogger(defaults.NAME)
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            class BufferedRunLogStore(BaseIntegration):
         
     | 
| 
       10 
     | 
    
         
            -
                """
         
     | 
| 
       11 
     | 
    
         
            -
                Only local execution mode is possible for Buffered Run Log store
         
     | 
| 
       12 
     | 
    
         
            -
                """
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                executor_type = "k8s-job"
         
     | 
| 
       15 
     | 
    
         
            -
                service_type = "run_log_store"  # One of secret, catalog, datastore
         
     | 
| 
       16 
     | 
    
         
            -
                service_provider = "buffered"  # The actual implementation of the service
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
                def validate(self, **kwargs):
         
     | 
| 
       19 
     | 
    
         
            -
                    raise Exception("K8s job cannot run work with buffered run log store")
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
            class FileSystemRunLogStore(BaseIntegration):
         
     | 
| 
       23 
     | 
    
         
            -
                """
         
     | 
| 
       24 
     | 
    
         
            -
                Only local execution mode is possible for Buffered Run Log store
         
     | 
| 
       25 
     | 
    
         
            -
                """
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                executor_type = "k8s-job"
         
     | 
| 
       28 
     | 
    
         
            -
                service_type = "run_log_store"  # One of secret, catalog, datastore
         
     | 
| 
       29 
     | 
    
         
            -
                service_provider = "file-system"  # The actual implementation of the service
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                def validate(self, **kwargs):
         
     | 
| 
       32 
     | 
    
         
            -
                    msg = (
         
     | 
| 
       33 
     | 
    
         
            -
                        "K8s job cannot run work with file-system run log store."
         
     | 
| 
       34 
     | 
    
         
            -
                        "Unless you have made a mechanism to use volume mounts"
         
     | 
| 
       35 
     | 
    
         
            -
                    )
         
     | 
| 
       36 
     | 
    
         
            -
                    logger.warning(msg)
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
            class ChunkedFSRunLogStore(BaseIntegration):
         
     | 
| 
       40 
     | 
    
         
            -
                """
         
     | 
| 
       41 
     | 
    
         
            -
                Only local execution mode is possible for Buffered Run Log store
         
     | 
| 
       42 
     | 
    
         
            -
                """
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                executor_type = "k8s-job"
         
     | 
| 
       45 
     | 
    
         
            -
                service_type = "run_log_store"  # One of secret, catalog, datastore
         
     | 
| 
       46 
     | 
    
         
            -
                service_provider = "chunked-fs"  # The actual implementation of the service
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                def validate(self, **kwargs):
         
     | 
| 
       49 
     | 
    
         
            -
                    msg = (
         
     | 
| 
       50 
     | 
    
         
            -
                        "K8s job cannot run work with chunked-fs run log store."
         
     | 
| 
       51 
     | 
    
         
            -
                        "Unless you have made a mechanism to use volume mounts"
         
     | 
| 
       52 
     | 
    
         
            -
                    )
         
     | 
| 
       53 
     | 
    
         
            -
                    logger.warning(msg)
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
            class FileSystemCatalog(BaseIntegration):
         
     | 
| 
       57 
     | 
    
         
            -
                """
         
     | 
| 
       58 
     | 
    
         
            -
                Only local execution mode is possible for Buffered Run Log store
         
     | 
| 
       59 
     | 
    
         
            -
                """
         
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
                executor_type = "k8s-job"
         
     | 
| 
       62 
     | 
    
         
            -
                service_type = "catalog"  # One of secret, catalog, datastore
         
     | 
| 
       63 
     | 
    
         
            -
                service_provider = "file-system"  # The actual implementation of the service
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
                def validate(self, **kwargs):
         
     | 
| 
       66 
     | 
    
         
            -
                    msg = (
         
     | 
| 
       67 
     | 
    
         
            -
                        "K8s Job cannot run work with file-system catalog." "Unless you have made a mechanism to use volume mounts"
         
     | 
| 
       68 
     | 
    
         
            -
                    )
         
     | 
| 
       69 
     | 
    
         
            -
                    logger.warning(msg)
         
     | 
| 
         
            File without changes
         
     | 
| 
         @@ -1,71 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            import logging
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            from runnable import defaults
         
     | 
| 
       4 
     | 
    
         
            -
            from runnable.defaults import TypeMapVariable
         
     | 
| 
       5 
     | 
    
         
            -
            from runnable.extensions.executor import GenericExecutor
         
     | 
| 
       6 
     | 
    
         
            -
            from runnable.extensions.nodes import TaskNode
         
     | 
| 
       7 
     | 
    
         
            -
            from runnable.nodes import BaseNode
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            logger = logging.getLogger(defaults.LOGGER_NAME)
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
            class LocalExecutor(GenericExecutor):
         
     | 
| 
       13 
     | 
    
         
            -
                """
         
     | 
| 
       14 
     | 
    
         
            -
                In the mode of local execution, we run everything on the local computer.
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
                This has some serious implications on the amount of time it would take to complete the run.
         
     | 
| 
       17 
     | 
    
         
            -
                Also ensure that the local compute is good enough for the compute to happen of all the steps.
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
                Example config:
         
     | 
| 
       20 
     | 
    
         
            -
                execution:
         
     | 
| 
       21 
     | 
    
         
            -
                  type: local
         
     | 
| 
       22 
     | 
    
         
            -
                  config:
         
     | 
| 
       23 
     | 
    
         
            -
                    enable_parallel: True or False to enable parallel.
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                """
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                service_name: str = "local"
         
     | 
| 
       28 
     | 
    
         
            -
                _local: bool = True
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                def trigger_job(self, node: BaseNode, map_variable: TypeMapVariable = None, **kwargs):
         
     | 
| 
       31 
     | 
    
         
            -
                    """
         
     | 
| 
       32 
     | 
    
         
            -
                    In this mode of execution, we prepare for the node execution and execute the node
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                    Args:
         
     | 
| 
       35 
     | 
    
         
            -
                        node (BaseNode): [description]
         
     | 
| 
       36 
     | 
    
         
            -
                        map_variable (str, optional): [description]. Defaults to ''.
         
     | 
| 
       37 
     | 
    
         
            -
                    """
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                    self.prepare_for_node_execution()
         
     | 
| 
       40 
     | 
    
         
            -
                    self.execute_node(node=node, map_variable=map_variable, **kwargs)
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                def execute_node(self, node: BaseNode, map_variable: TypeMapVariable = None, **kwargs):
         
     | 
| 
       43 
     | 
    
         
            -
                    """
         
     | 
| 
       44 
     | 
    
         
            -
                    For local execution, we just execute the node.
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                    Args:
         
     | 
| 
       47 
     | 
    
         
            -
                        node (BaseNode): _description_
         
     | 
| 
       48 
     | 
    
         
            -
                        map_variable (dict[str, str], optional): _description_. Defaults to None.
         
     | 
| 
       49 
     | 
    
         
            -
                    """
         
     | 
| 
       50 
     | 
    
         
            -
                    self._execute_node(node=node, map_variable=map_variable, **kwargs)
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
                def execute_job(self, node: TaskNode):
         
     | 
| 
       53 
     | 
    
         
            -
                    """
         
     | 
| 
       54 
     | 
    
         
            -
                    Set up the step log and call the execute node
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
                    Args:
         
     | 
| 
       57 
     | 
    
         
            -
                        node (BaseNode): _description_
         
     | 
| 
       58 
     | 
    
         
            -
                    """
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
                    step_log = self._context.run_log_store.create_step_log(node.name, node._get_step_log_name(map_variable=None))
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
                    self.add_code_identities(node=node, step_log=step_log)
         
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
                    step_log.step_type = node.node_type
         
     | 
| 
       65 
     | 
    
         
            -
                    step_log.status = defaults.PROCESSING
         
     | 
| 
       66 
     | 
    
         
            -
                    self._context.run_log_store.add_step_log(step_log, self._context.run_id)
         
     | 
| 
       67 
     | 
    
         
            -
                    self.execute_node(node=node)
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
                    # Update the run log status
         
     | 
| 
       70 
     | 
    
         
            -
                    step_log = self._context.run_log_store.get_step_log(node._get_step_log_name(), self._context.run_id)
         
     | 
| 
       71 
     | 
    
         
            -
                    self._context.run_log_store.update_run_log_status(run_id=self._context.run_id, status=step_log.status)
         
     | 
| 
         
            File without changes
         
     |