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.
Files changed (64) hide show
  1. runnable/__init__.py +0 -11
  2. runnable/catalog.py +27 -5
  3. runnable/cli.py +122 -26
  4. runnable/datastore.py +71 -35
  5. runnable/defaults.py +0 -1
  6. runnable/entrypoints.py +107 -32
  7. runnable/exceptions.py +6 -2
  8. runnable/executor.py +28 -9
  9. runnable/graph.py +37 -12
  10. runnable/integration.py +7 -2
  11. runnable/nodes.py +15 -17
  12. runnable/parameters.py +27 -8
  13. runnable/pickler.py +1 -1
  14. runnable/sdk.py +101 -33
  15. runnable/secrets.py +3 -1
  16. runnable/tasks.py +246 -34
  17. runnable/utils.py +41 -13
  18. {runnable-0.12.3.dist-info → runnable-0.14.0.dist-info}/METADATA +25 -31
  19. runnable-0.14.0.dist-info/RECORD +24 -0
  20. {runnable-0.12.3.dist-info → runnable-0.14.0.dist-info}/WHEEL +1 -1
  21. runnable-0.14.0.dist-info/entry_points.txt +40 -0
  22. runnable/extensions/__init__.py +0 -0
  23. runnable/extensions/catalog/__init__.py +0 -21
  24. runnable/extensions/catalog/file_system/__init__.py +0 -0
  25. runnable/extensions/catalog/file_system/implementation.py +0 -234
  26. runnable/extensions/catalog/k8s_pvc/__init__.py +0 -0
  27. runnable/extensions/catalog/k8s_pvc/implementation.py +0 -16
  28. runnable/extensions/catalog/k8s_pvc/integration.py +0 -59
  29. runnable/extensions/executor/__init__.py +0 -649
  30. runnable/extensions/executor/argo/__init__.py +0 -0
  31. runnable/extensions/executor/argo/implementation.py +0 -1194
  32. runnable/extensions/executor/argo/specification.yaml +0 -51
  33. runnable/extensions/executor/k8s_job/__init__.py +0 -0
  34. runnable/extensions/executor/k8s_job/implementation_FF.py +0 -259
  35. runnable/extensions/executor/k8s_job/integration_FF.py +0 -69
  36. runnable/extensions/executor/local/__init__.py +0 -0
  37. runnable/extensions/executor/local/implementation.py +0 -71
  38. runnable/extensions/executor/local_container/__init__.py +0 -0
  39. runnable/extensions/executor/local_container/implementation.py +0 -446
  40. runnable/extensions/executor/mocked/__init__.py +0 -0
  41. runnable/extensions/executor/mocked/implementation.py +0 -154
  42. runnable/extensions/executor/retry/__init__.py +0 -0
  43. runnable/extensions/executor/retry/implementation.py +0 -168
  44. runnable/extensions/nodes.py +0 -855
  45. runnable/extensions/run_log_store/__init__.py +0 -0
  46. runnable/extensions/run_log_store/chunked_file_system/__init__.py +0 -0
  47. runnable/extensions/run_log_store/chunked_file_system/implementation.py +0 -111
  48. runnable/extensions/run_log_store/chunked_k8s_pvc/__init__.py +0 -0
  49. runnable/extensions/run_log_store/chunked_k8s_pvc/implementation.py +0 -21
  50. runnable/extensions/run_log_store/chunked_k8s_pvc/integration.py +0 -61
  51. runnable/extensions/run_log_store/db/implementation_FF.py +0 -157
  52. runnable/extensions/run_log_store/db/integration_FF.py +0 -0
  53. runnable/extensions/run_log_store/file_system/__init__.py +0 -0
  54. runnable/extensions/run_log_store/file_system/implementation.py +0 -140
  55. runnable/extensions/run_log_store/generic_chunked.py +0 -557
  56. runnable/extensions/run_log_store/k8s_pvc/__init__.py +0 -0
  57. runnable/extensions/run_log_store/k8s_pvc/implementation.py +0 -21
  58. runnable/extensions/run_log_store/k8s_pvc/integration.py +0 -56
  59. runnable/extensions/secrets/__init__.py +0 -0
  60. runnable/extensions/secrets/dotenv/__init__.py +0 -0
  61. runnable/extensions/secrets/dotenv/implementation.py +0 -100
  62. runnable-0.12.3.dist-info/RECORD +0 -64
  63. runnable-0.12.3.dist-info/entry_points.txt +0 -41
  64. {runnable-0.12.3.dist-info → runnable-0.14.0.dist-info/licenses}/LICENSE +0 -0
