runnable 0.23.0__tar.gz → 0.25.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {runnable-0.23.0 → runnable-0.25.0}/PKG-INFO +1 -1
- {runnable-0.23.0 → runnable-0.25.0}/extensions/nodes/nodes.py +4 -0
- {runnable-0.23.0 → runnable-0.25.0}/pyproject.toml +1 -1
- {runnable-0.23.0 → runnable-0.25.0}/runnable/cli.py +8 -4
- {runnable-0.23.0 → runnable-0.25.0}/runnable/graph.py +0 -1
- {runnable-0.23.0 → runnable-0.25.0}/runnable/tasks.py +34 -13
- {runnable-0.23.0 → runnable-0.25.0}/runnable/utils.py +5 -1
- {runnable-0.23.0 → runnable-0.25.0}/.gitignore +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/LICENSE +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/README.md +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/README.md +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/__init__.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/catalog/README.md +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/catalog/file_system.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/catalog/pyproject.toml +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/job_executor/README.md +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/job_executor/__init__.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/job_executor/k8s.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/job_executor/k8s_job_spec.yaml +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/job_executor/local.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/job_executor/local_container.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/job_executor/pyproject.toml +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/nodes/README.md +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/nodes/pyproject.toml +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/pipeline_executor/README.md +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/pipeline_executor/__init__.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/pipeline_executor/argo.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/pipeline_executor/local.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/pipeline_executor/local_container.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/pipeline_executor/mocked.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/pipeline_executor/pyproject.toml +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/pipeline_executor/retry.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/run_log_store/README.md +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/run_log_store/__init__.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/run_log_store/chunked_fs.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/run_log_store/db/implementation_FF.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/run_log_store/db/integration_FF.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/run_log_store/file_system.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/run_log_store/generic_chunked.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/run_log_store/pyproject.toml +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/secrets/README.md +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/secrets/dotenv.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/extensions/secrets/pyproject.toml +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/runnable/__init__.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/runnable/catalog.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/runnable/context.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/runnable/datastore.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/runnable/defaults.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/runnable/entrypoints.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/runnable/exceptions.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/runnable/executor.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/runnable/names.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/runnable/nodes.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/runnable/parameters.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/runnable/pickler.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/runnable/sdk.py +0 -0
- {runnable-0.23.0 → runnable-0.25.0}/runnable/secrets.py +0 -0
@@ -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()
|
@@ -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(
|
@@ -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):
|
@@ -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}"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|