runnable 0.11.0__py3-none-any.whl → 0.11.1__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 +4 -0
- runnable/cli.py +1 -0
- runnable/entrypoints.py +5 -0
- runnable/extensions/executor/__init__.py +2 -0
- runnable/sdk.py +37 -13
- runnable/tasks.py +95 -43
- {runnable-0.11.0.dist-info → runnable-0.11.1.dist-info}/METADATA +2 -3
- {runnable-0.11.0.dist-info → runnable-0.11.1.dist-info}/RECORD +11 -11
- {runnable-0.11.0.dist-info → runnable-0.11.1.dist-info}/LICENSE +0 -0
- {runnable-0.11.0.dist-info → runnable-0.11.1.dist-info}/WHEEL +0 -0
- {runnable-0.11.0.dist-info → runnable-0.11.1.dist-info}/entry_points.txt +0 -0
runnable/__init__.py
CHANGED
@@ -29,6 +29,10 @@ from runnable.sdk import ( # noqa
|
|
29
29
|
pickled,
|
30
30
|
)
|
31
31
|
|
32
|
+
## TODO: Summary should be a bit better for catalog.
|
33
|
+
## If the execution fails, hint them about the retry executor.
|
34
|
+
# Make the retry executor loose!
|
35
|
+
|
32
36
|
# TODO: Think of model registry as a central place to store models.
|
33
37
|
# TODO: Implement Sagemaker pipelines as a executor.
|
34
38
|
|
runnable/cli.py
CHANGED
runnable/entrypoints.py
CHANGED
@@ -172,6 +172,7 @@ def execute(
|
|
172
172
|
)
|
173
173
|
console.print("Working with context:")
|
174
174
|
console.print(run_context)
|
175
|
+
console.rule(style="[dark orange]")
|
175
176
|
|
176
177
|
executor = run_context.executor
|
177
178
|
|
@@ -243,6 +244,7 @@ def execute_single_node(
|
|
243
244
|
)
|
244
245
|
console.print("Working with context:")
|
245
246
|
console.print(run_context)
|
247
|
+
console.rule(style="[dark orange]")
|
246
248
|
|
247
249
|
executor = run_context.executor
|
248
250
|
run_context.execution_plan = defaults.EXECUTION_PLAN.CHAINED.value
|
@@ -296,6 +298,7 @@ def execute_notebook(
|
|
296
298
|
|
297
299
|
console.print("Working with context:")
|
298
300
|
console.print(run_context)
|
301
|
+
console.rule(style="[dark orange]")
|
299
302
|
|
300
303
|
step_config = {
|
301
304
|
"command": notebook_file,
|
@@ -358,6 +361,7 @@ def execute_function(
|
|
358
361
|
|
359
362
|
console.print("Working with context:")
|
360
363
|
console.print(run_context)
|
364
|
+
console.rule(style="[dark orange]")
|
361
365
|
|
362
366
|
# Prepare the graph with a single node
|
363
367
|
step_config = {
|
@@ -427,6 +431,7 @@ def fan(
|
|
427
431
|
)
|
428
432
|
console.print("Working with context:")
|
429
433
|
console.print(run_context)
|
434
|
+
console.rule(style="[dark orange]")
|
430
435
|
|
431
436
|
executor = run_context.executor
|
432
437
|
run_context.execution_plan = defaults.EXECUTION_PLAN.CHAINED.value
|
runnable/sdk.py
CHANGED
@@ -15,8 +15,13 @@ from pydantic import (
|
|
15
15
|
field_validator,
|
16
16
|
model_validator,
|
17
17
|
)
|
18
|
-
from rich import
|
19
|
-
|
18
|
+
from rich.progress import (
|
19
|
+
BarColumn,
|
20
|
+
Progress,
|
21
|
+
SpinnerColumn,
|
22
|
+
TextColumn,
|
23
|
+
TimeElapsedColumn,
|
24
|
+
)
|
20
25
|
from rich.table import Column
|
21
26
|
from typing_extensions import Self
|
22
27
|
|
@@ -71,7 +76,7 @@ class Catalog(BaseModel):
|
|
71
76
|
|
72
77
|
class BaseTraversal(ABC, BaseModel):
|
73
78
|
name: str
|
74
|
-
next_node: str = Field(default="",
|
79
|
+
next_node: str = Field(default="", serialization_alias="next_node")
|
75
80
|
terminate_with_success: bool = Field(default=False, exclude=True)
|
76
81
|
terminate_with_failure: bool = Field(default=False, exclude=True)
|
77
82
|
on_failure: str = Field(default="", alias="on_failure")
|
@@ -83,6 +88,12 @@ class BaseTraversal(ABC, BaseModel):
|
|
83
88
|
def internal_name(self) -> str:
|
84
89
|
return self.name
|
85
90
|
|
91
|
+
def __hash__(self):
|
92
|
+
"""
|
93
|
+
Needed to Uniqueize DataCatalog objects.
|
94
|
+
"""
|
95
|
+
return hash(self.name)
|
96
|
+
|
86
97
|
def __rshift__(self, other: StepType) -> StepType:
|
87
98
|
if self.next_node:
|
88
99
|
raise Exception(f"The node {self} already has a next node: {self.next_node}")
|
@@ -180,6 +191,7 @@ class BaseTask(BaseTraversal):
|
|
180
191
|
catalog: Optional[Catalog] = Field(default=None, alias="catalog")
|
181
192
|
overrides: Dict[str, Any] = Field(default_factory=dict, alias="overrides")
|
182
193
|
returns: List[Union[str, TaskReturns]] = Field(default_factory=list, alias="returns")
|
194
|
+
secrets: List[str] = Field(default_factory=list)
|
183
195
|
|
184
196
|
@field_validator("returns", mode="before")
|
185
197
|
@classmethod
|
@@ -201,7 +213,7 @@ class BaseTask(BaseTraversal):
|
|
201
213
|
if not (self.terminate_with_failure or self.terminate_with_success):
|
202
214
|
raise AssertionError("A node not being terminated must have a user defined next node")
|
203
215
|
|
204
|
-
return TaskNode.parse_from_config(self.model_dump(exclude_none=True))
|
216
|
+
return TaskNode.parse_from_config(self.model_dump(exclude_none=True, by_alias=True))
|
205
217
|
|
206
218
|
|
207
219
|
class PythonTask(BaseTask):
|
@@ -297,9 +309,9 @@ class NotebookTask(BaseTask):
|
|
297
309
|
|
298
310
|
"""
|
299
311
|
|
300
|
-
notebook: str = Field(
|
312
|
+
notebook: str = Field(serialization_alias="command")
|
301
313
|
|
302
|
-
notebook_output_path: Optional[str] = Field(default=None, alias="notebook_output_path")
|
314
|
+
notebook_output_path: Optional[str] = Field(default=None, alias="notebook_output_path", validate_default=True)
|
303
315
|
optional_ploomber_args: Optional[Dict[str, Any]] = Field(default=None, alias="optional_ploomber_args")
|
304
316
|
|
305
317
|
@computed_field
|
@@ -526,7 +538,7 @@ class Pipeline(BaseModel):
|
|
526
538
|
_dag: graph.Graph = PrivateAttr()
|
527
539
|
model_config = ConfigDict(extra="forbid")
|
528
540
|
|
529
|
-
def _validate_path(self, path: List[StepType]) -> None:
|
541
|
+
def _validate_path(self, path: List[StepType], failure_path: bool = False) -> None:
|
530
542
|
# Check if one and only one step terminates with success
|
531
543
|
# Check no more than one step terminates with failure
|
532
544
|
|
@@ -544,7 +556,7 @@ class Pipeline(BaseModel):
|
|
544
556
|
raise Exception("A pipeline cannot have more than one step that terminates with failure")
|
545
557
|
reached_failure = True
|
546
558
|
|
547
|
-
if not reached_success:
|
559
|
+
if not reached_success and not reached_failure:
|
548
560
|
raise Exception("A pipeline must have at least one step that terminates with success")
|
549
561
|
|
550
562
|
def _construct_path(self, path: List[StepType]) -> None:
|
@@ -594,11 +606,21 @@ class Pipeline(BaseModel):
|
|
594
606
|
|
595
607
|
# Check all paths are valid and construct the path
|
596
608
|
paths = [success_path] + on_failure_paths
|
609
|
+
failure_path = False
|
597
610
|
for path in paths:
|
598
|
-
self._validate_path(path)
|
611
|
+
self._validate_path(path, failure_path)
|
599
612
|
self._construct_path(path)
|
600
613
|
|
601
|
-
|
614
|
+
failure_path = True
|
615
|
+
|
616
|
+
all_steps: List[StepType] = []
|
617
|
+
|
618
|
+
for path in paths:
|
619
|
+
for step in path:
|
620
|
+
all_steps.append(step)
|
621
|
+
|
622
|
+
seen = set()
|
623
|
+
unique = [x for x in all_steps if not (x in seen or seen.add(x))] # type: ignore
|
602
624
|
|
603
625
|
self._dag = graph.Graph(
|
604
626
|
start_at=all_steps[0].name,
|
@@ -606,7 +628,7 @@ class Pipeline(BaseModel):
|
|
606
628
|
internal_branch_name=self.internal_branch_name,
|
607
629
|
)
|
608
630
|
|
609
|
-
for step in
|
631
|
+
for step in unique:
|
610
632
|
self._dag.add_node(step.create_node())
|
611
633
|
|
612
634
|
if self.add_terminal_nodes:
|
@@ -675,8 +697,9 @@ class Pipeline(BaseModel):
|
|
675
697
|
|
676
698
|
run_context.dag = graph.create_graph(dag_definition)
|
677
699
|
|
678
|
-
print("Working with context:")
|
679
|
-
print(run_context)
|
700
|
+
console.print("Working with context:")
|
701
|
+
console.print(run_context)
|
702
|
+
console.rule(style="[dark orange]")
|
680
703
|
|
681
704
|
if not run_context.executor._local:
|
682
705
|
# We are not working with non local executor
|
@@ -693,6 +716,7 @@ class Pipeline(BaseModel):
|
|
693
716
|
run_context.executor.prepare_for_graph_execution()
|
694
717
|
|
695
718
|
with Progress(
|
719
|
+
SpinnerColumn(spinner_name="runner"),
|
696
720
|
TextColumn("[progress.description]{task.description}", table_column=Column(ratio=2)),
|
697
721
|
BarColumn(table_column=Column(ratio=1), style="dark_orange"),
|
698
722
|
TimeElapsedColumn(table_column=Column(ratio=1)),
|
runnable/tasks.py
CHANGED
@@ -9,13 +9,14 @@ import sys
|
|
9
9
|
from datetime import datetime
|
10
10
|
from pickle import PicklingError
|
11
11
|
from string import Template
|
12
|
-
from typing import Any, Dict, List, Literal, Tuple
|
12
|
+
from typing import Any, Dict, List, Literal, Optional, Tuple
|
13
13
|
|
14
14
|
from pydantic import BaseModel, ConfigDict, Field, ValidationInfo, field_validator
|
15
|
+
from rich.console import Console
|
15
16
|
from stevedore import driver
|
16
17
|
|
17
18
|
import runnable.context as context
|
18
|
-
from runnable import
|
19
|
+
from runnable import defaults, exceptions, parameters, utils
|
19
20
|
from runnable.datastore import (
|
20
21
|
JsonParameter,
|
21
22
|
MetricParameter,
|
@@ -32,6 +33,9 @@ logging.getLogger("stevedore").setLevel(logging.CRITICAL)
|
|
32
33
|
# TODO: Can we add memory peak, cpu usage, etc. to the metrics?
|
33
34
|
|
34
35
|
|
36
|
+
console = Console(file=io.StringIO())
|
37
|
+
|
38
|
+
|
35
39
|
class TaskReturns(BaseModel):
|
36
40
|
name: str
|
37
41
|
kind: Literal["json", "object", "metric"] = Field(default="json")
|
@@ -42,7 +46,7 @@ class BaseTaskType(BaseModel):
|
|
42
46
|
|
43
47
|
task_type: str = Field(serialization_alias="command_type")
|
44
48
|
node_name: str = Field(exclude=True)
|
45
|
-
secrets:
|
49
|
+
secrets: List[str] = Field(default_factory=list)
|
46
50
|
returns: List[TaskReturns] = Field(default_factory=list, alias="returns")
|
47
51
|
|
48
52
|
model_config = ConfigDict(extra="forbid")
|
@@ -69,15 +73,14 @@ class BaseTaskType(BaseModel):
|
|
69
73
|
raise NotImplementedError()
|
70
74
|
|
71
75
|
def set_secrets_as_env_variables(self):
|
72
|
-
for key
|
76
|
+
for key in self.secrets:
|
73
77
|
secret_value = context.run_context.secrets_handler.get(key)
|
74
|
-
|
75
|
-
os.environ[value] = secret_value
|
78
|
+
os.environ[key] = secret_value
|
76
79
|
|
77
80
|
def delete_secrets_from_env_variables(self):
|
78
|
-
for
|
79
|
-
if
|
80
|
-
del os.environ[
|
81
|
+
for key in self.secrets:
|
82
|
+
if key in os.environ:
|
83
|
+
del os.environ[key]
|
81
84
|
|
82
85
|
def execute_command(
|
83
86
|
self,
|
@@ -135,17 +138,21 @@ class BaseTaskType(BaseModel):
|
|
135
138
|
if not allow_complex:
|
136
139
|
params = {key: value for key, value in params.items() if isinstance(value, JsonParameter)}
|
137
140
|
|
138
|
-
log_file_name = self.node_name
|
141
|
+
log_file_name = self.node_name # + ".execution.log"
|
139
142
|
if map_variable:
|
140
143
|
for _, value in map_variable.items():
|
141
144
|
log_file_name += "_" + str(value)
|
142
145
|
|
146
|
+
log_file_name = "".join(x for x in log_file_name if x.isalnum()) + ".execution.log"
|
147
|
+
|
143
148
|
log_file = open(log_file_name, "w")
|
144
149
|
|
145
150
|
f = io.StringIO()
|
146
151
|
try:
|
147
152
|
with contextlib.redirect_stdout(f):
|
153
|
+
# with contextlib.nullcontext():
|
148
154
|
yield params
|
155
|
+
print(console.file.getvalue()) # type: ignore
|
149
156
|
except Exception as e: # pylint: disable=broad-except
|
150
157
|
logger.exception(e)
|
151
158
|
finally:
|
@@ -156,10 +163,11 @@ class BaseTaskType(BaseModel):
|
|
156
163
|
log_file.close()
|
157
164
|
|
158
165
|
# Put the log file in the catalog
|
159
|
-
|
166
|
+
self._context.catalog_handler.put(name=log_file.name, run_id=context.run_context.run_id)
|
160
167
|
os.remove(log_file.name)
|
161
168
|
|
162
169
|
# Update parameters
|
170
|
+
# This should only update the parameters that are changed at the root level.
|
163
171
|
self._context.run_log_store.set_parameters(parameters=params, run_id=self._context.run_id)
|
164
172
|
|
165
173
|
|
@@ -219,8 +227,7 @@ class PythonTaskType(BaseTaskType): # pylint: disable=too-few-public-methods
|
|
219
227
|
logger.info(f"Calling {func} from {module} with {filtered_parameters}")
|
220
228
|
user_set_parameters = f(**filtered_parameters) # This is a tuple or single value
|
221
229
|
except Exception as e:
|
222
|
-
|
223
|
-
console.print(e, style=defaults.error_style)
|
230
|
+
console.log(e, style=defaults.error_style, markup=False)
|
224
231
|
raise exceptions.CommandCallError(f"Function call: {self.command} did not succeed.\n") from e
|
225
232
|
|
226
233
|
attempt_log.input_parameters = params.copy()
|
@@ -263,9 +270,9 @@ class PythonTaskType(BaseTaskType): # pylint: disable=too-few-public-methods
|
|
263
270
|
attempt_log.status = defaults.SUCCESS
|
264
271
|
except Exception as _e:
|
265
272
|
msg = f"Call to the function {self.command} did not succeed.\n"
|
266
|
-
logger.exception(_e)
|
267
273
|
attempt_log.message = msg
|
268
|
-
console.
|
274
|
+
console.print_exception(show_locals=False)
|
275
|
+
console.log(_e, style=defaults.error_style)
|
269
276
|
|
270
277
|
attempt_log.end_time = str(datetime.now())
|
271
278
|
|
@@ -277,7 +284,7 @@ class NotebookTaskType(BaseTaskType):
|
|
277
284
|
|
278
285
|
task_type: str = Field(default="notebook", serialization_alias="command_type")
|
279
286
|
command: str
|
280
|
-
notebook_output_path: str = Field(default=
|
287
|
+
notebook_output_path: Optional[str] = Field(default=None, validate_default=True)
|
281
288
|
optional_ploomber_args: dict = {}
|
282
289
|
|
283
290
|
@field_validator("command")
|
@@ -319,7 +326,7 @@ class NotebookTaskType(BaseTaskType):
|
|
319
326
|
import ploomber_engine as pm
|
320
327
|
from ploomber_engine.ipython import PloomberClient
|
321
328
|
|
322
|
-
notebook_output_path = self.notebook_output_path
|
329
|
+
notebook_output_path = self.notebook_output_path or ""
|
323
330
|
|
324
331
|
with self.execution_context(
|
325
332
|
map_variable=map_variable, allow_complex=False
|
@@ -424,15 +431,17 @@ class ShellTaskType(BaseTaskType):
|
|
424
431
|
|
425
432
|
# Expose secrets as environment variables
|
426
433
|
if self.secrets:
|
427
|
-
for key
|
434
|
+
for key in self.secrets:
|
428
435
|
secret_value = context.run_context.secrets_handler.get(key)
|
429
|
-
subprocess_env[
|
436
|
+
subprocess_env[key] = secret_value
|
430
437
|
|
431
438
|
with self.execution_context(map_variable=map_variable, allow_complex=False) as params:
|
432
439
|
subprocess_env.update({k: v.get_value() for k, v in params.items()})
|
433
440
|
|
434
441
|
# Json dumps all runnable environment variables
|
435
442
|
for key, value in subprocess_env.items():
|
443
|
+
if isinstance(value, str):
|
444
|
+
continue
|
436
445
|
subprocess_env[key] = json.dumps(value)
|
437
446
|
|
438
447
|
collect_delimiter = "=== COLLECT ==="
|
@@ -441,37 +450,80 @@ class ShellTaskType(BaseTaskType):
|
|
441
450
|
logger.info(f"Executing shell command: {command}")
|
442
451
|
|
443
452
|
capture = False
|
444
|
-
return_keys =
|
453
|
+
return_keys = {x.name: x for x in self.returns}
|
445
454
|
|
446
|
-
|
455
|
+
proc = subprocess.Popen(
|
447
456
|
command,
|
448
457
|
shell=True,
|
449
458
|
env=subprocess_env,
|
450
459
|
stdout=subprocess.PIPE,
|
451
460
|
stderr=subprocess.PIPE,
|
452
461
|
text=True,
|
453
|
-
)
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
462
|
+
)
|
463
|
+
result = proc.communicate()
|
464
|
+
logger.debug(result)
|
465
|
+
logger.info(proc.returncode)
|
466
|
+
|
467
|
+
if proc.returncode != 0:
|
468
|
+
msg = ",".join(result[1].split("\n"))
|
469
|
+
attempt_log.status = defaults.FAIL
|
470
|
+
attempt_log.end_time = str(datetime.now())
|
471
|
+
attempt_log.message = msg
|
472
|
+
console.print(msg, style=defaults.error_style)
|
473
|
+
return attempt_log
|
474
|
+
|
475
|
+
# for stderr
|
476
|
+
for line in result[1].split("\n"):
|
477
|
+
if line.strip() == "":
|
478
|
+
continue
|
479
|
+
console.print(line, style=defaults.warning_style)
|
480
|
+
|
481
|
+
output_parameters: Dict[str, Parameter] = {}
|
482
|
+
metrics: Dict[str, Parameter] = {}
|
483
|
+
|
484
|
+
# only from stdout
|
485
|
+
for line in result[0].split("\n"):
|
486
|
+
if line.strip() == "":
|
487
|
+
continue
|
488
|
+
|
489
|
+
logger.info(line)
|
490
|
+
console.print(line)
|
491
|
+
|
492
|
+
if line.strip() == collect_delimiter:
|
493
|
+
# The lines from now on should be captured
|
494
|
+
capture = True
|
495
|
+
continue
|
496
|
+
|
497
|
+
if capture:
|
498
|
+
key, value = line.strip().split("=", 1)
|
499
|
+
if key in return_keys:
|
500
|
+
task_return = return_keys[key]
|
501
|
+
|
502
|
+
try:
|
503
|
+
value = json.loads(value)
|
504
|
+
except json.JSONDecodeError:
|
505
|
+
value = value
|
506
|
+
|
507
|
+
output_parameter = task_return_to_parameter(
|
508
|
+
task_return=task_return,
|
509
|
+
value=value,
|
510
|
+
)
|
511
|
+
|
512
|
+
if task_return.kind == "metric":
|
513
|
+
metrics[task_return.name] = output_parameter
|
514
|
+
|
515
|
+
param_name = task_return.name
|
516
|
+
if map_variable:
|
517
|
+
for _, v in map_variable.items():
|
518
|
+
param_name = f"{param_name}_{v}"
|
519
|
+
|
520
|
+
output_parameters[param_name] = output_parameter
|
521
|
+
|
522
|
+
attempt_log.output_parameters = output_parameters
|
523
|
+
attempt_log.user_defined_metrics = metrics
|
524
|
+
params.update(output_parameters)
|
525
|
+
|
526
|
+
attempt_log.status = defaults.SUCCESS
|
475
527
|
|
476
528
|
attempt_log.end_time = str(datetime.now())
|
477
529
|
return attempt_log
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: runnable
|
3
|
-
Version: 0.11.
|
3
|
+
Version: 0.11.1
|
4
4
|
Summary: A Compute agnostic pipelining software
|
5
5
|
Home-page: https://github.com/vijayvammi/runnable
|
6
6
|
License: Apache-2.0
|
@@ -15,13 +15,12 @@ Classifier: Programming Language :: Python :: 3.11
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.12
|
16
16
|
Provides-Extra: database
|
17
17
|
Provides-Extra: docker
|
18
|
-
Provides-Extra: mlflow
|
19
18
|
Provides-Extra: notebook
|
20
19
|
Requires-Dist: click
|
21
20
|
Requires-Dist: click-plugins (>=1.1.1,<2.0.0)
|
22
21
|
Requires-Dist: dill (>=0.3.8,<0.4.0)
|
23
22
|
Requires-Dist: docker ; extra == "docker"
|
24
|
-
Requires-Dist: mlflow-skinny
|
23
|
+
Requires-Dist: mlflow-skinny
|
25
24
|
Requires-Dist: ploomber-engine (>=0.0.31,<0.0.32) ; extra == "notebook"
|
26
25
|
Requires-Dist: pydantic (>=2.5,<3.0)
|
27
26
|
Requires-Dist: rich (>=13.5.2,<14.0.0)
|
@@ -1,10 +1,10 @@
|
|
1
|
-
runnable/__init__.py,sha256=
|
1
|
+
runnable/__init__.py,sha256=C5ySSfN_vHWFTscnxLx3tfMjKT3Bs9jfUjXnDvun33Y,870
|
2
2
|
runnable/catalog.py,sha256=22OECi5TrpHErxYIhfx-lJ2vgBUi4-5V9CaYEVm98hE,4138
|
3
|
-
runnable/cli.py,sha256=
|
3
|
+
runnable/cli.py,sha256=RILUrEfzernuKD3dNdXPBkqN_1OgE5GosYRuInj0FVs,9618
|
4
4
|
runnable/context.py,sha256=QhiXJHRcEBfSKB1ijvL5yB9w44x0HCe7VEiwK1cUJ9U,1124
|
5
5
|
runnable/datastore.py,sha256=EgKi4_b5g6KbInpjMyw8Xwr-EgcSGi1Lx2u5vp4amSQ,27672
|
6
6
|
runnable/defaults.py,sha256=MOX7I2S6yO4FphZaZREFQca94a20oO8uvzXLd6GLKQs,4703
|
7
|
-
runnable/entrypoints.py,sha256
|
7
|
+
runnable/entrypoints.py,sha256=a8M7vb954as_ni7lM0t65czXQj2AHjB-KrQJ3zt3sWo,16397
|
8
8
|
runnable/exceptions.py,sha256=6NIYoTAzdKyGQ9PvW1Hu7b80OS746395KiGDhM7ThH8,2526
|
9
9
|
runnable/executor.py,sha256=xfBighQ5t_vejohip000XfxLwsgechUE1ZMIJWrZbUA,14484
|
10
10
|
runnable/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -14,7 +14,7 @@ runnable/extensions/catalog/file_system/implementation.py,sha256=9j920o9SULdcVp1
|
|
14
14
|
runnable/extensions/catalog/k8s_pvc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
15
|
runnable/extensions/catalog/k8s_pvc/implementation.py,sha256=oJDDI0APT7lrtjWmzYJRDHLGn3Vhbn2MdFSRYvFBUpY,436
|
16
16
|
runnable/extensions/catalog/k8s_pvc/integration.py,sha256=OfrHbNFN8sR-wsVa4os3ajmWJFSd5H4KOHGVAmjRZTQ,1850
|
17
|
-
runnable/extensions/executor/__init__.py,sha256=
|
17
|
+
runnable/extensions/executor/__init__.py,sha256=eV3q_dL2cRqYaJ8RWV6Xk1__KMWMM2hUnQFT7Z5pRso,26698
|
18
18
|
runnable/extensions/executor/argo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
19
|
runnable/extensions/executor/argo/implementation.py,sha256=_BfxCe742S6uV-7PuQ53KjzwY-8Rq-5y9txOXMYf20U,43670
|
20
20
|
runnable/extensions/executor/argo/specification.yaml,sha256=wXQcm2gOQYqy-IOQIhucohS32ZrHKCfGA5zZ0RraPYc,1276
|
@@ -55,12 +55,12 @@ runnable/names.py,sha256=vn92Kv9ANROYSZX6Z4z1v_WA3WiEdIYmG6KEStBFZug,8134
|
|
55
55
|
runnable/nodes.py,sha256=UqR-bJx0Hi7uLSUw_saB7VsNdFh3POKtdgsEPsasHfE,16576
|
56
56
|
runnable/parameters.py,sha256=KGGW8_uoIK2hd3EwzzBmoHBOrai3fh-SESNPpJRTfj4,5161
|
57
57
|
runnable/pickler.py,sha256=5SDNf0miMUJ3ZauhQdzwk8_t-9jeOqaTjP5bvRnu9sU,2685
|
58
|
-
runnable/sdk.py,sha256=
|
58
|
+
runnable/sdk.py,sha256=JsM27GUc3c57ZepK996FHtfzXP6FGs8MP-s96RC-_fo,27648
|
59
59
|
runnable/secrets.py,sha256=dakb7WRloWVo-KpQp6Vy4rwFdGi58BTlT4OifQY106I,2324
|
60
|
-
runnable/tasks.py,sha256=
|
60
|
+
runnable/tasks.py,sha256=CH0W7evAZK5hco0medJS6DwHRr06bng7oB7xk0Xh6zQ,20618
|
61
61
|
runnable/utils.py,sha256=okZFGbJWqStl5Rq5vLhNUQZDv_vhcT58bq9MDrTVxhc,19449
|
62
|
-
runnable-0.11.
|
63
|
-
runnable-0.11.
|
64
|
-
runnable-0.11.
|
65
|
-
runnable-0.11.
|
66
|
-
runnable-0.11.
|
62
|
+
runnable-0.11.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
63
|
+
runnable-0.11.1.dist-info/METADATA,sha256=IKuld8eA9gcb6y7YZaO-3Dpmw2x4U2wnPg0eag1fewU,17020
|
64
|
+
runnable-0.11.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
65
|
+
runnable-0.11.1.dist-info/entry_points.txt,sha256=Wy-dimdD2REO2a36Ri84fqGqA5iwGy2RIbdgRNtCNdM,1540
|
66
|
+
runnable-0.11.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|