@@ -1,168 +0,0 @@
1
- import logging
2
- from functools import cached_property
3
- from typing import Any, Dict, Optional
4
-
5
- from runnable import context, defaults, exceptions
6
- from runnable.datastore import RunLog
7
- from runnable.defaults import TypeMapVariable
8
- from runnable.extensions.executor import GenericExecutor
9
- from runnable.extensions.nodes import TaskNode
10
- from runnable.nodes import BaseNode
11
-
12
- logger = logging.getLogger(defaults.LOGGER_NAME)
13
-
14
-
15
- class RetryExecutor(GenericExecutor):
16
- """
17
- The skeleton of an executor class.
18
- Any implementation of an executor should inherit this class and over-ride accordingly.
19
-
20
- This is a loaded base class which has a lot of methods already implemented for "typical" executions.
21
- Look at the function docs to understand how to use them appropriately.
22
-
23
- For any implementation:
24
- 1). Who/when should the run log be set up?
25
- 2). Who/When should the step log be set up?
26
-
27
- """
28
-
29
- service_name: str = "retry"
30
- service_type: str = "executor"
31
- run_id: str
32
-
33
- _local: bool = True
34
- _original_run_log: Optional[RunLog] = None
35
- _restart_initiated: bool = False
36
-
37
- @property
38
- def _context(self):
39
- return context.run_context
40
-
41
- @cached_property
42
- def original_run_log(self):
43
- return self._context.run_log_store.get_run_log_by_id(
44
- run_id=self.run_id,
45
- full=True,
46
- )
47
-
48
- def _set_up_for_re_run(self, params: Dict[str, Any]) -> None:
49
- # Sync the previous run log catalog to this one.
50
- self._context.catalog_handler.sync_between_runs(previous_run_id=self.run_id, run_id=self._context.run_id)
51
-
52
- params.update(self.original_run_log.parameters)
53
-
54
- def _set_up_run_log(self, exists_ok=False):
55
- """
56
- Create a run log and put that in the run log store
57
-
58
- If exists_ok, we allow the run log to be already present in the run log store.
59
- """
60
- super()._set_up_run_log(exists_ok=exists_ok)
61
-
62
- # Should the parameters be copied from previous execution
63
- # self._set_up_for_re_run(params=params)
64
-
65
- def execute_from_graph(self, node: BaseNode, map_variable: TypeMapVariable = None, **kwargs):
66
- """
67
- This is the entry point to from the graph execution.
68
-
69
- While the self.execute_graph is responsible for traversing the graph, this function is responsible for
70
- actual execution of the node.
71
-
72
- If the node type is:
73
- * task : We can delegate to _execute_node after checking the eligibility for re-run in cases of a re-run
74
- * success: We can delegate to _execute_node
75
- * fail: We can delegate to _execute_node
76
-
77
- For nodes that are internally graphs:
78
- * parallel: Delegate the responsibility of execution to the node.execute_as_graph()
79
- * dag: Delegate the responsibility of execution to the node.execute_as_graph()
80
- * map: Delegate the responsibility of execution to the node.execute_as_graph()
81
-
82
- Transpilers will NEVER use this method and will NEVER call ths method.
83
- This method should only be used by interactive executors.
84
-
85
- Args:
86
- node (Node): The node to execute
87
- map_variable (dict, optional): If the node if of a map state, this corresponds to the value of iterable.
88
- Defaults to None.
89
- """
90
- step_log = self._context.run_log_store.create_step_log(node.name, node._get_step_log_name(map_variable))
91
-
92
- self.add_code_identities(node=node, step_log=step_log)
93
-
94
- step_log.step_type = node.node_type
95
- step_log.status = defaults.PROCESSING
96
-
97
- # Add the step log to the database as per the situation.
98
- # If its a terminal node, complete it now
99
- if node.node_type in ["success", "fail"]:
100
- self._context.run_log_store.add_step_log(step_log, self._context.run_id)
101
- self._execute_node(node, map_variable=map_variable, **kwargs)
102
- return
103
-
104
- # In retry step
105
- if not self._is_step_eligible_for_rerun(node, map_variable=map_variable):
106
- # If the node name does not match, we move on to the next node.
107
- # If previous run was successful, move on to the next step
108
- step_log.mock = True
109
- step_log.status = defaults.SUCCESS
110
- self._context.run_log_store.add_step_log(step_log, self._context.run_id)
111
- return
112
-
113
- # We call an internal function to iterate the sub graphs and execute them
114
- if node.is_composite:
115
- self._context.run_log_store.add_step_log(step_log, self._context.run_id)
116
- node.execute_as_graph(map_variable=map_variable, **kwargs)
117
- return
118
-
119
- # Executor specific way to trigger a job
120
- self._context.run_log_store.add_step_log(step_log, self._context.run_id)
121
- self.execute_node(node=node, map_variable=map_variable, **kwargs)
122
-
123
- def _is_step_eligible_for_rerun(self, node: BaseNode, map_variable: TypeMapVariable = None):
124
- """
125
- In case of a re-run, this method checks to see if the previous run step status to determine if a re-run is
126
- necessary.
127
- * True: If its not a re-run.
128
- * True: If its a re-run and we failed in the last run or the corresponding logs do not exist.
129
- * False: If its a re-run and we succeeded in the last run.
130
-
131
- Most cases, this logic need not be touched
132
-
133
- Args:
134
- node (Node): The node to check against re-run
135
- map_variable (dict, optional): If the node if of a map state, this corresponds to the value of iterable..
136
- Defaults to None.
137
-
138
- Returns:
139
- bool: Eligibility for re-run. True means re-run, False means skip to the next step.
140
- """
141
-
142
- node_step_log_name = node._get_step_log_name(map_variable=map_variable)
143
- logger.info(f"Scanning previous run logs for node logs of: {node_step_log_name}")
144
-
145
- if self._restart_initiated:
146
- return True
147
-
148
- try:
149
- previous_attempt_log, _ = self.original_run_log.search_step_by_internal_name(node_step_log_name)
150
- except exceptions.StepLogNotFoundError:
151
- logger.warning(f"Did not find the node {node.name} in previous run log")
152
- self._restart_initiated = True
153
- return True # We should re-run the node.
154
-
155
- logger.info(f"The original step status: {previous_attempt_log.status}")
156
-
157
- if previous_attempt_log.status == defaults.SUCCESS:
158
- return False # We need not run the node
159
-
160
- logger.info(f"The new execution should start executing graph from this node {node.name}")
161
- self._restart_initiated = True
162
- return True
163
-
164
- def execute_node(self, node: BaseNode, map_variable: TypeMapVariable = None, **kwargs):
165
- self._execute_node(node, map_variable=map_variable, **kwargs)
166
-
167
- def execute_job(self, node: TaskNode):
168
- pass