runnable 0.13.0__py3-none-any.whl → 0.16.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 +1 -12
- runnable/catalog.py +29 -5
- runnable/cli.py +268 -215
- runnable/context.py +10 -3
- runnable/datastore.py +212 -53
- runnable/defaults.py +13 -55
- runnable/entrypoints.py +270 -183
- runnable/exceptions.py +28 -2
- runnable/executor.py +133 -86
- runnable/graph.py +37 -13
- runnable/nodes.py +50 -22
- runnable/parameters.py +27 -8
- runnable/pickler.py +1 -1
- runnable/sdk.py +230 -66
- runnable/secrets.py +3 -1
- runnable/tasks.py +99 -41
- runnable/utils.py +59 -39
- {runnable-0.13.0.dist-info → runnable-0.16.0.dist-info}/METADATA +28 -31
- runnable-0.16.0.dist-info/RECORD +23 -0
- {runnable-0.13.0.dist-info → runnable-0.16.0.dist-info}/WHEEL +1 -1
- runnable-0.16.0.dist-info/entry_points.txt +45 -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.py +0 -69
- 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 -870
- 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/integration.py +0 -192
- runnable-0.13.0.dist-info/RECORD +0 -63
- runnable-0.13.0.dist-info/entry_points.txt +0 -41
- {runnable-0.13.0.dist-info → runnable-0.16.0.dist-info/licenses}/LICENSE +0 -0
runnable/__init__.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# ruff: noqa
|
2
2
|
|
3
|
-
# TODO: Might need to add Rich to pyinstaller part
|
4
3
|
import logging
|
5
4
|
import os
|
6
5
|
from logging.config import dictConfig
|
@@ -20,6 +19,7 @@ task_console = Console(record=True)
|
|
20
19
|
from runnable.sdk import ( # noqa
|
21
20
|
Catalog,
|
22
21
|
Fail,
|
22
|
+
Job,
|
23
23
|
Map,
|
24
24
|
NotebookTask,
|
25
25
|
Parallel,
|
@@ -34,14 +34,3 @@ from runnable.sdk import ( # noqa
|
|
34
34
|
|
35
35
|
# Needed to disable ploomber telemetry
|
36
36
|
os.environ["PLOOMBER_STATS_ENABLED"] = "false"
|
37
|
-
|
38
|
-
## TODO: Summary should be a bit better for catalog.
|
39
|
-
## If the execution fails, hint them about the retry executor.
|
40
|
-
# Make the retry executor loose!
|
41
|
-
|
42
|
-
# TODO: Think of model registry as a central place to store models.
|
43
|
-
# TODO: Implement Sagemaker pipelines as a executor.
|
44
|
-
|
45
|
-
|
46
|
-
# TODO: Think of way of generating dag hash without executor configuration
|
47
|
-
# Try to get a release
|
runnable/catalog.py
CHANGED
@@ -10,6 +10,28 @@ from runnable.datastore import DataCatalog
|
|
10
10
|
|
11
11
|
logger = logging.getLogger(defaults.LOGGER_NAME)
|
12
12
|
|
13
|
+
# TODO: Should ** be allowed as glob pattern as it can potentially copy everything to catalog
|
14
|
+
|
15
|
+
|
16
|
+
def is_catalog_out_of_sync(
|
17
|
+
catalog, synced_catalogs=Optional[List[DataCatalog]]
|
18
|
+
) -> bool:
|
19
|
+
"""
|
20
|
+
Check if the catalog items are out of sync from already cataloged objects.
|
21
|
+
If they are, return False.
|
22
|
+
If the object does not exist or synced catalog does not exist, return True
|
23
|
+
"""
|
24
|
+
if not synced_catalogs:
|
25
|
+
return True # If nothing has been synced in the past
|
26
|
+
|
27
|
+
for synced_catalog in synced_catalogs:
|
28
|
+
if synced_catalog.catalog_relative_path == catalog.catalog_relative_path:
|
29
|
+
if synced_catalog.data_hash == catalog.data_hash:
|
30
|
+
return False
|
31
|
+
return True
|
32
|
+
|
33
|
+
return True # The object does not exist, sync it
|
34
|
+
|
13
35
|
|
14
36
|
# --8<-- [start:docs]
|
15
37
|
|
@@ -26,8 +48,7 @@ class BaseCatalog(ABC, BaseModel):
|
|
26
48
|
model_config = ConfigDict(extra="forbid")
|
27
49
|
|
28
50
|
@abstractmethod
|
29
|
-
def get_summary(self) -> Dict[str, Any]:
|
30
|
-
...
|
51
|
+
def get_summary(self) -> Dict[str, Any]: ...
|
31
52
|
|
32
53
|
@property
|
33
54
|
def _context(self):
|
@@ -38,7 +59,9 @@ class BaseCatalog(ABC, BaseModel):
|
|
38
59
|
return defaults.COMPUTE_DATA_FOLDER
|
39
60
|
|
40
61
|
@abstractmethod
|
41
|
-
def get(
|
62
|
+
def get(
|
63
|
+
self, name: str, run_id: str, compute_data_folder: str = "", **kwargs
|
64
|
+
) -> List[DataCatalog]:
|
42
65
|
"""
|
43
66
|
Get the catalog item by 'name' for the 'run id' and store it in compute data folder.
|
44
67
|
|
@@ -119,7 +142,9 @@ class DoNothingCatalog(BaseCatalog):
|
|
119
142
|
def get_summary(self) -> Dict[str, Any]:
|
120
143
|
return {}
|
121
144
|
|
122
|
-
def get(
|
145
|
+
def get(
|
146
|
+
self, name: str, run_id: str, compute_data_folder: str = "", **kwargs
|
147
|
+
) -> List[DataCatalog]:
|
123
148
|
"""
|
124
149
|
Does nothing
|
125
150
|
"""
|
@@ -145,4 +170,3 @@ class DoNothingCatalog(BaseCatalog):
|
|
145
170
|
Does nothing
|
146
171
|
"""
|
147
172
|
logger.info("Using a do-nothing catalog, doing nothing while sync between runs")
|
148
|
-
...
|
runnable/cli.py
CHANGED
@@ -1,112 +1,154 @@
|
|
1
|
-
# A dummy to trigger the PR
|
2
1
|
import logging
|
2
|
+
from enum import Enum
|
3
|
+
from typing import Annotated
|
3
4
|
|
4
|
-
import
|
5
|
-
from click_plugins import with_plugins
|
6
|
-
from pkg_resources import iter_entry_points
|
5
|
+
import typer
|
7
6
|
|
8
7
|
from runnable import defaults, entrypoints
|
9
8
|
|
10
9
|
logger = logging.getLogger(defaults.LOGGER_NAME)
|
11
10
|
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
All commands have options that you can see by runnable <command> --help
|
20
|
-
"""
|
21
|
-
pass
|
12
|
+
app = typer.Typer(
|
13
|
+
help=(
|
14
|
+
"Welcome to runnable. Please provide the command that you want to use."
|
15
|
+
"All commands have options that you can see by runnable <command> --help"
|
16
|
+
),
|
17
|
+
)
|
22
18
|
|
23
19
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
)
|
43
|
-
|
44
|
-
|
45
|
-
|
20
|
+
class LogLevel(str, Enum):
|
21
|
+
INFO = "INFO"
|
22
|
+
DEBUG = "DEBUG"
|
23
|
+
WARNING = "WARNING"
|
24
|
+
ERROR = "ERROR"
|
25
|
+
FATAL = "FATAL"
|
26
|
+
|
27
|
+
|
28
|
+
class ExecutionMode(str, Enum):
|
29
|
+
YAML = "yaml"
|
30
|
+
PYTHON = "python"
|
31
|
+
|
32
|
+
|
33
|
+
class FanMode(str, Enum):
|
34
|
+
IN = "in"
|
35
|
+
OUT = "out"
|
36
|
+
|
37
|
+
|
38
|
+
@app.command()
|
39
|
+
def execute(
|
40
|
+
yaml_file: Annotated[str, typer.Argument(help="The pipeline definition file")],
|
41
|
+
config_file: Annotated[
|
42
|
+
str,
|
43
|
+
typer.Option(
|
44
|
+
"--config", "-c", help="The configuration file specifying the services"
|
45
|
+
),
|
46
|
+
] = "",
|
47
|
+
parameters_file: Annotated[
|
48
|
+
str,
|
49
|
+
typer.Option(
|
50
|
+
"--parameters",
|
51
|
+
"-p",
|
52
|
+
help="Parameters, in yaml, accessible by the application",
|
53
|
+
),
|
54
|
+
] = "",
|
55
|
+
log_level: Annotated[
|
56
|
+
LogLevel,
|
57
|
+
typer.Option(
|
58
|
+
"--log-level",
|
59
|
+
help="The log level",
|
60
|
+
show_default=True,
|
61
|
+
case_sensitive=False,
|
62
|
+
),
|
63
|
+
] = LogLevel.WARNING,
|
64
|
+
tag: Annotated[str, typer.Option(help="A tag attached to the run")] = "",
|
65
|
+
run_id: Annotated[
|
66
|
+
str,
|
67
|
+
typer.Option(
|
68
|
+
help="An optional run_id, one would be generated if its not provided"
|
69
|
+
),
|
70
|
+
] = "",
|
71
|
+
):
|
46
72
|
"""
|
47
|
-
Execute a pipeline
|
73
|
+
Execute a pipeline defined by yaml file.
|
74
|
+
|
75
|
+
The executor is defined by executor block of the configuration file.
|
76
|
+
|
77
|
+
The behavior of this command depends on the executor type:
|
48
78
|
|
49
|
-
|
79
|
+
-- For local executors (local, local-container), the pipeline is executed in the current environment.
|
50
80
|
|
51
|
-
|
52
|
-
-f, --file TEXT The pipeline definition file [default: pipeline.yaml]
|
53
|
-
-c, --config-file TEXT config file, in yaml, to be used for the run [default: None]
|
54
|
-
-p, --parameters-file TEXT Parameters, in yaml, accessible by the application [default: None]
|
55
|
-
--log-level One of [INFO|DEBUG|WARNING|ERROR|FATAL]
|
56
|
-
The log level
|
57
|
-
[default: INFO]
|
58
|
-
--tag TEXT A tag attached to the run
|
59
|
-
[default: ]
|
60
|
-
--run-id TEXT An optional run_id, one would be generated if not
|
61
|
-
provided
|
81
|
+
-- For remote executors (argo, airflow), the pipeline translated to the specification.
|
62
82
|
"""
|
63
|
-
logger.setLevel(log_level)
|
83
|
+
logger.setLevel(log_level.value)
|
64
84
|
|
65
|
-
entrypoints.
|
85
|
+
entrypoints.execute_pipeline_yaml_spec(
|
66
86
|
configuration_file=config_file,
|
67
|
-
pipeline_file=
|
87
|
+
pipeline_file=yaml_file,
|
68
88
|
tag=tag,
|
69
89
|
run_id=run_id,
|
70
90
|
parameters_file=parameters_file,
|
71
91
|
)
|
72
92
|
|
73
93
|
|
74
|
-
@
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
94
|
+
@app.command(hidden=True)
|
95
|
+
def execute_single_node(
|
96
|
+
run_id: Annotated[
|
97
|
+
str,
|
98
|
+
typer.Argument(
|
99
|
+
help="An optional run_id, one would be generated if its not provided"
|
100
|
+
),
|
101
|
+
],
|
102
|
+
yaml_or_python_file: Annotated[
|
103
|
+
str, typer.Argument(help="The pipeline definition file")
|
104
|
+
],
|
105
|
+
step_name: Annotated[str, typer.Argument(help="The step name to execute")],
|
106
|
+
config_file: Annotated[
|
107
|
+
str,
|
108
|
+
typer.Option(
|
109
|
+
"--config", "-c", help="The configuration file specifying the services"
|
110
|
+
),
|
111
|
+
] = "",
|
112
|
+
parameters_file: Annotated[
|
113
|
+
str,
|
114
|
+
typer.Option(
|
115
|
+
"--parameters-file",
|
116
|
+
"-p",
|
117
|
+
help="Parameters, in yaml, accessible by the application",
|
118
|
+
),
|
119
|
+
] = "",
|
120
|
+
log_level: Annotated[
|
121
|
+
LogLevel,
|
122
|
+
typer.Option(
|
123
|
+
"--log-level",
|
124
|
+
help="The log level",
|
125
|
+
show_default=True,
|
126
|
+
case_sensitive=False,
|
127
|
+
),
|
128
|
+
] = LogLevel.INFO,
|
129
|
+
tag: Annotated[str, typer.Option(help="A tag attached to the run")] = "",
|
130
|
+
mode: Annotated[
|
131
|
+
ExecutionMode,
|
132
|
+
typer.Option(
|
133
|
+
"--mode",
|
134
|
+
"-m",
|
135
|
+
help="spec in yaml or python sdk",
|
136
|
+
),
|
137
|
+
] = ExecutionMode.YAML,
|
138
|
+
map_variable: Annotated[
|
139
|
+
str,
|
140
|
+
typer.Option(
|
141
|
+
"--map-variable",
|
142
|
+
help="The map variable dictionary in str",
|
143
|
+
show_default=True,
|
144
|
+
),
|
145
|
+
] = "",
|
146
|
+
):
|
147
|
+
logger.setLevel(log_level.value)
|
107
148
|
entrypoints.execute_single_node(
|
108
149
|
configuration_file=config_file,
|
109
|
-
pipeline_file=
|
150
|
+
pipeline_file=yaml_or_python_file,
|
151
|
+
mode=mode,
|
110
152
|
step_name=step_name,
|
111
153
|
map_variable=map_variable,
|
112
154
|
run_id=run_id,
|
@@ -115,157 +157,168 @@ def execute_single_node(run_id, step_name, map_variable, file, config_file, para
|
|
115
157
|
)
|
116
158
|
|
117
159
|
|
118
|
-
@
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
)
|
124
|
-
|
125
|
-
"
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
log_level
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
160
|
+
@app.command(hidden=True)
|
161
|
+
def fan(
|
162
|
+
run_id: Annotated[str, typer.Argument(help="The run id")],
|
163
|
+
step_name: Annotated[str, typer.Argument(help="The step name")],
|
164
|
+
python_or_yaml_file: Annotated[
|
165
|
+
str, typer.Argument(help="The pipeline definition file")
|
166
|
+
],
|
167
|
+
mode: Annotated[FanMode, typer.Option(help="fan in or fan out")],
|
168
|
+
map_variable: Annotated[
|
169
|
+
str,
|
170
|
+
typer.Option(
|
171
|
+
"--map-variable",
|
172
|
+
help="The map variable dictionary in str",
|
173
|
+
show_default=True,
|
174
|
+
),
|
175
|
+
],
|
176
|
+
config_file: Annotated[
|
177
|
+
str,
|
178
|
+
typer.Option(
|
179
|
+
"--config-file", "-c", help="The configuration file specifying the services"
|
180
|
+
),
|
181
|
+
] = "",
|
182
|
+
parameters_file: Annotated[
|
183
|
+
str,
|
184
|
+
typer.Option(
|
185
|
+
"--parameters-file",
|
186
|
+
"-p",
|
187
|
+
help="Parameters, in yaml, accessible by the application",
|
188
|
+
),
|
189
|
+
] = "",
|
190
|
+
log_level: Annotated[
|
191
|
+
LogLevel,
|
192
|
+
typer.Option(
|
193
|
+
"--log-level",
|
194
|
+
help="The log level",
|
195
|
+
show_default=True,
|
196
|
+
case_sensitive=False,
|
197
|
+
),
|
198
|
+
] = LogLevel.INFO,
|
199
|
+
tag: Annotated[str, typer.Option(help="A tag attached to the run")] = "",
|
154
200
|
):
|
155
|
-
|
156
|
-
External entry point to execute a Jupyter notebook in isolation.
|
157
|
-
|
158
|
-
The notebook would be executed in the environment defined by the config file or default if none.
|
159
|
-
The execution plan is unchained.
|
160
|
-
"""
|
161
|
-
logger.setLevel(log_level)
|
162
|
-
catalog_config = {"compute_data_folder": data_folder, "put": list(put_in_catalog) if put_in_catalog else None}
|
163
|
-
if not filename.endswith(".ipynb"):
|
164
|
-
raise Exception("A notebook should always have ipynb as the extension")
|
201
|
+
logger.setLevel(log_level.value)
|
165
202
|
|
166
|
-
|
167
|
-
|
168
|
-
notebook_file=filename,
|
169
|
-
catalog_config=catalog_config,
|
203
|
+
# Fan in or out
|
204
|
+
entrypoints.fan(
|
170
205
|
configuration_file=config_file,
|
171
|
-
|
172
|
-
|
173
|
-
|
206
|
+
pipeline_file=python_or_yaml_file,
|
207
|
+
step_name=step_name,
|
208
|
+
mode=mode,
|
209
|
+
map_variable=map_variable,
|
174
210
|
run_id=run_id,
|
211
|
+
tag=tag,
|
212
|
+
parameters_file=parameters_file,
|
175
213
|
)
|
176
214
|
|
177
215
|
|
178
|
-
@
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
)
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
)
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
216
|
+
@app.command()
|
217
|
+
def submit_job(
|
218
|
+
job_definition_file: Annotated[
|
219
|
+
str,
|
220
|
+
typer.Argument(
|
221
|
+
help=("The yaml file containing the job definition"),
|
222
|
+
),
|
223
|
+
],
|
224
|
+
config_file: Annotated[
|
225
|
+
str,
|
226
|
+
typer.Option(
|
227
|
+
"--config", "-c", help="The configuration file specifying the services"
|
228
|
+
),
|
229
|
+
] = "",
|
230
|
+
parameters_file: Annotated[
|
231
|
+
str,
|
232
|
+
typer.Option(
|
233
|
+
"--parameters",
|
234
|
+
"-p",
|
235
|
+
help="Parameters, in yaml, accessible by the application",
|
236
|
+
),
|
237
|
+
] = "",
|
238
|
+
log_level: Annotated[
|
239
|
+
LogLevel,
|
240
|
+
typer.Option(
|
241
|
+
"--log-level",
|
242
|
+
help="The log level",
|
243
|
+
show_default=True,
|
244
|
+
case_sensitive=False,
|
245
|
+
),
|
246
|
+
] = LogLevel.WARNING,
|
247
|
+
tag: Annotated[str, typer.Option(help="A tag attached to the run")] = "",
|
248
|
+
run_id: Annotated[
|
249
|
+
str,
|
250
|
+
typer.Option(
|
251
|
+
help="An optional run_id, one would be generated if its not provided"
|
252
|
+
),
|
253
|
+
] = "",
|
204
254
|
):
|
205
|
-
|
206
|
-
External entry point to execute a python function in isolation.
|
255
|
+
logger.setLevel(log_level.value)
|
207
256
|
|
208
|
-
|
209
|
-
The execution plan is unchained.
|
210
|
-
"""
|
211
|
-
logger.setLevel(log_level)
|
212
|
-
catalog_config = {"compute_data_folder": data_folder, "put": list(put_in_catalog) if put_in_catalog else None}
|
213
|
-
entrypoints.execute_function(
|
214
|
-
entrypoint=entrypoint,
|
215
|
-
command=command,
|
216
|
-
catalog_config=catalog_config,
|
257
|
+
entrypoints.execute_job_yaml_spec(
|
217
258
|
configuration_file=config_file,
|
218
|
-
|
259
|
+
job_definition_file=job_definition_file,
|
219
260
|
tag=tag,
|
220
261
|
run_id=run_id,
|
262
|
+
parameters_file=parameters_file,
|
221
263
|
)
|
222
264
|
|
223
265
|
|
224
|
-
@
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
"
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
""
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
266
|
+
@app.command(hidden=True)
|
267
|
+
def execute_job(
|
268
|
+
job_definition_file: Annotated[
|
269
|
+
str,
|
270
|
+
typer.Argument(
|
271
|
+
help=("The yaml file containing the job definition"),
|
272
|
+
),
|
273
|
+
],
|
274
|
+
run_id: Annotated[
|
275
|
+
str,
|
276
|
+
typer.Argument(help="An run_id, one would be generated if its not provided"),
|
277
|
+
],
|
278
|
+
config_file: Annotated[
|
279
|
+
str,
|
280
|
+
typer.Option(
|
281
|
+
"--config", "-c", help="The configuration file specifying the services"
|
282
|
+
),
|
283
|
+
] = "",
|
284
|
+
parameters_file: Annotated[
|
285
|
+
str,
|
286
|
+
typer.Option(
|
287
|
+
"--parameters",
|
288
|
+
"-p",
|
289
|
+
help="Parameters, in yaml, accessible by the application",
|
290
|
+
),
|
291
|
+
] = "",
|
292
|
+
mode: Annotated[
|
293
|
+
ExecutionMode,
|
294
|
+
typer.Option(
|
295
|
+
"--mode",
|
296
|
+
"-m",
|
297
|
+
help="spec in yaml or python sdk",
|
298
|
+
),
|
299
|
+
] = ExecutionMode.YAML,
|
300
|
+
log_level: Annotated[
|
301
|
+
LogLevel,
|
302
|
+
typer.Option(
|
303
|
+
"--log-level",
|
304
|
+
help="The log level",
|
305
|
+
show_default=True,
|
306
|
+
case_sensitive=False,
|
307
|
+
),
|
308
|
+
] = LogLevel.WARNING,
|
309
|
+
tag: Annotated[str, typer.Option(help="A tag attached to the run")] = "",
|
310
|
+
):
|
311
|
+
logger.setLevel(log_level.value)
|
255
312
|
|
256
|
-
|
257
|
-
entrypoints.fan(
|
313
|
+
entrypoints.execute_job_non_local(
|
258
314
|
configuration_file=config_file,
|
259
|
-
|
260
|
-
step_name=step_name,
|
315
|
+
job_definition_file=job_definition_file,
|
261
316
|
mode=mode,
|
262
|
-
map_variable=map_variable,
|
263
|
-
run_id=run_id,
|
264
317
|
tag=tag,
|
318
|
+
run_id=run_id,
|
265
319
|
parameters_file=parameters_file,
|
266
320
|
)
|
267
321
|
|
268
322
|
|
269
|
-
# Needed for the binary creation
|
270
323
|
if __name__ == "__main__":
|
271
|
-
|
324
|
+
app()
|
runnable/context.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import Dict, Optional
|
1
|
+
from typing import Dict, List, Optional
|
2
2
|
|
3
3
|
from pydantic import BaseModel, ConfigDict, Field, SerializeAsAny
|
4
4
|
from rich.progress import Progress
|
@@ -9,6 +9,7 @@ from runnable.executor import BaseExecutor
|
|
9
9
|
from runnable.graph import Graph
|
10
10
|
from runnable.pickler import BasePickler
|
11
11
|
from runnable.secrets import BaseSecrets
|
12
|
+
from runnable.tasks import BaseTaskType
|
12
13
|
|
13
14
|
|
14
15
|
class Context(BaseModel):
|
@@ -22,15 +23,21 @@ class Context(BaseModel):
|
|
22
23
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
23
24
|
|
24
25
|
pipeline_file: Optional[str] = ""
|
26
|
+
job_definition_file: Optional[str] = ""
|
25
27
|
parameters_file: Optional[str] = ""
|
26
28
|
configuration_file: Optional[str] = ""
|
29
|
+
from_sdk: bool = False
|
27
30
|
|
28
|
-
tag: str = ""
|
29
31
|
run_id: str = ""
|
32
|
+
|
33
|
+
tag: str = ""
|
30
34
|
variables: Dict[str, str] = {}
|
35
|
+
|
31
36
|
dag: Optional[Graph] = None
|
32
37
|
dag_hash: str = ""
|
33
|
-
|
38
|
+
|
39
|
+
job: Optional[BaseTaskType] = None
|
40
|
+
job_catalog_settings: Optional[List[str]] = []
|
34
41
|
|
35
42
|
|
36
43
|
run_context = None # type: Context # type: ignore
|