runnable 0.23.0__py3-none-any.whl → 0.25.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.
- extensions/nodes/nodes.py +4 -0
- runnable/cli.py +8 -4
- runnable/graph.py +0 -1
- runnable/tasks.py +34 -13
- runnable/utils.py +5 -1
- {runnable-0.23.0.dist-info → runnable-0.25.0.dist-info}/METADATA +1 -1
- {runnable-0.23.0.dist-info → runnable-0.25.0.dist-info}/RECORD +10 -10
- {runnable-0.23.0.dist-info → runnable-0.25.0.dist-info}/WHEEL +0 -0
- {runnable-0.23.0.dist-info → runnable-0.25.0.dist-info}/entry_points.txt +0 -0
- {runnable-0.23.0.dist-info → runnable-0.25.0.dist-info}/licenses/LICENSE +0 -0
extensions/nodes/nodes.py
CHANGED
@@ -661,6 +661,10 @@ class MapNode(CompositeNode):
|
|
661
661
|
|
662
662
|
self._context.run_log_store.add_step_log(step_log, self._context.run_id)
|
663
663
|
|
664
|
+
# If we failed, we return without any collection
|
665
|
+
if not step_log.status == defaults.SUCCESS:
|
666
|
+
return
|
667
|
+
|
664
668
|
# Apply the reduce function and reduce the returns of the task nodes.
|
665
669
|
# The final value of the parameter is the result of the reduce function.
|
666
670
|
reducer_f = self.get_reducer_function()
|
runnable/cli.py
CHANGED
@@ -64,8 +64,9 @@ def execute(
|
|
64
64
|
tag: Annotated[str, typer.Option(help="A tag attached to the run")] = "",
|
65
65
|
run_id: Annotated[
|
66
66
|
str,
|
67
|
-
typer.
|
68
|
-
|
67
|
+
typer.Argument(
|
68
|
+
envvar=defaults.ENV_RUN_ID,
|
69
|
+
help="An optional run_id, one would be generated if its not provided",
|
69
70
|
),
|
70
71
|
] = "",
|
71
72
|
):
|
@@ -282,8 +283,11 @@ def execute_job(
|
|
282
283
|
],
|
283
284
|
run_id: Annotated[
|
284
285
|
str,
|
285
|
-
typer.Argument(
|
286
|
-
|
286
|
+
typer.Argument(
|
287
|
+
envvar="RUNNABLE_RUN_ID",
|
288
|
+
help="An optional run_id, one would be generated if its not provided",
|
289
|
+
),
|
290
|
+
] = "",
|
287
291
|
config_file: Annotated[
|
288
292
|
str,
|
289
293
|
typer.Option(
|
runnable/graph.py
CHANGED
runnable/tasks.py
CHANGED
@@ -31,7 +31,26 @@ logger = logging.getLogger(defaults.LOGGER_NAME)
|
|
31
31
|
logging.getLogger("stevedore").setLevel(logging.CRITICAL)
|
32
32
|
|
33
33
|
|
34
|
-
|
34
|
+
class TeeIO(io.StringIO):
|
35
|
+
"""
|
36
|
+
A custom class to write to the buffer and the output stream at the same time.
|
37
|
+
"""
|
38
|
+
|
39
|
+
def __init__(self, output_stream=sys.stdout):
|
40
|
+
super().__init__()
|
41
|
+
self.output_stream = output_stream
|
42
|
+
|
43
|
+
def write(self, s):
|
44
|
+
super().write(s) # Write to the buffer
|
45
|
+
self.output_stream.write(s) # Write to the output stream
|
46
|
+
|
47
|
+
def flush(self):
|
48
|
+
super().flush()
|
49
|
+
self.output_stream.flush()
|
50
|
+
|
51
|
+
|
52
|
+
buffer = TeeIO()
|
53
|
+
sys.stdout = buffer
|
35
54
|
|
36
55
|
|
37
56
|
class TaskReturns(BaseModel):
|
@@ -152,6 +171,7 @@ class BaseTaskType(BaseModel):
|
|
152
171
|
key: value
|
153
172
|
for key, value in params.items()
|
154
173
|
if isinstance(value, JsonParameter)
|
174
|
+
or isinstance(value, MetricParameter)
|
155
175
|
}
|
156
176
|
|
157
177
|
parameters_in = copy.deepcopy(params)
|
@@ -274,7 +294,7 @@ class PythonTaskType(BaseTaskType): # pylint: disable=too-few-public-methods
|
|
274
294
|
f"Calling {func} from {module} with {filtered_parameters}"
|
275
295
|
)
|
276
296
|
|
277
|
-
out_file =
|
297
|
+
out_file = TeeIO()
|
278
298
|
with contextlib.redirect_stdout(out_file):
|
279
299
|
user_set_parameters = f(
|
280
300
|
**filtered_parameters
|
@@ -284,16 +304,15 @@ class PythonTaskType(BaseTaskType): # pylint: disable=too-few-public-methods
|
|
284
304
|
raise exceptions.CommandCallError(
|
285
305
|
f"Function call: {self.command} did not succeed.\n"
|
286
306
|
) from e
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
)
|
307
|
+
finally:
|
308
|
+
attempt_log.input_parameters = params.copy()
|
309
|
+
if map_variable:
|
310
|
+
attempt_log.input_parameters.update(
|
311
|
+
{
|
312
|
+
k: JsonParameter(value=v, kind="json")
|
313
|
+
for k, v in map_variable.items()
|
314
|
+
}
|
315
|
+
)
|
297
316
|
|
298
317
|
if self.returns:
|
299
318
|
if not isinstance(user_set_parameters, tuple): # make it a tuple
|
@@ -448,6 +467,7 @@ class NotebookTaskType(BaseTaskType):
|
|
448
467
|
) as params,
|
449
468
|
self.expose_secrets() as _,
|
450
469
|
):
|
470
|
+
attempt_log.input_parameters = params.copy()
|
451
471
|
copy_params = copy.deepcopy(params)
|
452
472
|
|
453
473
|
if map_variable:
|
@@ -476,7 +496,7 @@ class NotebookTaskType(BaseTaskType):
|
|
476
496
|
}
|
477
497
|
kwds.update(ploomber_optional_args)
|
478
498
|
|
479
|
-
out_file =
|
499
|
+
out_file = TeeIO()
|
480
500
|
with contextlib.redirect_stdout(out_file):
|
481
501
|
pm.execute_notebook(**kwds)
|
482
502
|
task_console.print(out_file.getvalue())
|
@@ -635,6 +655,7 @@ class ShellTaskType(BaseTaskType):
|
|
635
655
|
) as params:
|
636
656
|
subprocess_env.update({k: v.get_value() for k, v in params.items()})
|
637
657
|
|
658
|
+
attempt_log.input_parameters = params.copy()
|
638
659
|
# Json dumps all runnable environment variables
|
639
660
|
for key, value in subprocess_env.items():
|
640
661
|
if isinstance(value, str):
|
runnable/utils.py
CHANGED
@@ -77,7 +77,11 @@ def generate_run_id(run_id: str = "") -> str:
|
|
77
77
|
Returns:
|
78
78
|
str: A generated run_id
|
79
79
|
"""
|
80
|
-
# If we are not provided with a run_id,
|
80
|
+
# If we are not provided with a run_id, check env var
|
81
|
+
if not run_id:
|
82
|
+
run_id = os.environ.get(defaults.ENV_RUN_ID, "")
|
83
|
+
|
84
|
+
# If both are not given, generate one
|
81
85
|
if not run_id:
|
82
86
|
now = datetime.now()
|
83
87
|
run_id = f"{names.get_random_name()}-{now.hour:02}{now.minute:02}"
|
@@ -11,7 +11,7 @@ extensions/job_executor/local.py,sha256=FvxTk0vyxdrbLOAyNkLyjvmmowypabWOSITQBK_f
|
|
11
11
|
extensions/job_executor/local_container.py,sha256=hyFnpicCp3_87mZsW64P6KSVbz7XMLjwJUWVjeCJ0_I,6627
|
12
12
|
extensions/job_executor/pyproject.toml,sha256=UIEgiCYHTXcRWSByNMFuKJFKgxTBpQqTqyUecIsb_Vc,286
|
13
13
|
extensions/nodes/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
|
-
extensions/nodes/nodes.py,sha256=
|
14
|
+
extensions/nodes/nodes.py,sha256=WdOmep4uxmY2mTOtsuVZ5QhYl96jqJprkG6jkIg7BVg,34774
|
15
15
|
extensions/nodes/pyproject.toml,sha256=YTu-ETN3JNFSkMzzWeOwn4m-O2nbRH-PmiPBALDCUw4,278
|
16
16
|
extensions/pipeline_executor/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
17
|
extensions/pipeline_executor/__init__.py,sha256=bobyC4BWmDKCnMQsuyj9buQX7tZOFxuwU3Coq9-QgR0,25568
|
@@ -34,24 +34,24 @@ extensions/secrets/dotenv.py,sha256=FbYYd_pVuJuVuIDIvXbzKuSSQ9GPq7xJXTDbJMTQbhM,
|
|
34
34
|
extensions/secrets/pyproject.toml,sha256=mLJNImNcBlbLKHh-0ugVWT9V83R4RibyyYDtBCSqVF4,282
|
35
35
|
runnable/__init__.py,sha256=n14AnTUUEYxXlTJ6-YLT0tMmeFb7Co_3kNldV6pgKSs,662
|
36
36
|
runnable/catalog.py,sha256=b9N40kTv1IBidzlWjkHcBGyYhq6qIDHZfBuFenzjsMI,4924
|
37
|
-
runnable/cli.py,sha256=
|
37
|
+
runnable/cli.py,sha256=3BiKSj95h2Drn__YlchMPZ5rBMafuRb2OGIsVpbsO5Y,8788
|
38
38
|
runnable/context.py,sha256=by5uepmuCP0dmM9BmsliXihSes5QEFejwAsmekcqylE,1388
|
39
39
|
runnable/datastore.py,sha256=9y5enzn6AXLHLdwvgkdjGPrBkVlrcjfbaAHsst-lJzg,32466
|
40
40
|
runnable/defaults.py,sha256=3o9IVGryyCE6PoQTOoaIaHHTbJGEzmdXMcwzOhwAYoI,3518
|
41
41
|
runnable/entrypoints.py,sha256=xkUa568-7x9xALz13qW14DxS1nnLDKwLwdIBJZG-vM0,18982
|
42
42
|
runnable/exceptions.py,sha256=LFbp0-Qxg2PAMLEVt7w2whhBxSG-5pzUEv5qN-Rc4_c,3003
|
43
43
|
runnable/executor.py,sha256=ne-iRQqGuEmmuApnkBDz1_hokVcjFrbe7BvWqXCG1Ys,15684
|
44
|
-
runnable/graph.py,sha256=
|
44
|
+
runnable/graph.py,sha256=poQz5zcvq89ju_u5sYlunQLPbHnXTaUmjcvstPwvT4U,16536
|
45
45
|
runnable/names.py,sha256=vn92Kv9ANROYSZX6Z4z1v_WA3WiEdIYmG6KEStBFZug,8134
|
46
46
|
runnable/nodes.py,sha256=YU9u7r1ESzui1uVtJ1dgwdv1ozyJnF2k-MCFieT8CLI,17519
|
47
47
|
runnable/parameters.py,sha256=LyQb1d0SaFeI4PJ_yDYt9wArm9ThSPASWb36TwIdDUs,5213
|
48
48
|
runnable/pickler.py,sha256=ydJ_eti_U1F4l-YacFp7BWm6g5vTn04UXye25S1HVok,2684
|
49
49
|
runnable/sdk.py,sha256=T1nqDpLN9fULvvU9L-oY0EHqYdKUI9qk7oekLynm02Y,33568
|
50
50
|
runnable/secrets.py,sha256=PXcEJw-4WPzeWRLfsatcPPyr1zkqgHzdRWRcS9vvpvM,2354
|
51
|
-
runnable/tasks.py,sha256=
|
52
|
-
runnable/utils.py,sha256=
|
53
|
-
runnable-0.
|
54
|
-
runnable-0.
|
55
|
-
runnable-0.
|
56
|
-
runnable-0.
|
57
|
-
runnable-0.
|
51
|
+
runnable/tasks.py,sha256=SYy9eZOs1iCwu1IX5O9WyXk6DMpVsqaruQtMX-YX0bY,29207
|
52
|
+
runnable/utils.py,sha256=hJUfRmIgU20weWPmBOHF22F6svBU0A_0nqifRMuXKs0,19822
|
53
|
+
runnable-0.25.0.dist-info/METADATA,sha256=bpDSeecHPHb9qCHycgxbAtPFpuEx73t1bO_OAal8dN8,9945
|
54
|
+
runnable-0.25.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
55
|
+
runnable-0.25.0.dist-info/entry_points.txt,sha256=seek5WVGvwYALm8lZ0TfPXwG5NaCeUKjU8urF8k3gvY,1621
|
56
|
+
runnable-0.25.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
57
|
+
runnable-0.25.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|