runnable 0.30.2__py3-none-any.whl → 0.30.4__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/catalog/any_path.py +4 -2
- extensions/job_executor/__init__.py +2 -1
- extensions/job_executor/k8s.py +6 -2
- extensions/job_executor/local.py +7 -2
- extensions/job_executor/local_container.py +7 -1
- extensions/nodes/torch.py +16 -1
- extensions/pipeline_executor/__init__.py +11 -7
- extensions/pipeline_executor/argo.py +1 -1
- runnable/catalog.py +6 -2
- runnable/executor.py +5 -1
- {runnable-0.30.2.dist-info → runnable-0.30.4.dist-info}/METADATA +1 -1
- {runnable-0.30.2.dist-info → runnable-0.30.4.dist-info}/RECORD +15 -15
- {runnable-0.30.2.dist-info → runnable-0.30.4.dist-info}/WHEEL +0 -0
- {runnable-0.30.2.dist-info → runnable-0.30.4.dist-info}/entry_points.txt +0 -0
- {runnable-0.30.2.dist-info → runnable-0.30.4.dist-info}/licenses/LICENSE +0 -0
extensions/catalog/any_path.py
CHANGED
@@ -94,7 +94,9 @@ class AnyPathCatalog(BaseCatalog):
|
|
94
94
|
|
95
95
|
return data_catalogs
|
96
96
|
|
97
|
-
def put(
|
97
|
+
def put(
|
98
|
+
self, name: str, allow_file_not_found_exc: bool = False
|
99
|
+
) -> List[DataCatalog]:
|
98
100
|
"""
|
99
101
|
Put the files matching the glob pattern into the catalog.
|
100
102
|
|
@@ -154,7 +156,7 @@ class AnyPathCatalog(BaseCatalog):
|
|
154
156
|
# TODO: Think about syncing only if the file is changed
|
155
157
|
self.upload_to_catalog(file)
|
156
158
|
|
157
|
-
if not data_catalogs:
|
159
|
+
if not data_catalogs and not allow_file_not_found_exc:
|
158
160
|
raise Exception(f"Did not find any files matching {name} in {copy_from}")
|
159
161
|
|
160
162
|
return data_catalogs
|
@@ -139,6 +139,7 @@ class GenericJobExecutor(BaseJobExecutor):
|
|
139
139
|
def _sync_catalog(
|
140
140
|
self,
|
141
141
|
catalog_settings=Optional[List[str]],
|
142
|
+
allow_file_not_found_exc: bool = False,
|
142
143
|
) -> List[DataCatalog] | None:
|
143
144
|
if not catalog_settings:
|
144
145
|
logger.info("No catalog settings found")
|
@@ -147,7 +148,7 @@ class GenericJobExecutor(BaseJobExecutor):
|
|
147
148
|
data_catalogs = []
|
148
149
|
for name_pattern in catalog_settings:
|
149
150
|
data_catalog = self._context.catalog_handler.put(
|
150
|
-
name=name_pattern,
|
151
|
+
name=name_pattern, allow_file_not_found_exc=allow_file_not_found_exc
|
151
152
|
)
|
152
153
|
|
153
154
|
logger.debug(f"Added data catalog: {data_catalog} to job log")
|
extensions/job_executor/k8s.py
CHANGED
@@ -7,7 +7,6 @@ from kubernetes import client
|
|
7
7
|
from kubernetes import config as k8s_config
|
8
8
|
from pydantic import BaseModel, ConfigDict, Field, PlainSerializer, PrivateAttr
|
9
9
|
from pydantic.alias_generators import to_camel
|
10
|
-
from rich import print
|
11
10
|
|
12
11
|
from extensions.job_executor import GenericJobExecutor
|
13
12
|
from runnable import console, defaults, utils
|
@@ -223,8 +222,13 @@ class GenericK8sJobExecutor(GenericJobExecutor):
|
|
223
222
|
job_log.status = attempt_log.status
|
224
223
|
job_log.attempts.append(attempt_log)
|
225
224
|
|
225
|
+
allow_file_not_found_exc = True
|
226
|
+
if job_log.status == defaults.SUCCESS:
|
227
|
+
allow_file_not_found_exc = False
|
228
|
+
|
226
229
|
data_catalogs_put: Optional[List[DataCatalog]] = self._sync_catalog(
|
227
|
-
catalog_settings=catalog_settings
|
230
|
+
catalog_settings=catalog_settings,
|
231
|
+
allow_file_not_found_exc=allow_file_not_found_exc,
|
228
232
|
)
|
229
233
|
logger.debug(f"data_catalogs_put: {data_catalogs_put}")
|
230
234
|
|
extensions/job_executor/local.py
CHANGED
@@ -55,11 +55,16 @@ class LocalJobExecutor(GenericJobExecutor):
|
|
55
55
|
job_log.status = attempt_log.status
|
56
56
|
job_log.attempts.append(attempt_log)
|
57
57
|
|
58
|
+
allow_file_not_found_exc = True
|
59
|
+
if job_log.status == defaults.SUCCESS:
|
60
|
+
allow_file_not_found_exc = False
|
61
|
+
|
58
62
|
data_catalogs_put: Optional[List[DataCatalog]] = self._sync_catalog(
|
59
|
-
catalog_settings=catalog_settings
|
63
|
+
catalog_settings=catalog_settings,
|
64
|
+
allow_file_not_found_exc=allow_file_not_found_exc,
|
60
65
|
)
|
61
|
-
logger.debug(f"data_catalogs_put: {data_catalogs_put}")
|
62
66
|
|
67
|
+
logger.debug(f"data_catalogs_put: {data_catalogs_put}")
|
63
68
|
job_log.add_data_catalogs(data_catalogs_put or [])
|
64
69
|
|
65
70
|
console.print("Summary of job")
|
@@ -64,9 +64,15 @@ class LocalContainerJobExecutor(GenericJobExecutor):
|
|
64
64
|
job_log.status = attempt_log.status
|
65
65
|
job_log.attempts.append(attempt_log)
|
66
66
|
|
67
|
+
allow_file_not_found_exc = True
|
68
|
+
if job_log.status == defaults.SUCCESS:
|
69
|
+
allow_file_not_found_exc = False
|
70
|
+
|
67
71
|
data_catalogs_put: Optional[List[DataCatalog]] = self._sync_catalog(
|
68
|
-
catalog_settings=catalog_settings
|
72
|
+
catalog_settings=catalog_settings,
|
73
|
+
allow_file_not_found_exc=allow_file_not_found_exc,
|
69
74
|
)
|
75
|
+
|
70
76
|
logger.debug(f"data_catalogs_put: {data_catalogs_put}")
|
71
77
|
|
72
78
|
job_log.add_data_catalogs(data_catalogs_put or [])
|
extensions/nodes/torch.py
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
import importlib
|
2
2
|
import logging
|
3
3
|
import os
|
4
|
+
import random
|
5
|
+
import string
|
4
6
|
from datetime import datetime
|
5
7
|
from typing import Any, Callable
|
6
8
|
|
@@ -28,7 +30,13 @@ def training_subprocess():
|
|
28
30
|
command = os.environ.get("RUNNABLE_TORCH_COMMAND")
|
29
31
|
run_id = os.environ.get("RUNNABLE_TORCH_RUN_ID", "")
|
30
32
|
parameters_files = os.environ.get("RUNNABLE_TORCH_PARAMETERS_FILES", "")
|
31
|
-
process_run_id =
|
33
|
+
process_run_id = (
|
34
|
+
run_id
|
35
|
+
+ "-"
|
36
|
+
+ os.environ.get("RANK", "")
|
37
|
+
+ "-"
|
38
|
+
+ "".join(random.choices(string.ascii_lowercase, k=3))
|
39
|
+
)
|
32
40
|
|
33
41
|
delete_env_vars_with_prefix("RUNNABLE_")
|
34
42
|
|
@@ -40,6 +48,13 @@ def training_subprocess():
|
|
40
48
|
job_id=process_run_id,
|
41
49
|
)
|
42
50
|
|
51
|
+
from runnable.context import run_context
|
52
|
+
|
53
|
+
job_log = run_context.run_log_store.get_run_log_by_id(run_id=run_context.run_id)
|
54
|
+
|
55
|
+
if job_log.status == defaults.FAIL:
|
56
|
+
raise Exception(f"Job {process_run_id} failed")
|
57
|
+
|
43
58
|
|
44
59
|
def get_callable_from_dotted_path(dotted_path) -> Callable:
|
45
60
|
try:
|
@@ -111,7 +111,7 @@ class GenericPipelineExecutor(BasePipelineExecutor):
|
|
111
111
|
)
|
112
112
|
|
113
113
|
def _sync_catalog(
|
114
|
-
self, stage: str, synced_catalogs=None
|
114
|
+
self, stage: str, synced_catalogs=None, allow_file_no_found_exc: bool = False
|
115
115
|
) -> Optional[List[DataCatalog]]:
|
116
116
|
"""
|
117
117
|
1). Identify the catalog settings by over-riding node settings with the global settings.
|
@@ -160,7 +160,7 @@ class GenericPipelineExecutor(BasePipelineExecutor):
|
|
160
160
|
|
161
161
|
elif stage == "put":
|
162
162
|
data_catalog = self._context.catalog_handler.put(
|
163
|
-
name=name_pattern,
|
163
|
+
name=name_pattern, allow_file_not_found_exc=allow_file_no_found_exc
|
164
164
|
)
|
165
165
|
else:
|
166
166
|
raise Exception(f"Stage {stage} not supported")
|
@@ -233,12 +233,16 @@ class GenericPipelineExecutor(BasePipelineExecutor):
|
|
233
233
|
mock=mock,
|
234
234
|
)
|
235
235
|
|
236
|
+
allow_file_not_found_exc = True
|
236
237
|
if step_log.status == defaults.SUCCESS:
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
238
|
+
# raise exception if we succeeded but the file was not found
|
239
|
+
allow_file_not_found_exc = False
|
240
|
+
|
241
|
+
data_catalogs_put: Optional[List[DataCatalog]] = self._sync_catalog(
|
242
|
+
stage="put", allow_file_no_found_exc=allow_file_not_found_exc
|
243
|
+
)
|
244
|
+
logger.debug(f"data_catalogs_put: {data_catalogs_put}")
|
245
|
+
step_log.add_data_catalogs(data_catalogs_put or [])
|
242
246
|
|
243
247
|
# get catalog should always be added to the step log
|
244
248
|
step_log.add_data_catalogs(data_catalogs_get or [])
|
@@ -658,7 +658,7 @@ class ArgoExecutor(GenericPipelineExecutor):
|
|
658
658
|
def _set_env_vars_to_task(
|
659
659
|
self, working_on: BaseNode, container_template: CoreContainerTemplate
|
660
660
|
):
|
661
|
-
if not isinstance(working_on, TaskNode) or isinstance(working_on, TorchNode):
|
661
|
+
if not (isinstance(working_on, TaskNode) or isinstance(working_on, TorchNode)):
|
662
662
|
return
|
663
663
|
|
664
664
|
global_envs: dict[str, str] = {}
|
runnable/catalog.py
CHANGED
@@ -76,7 +76,9 @@ class BaseCatalog(ABC, BaseModel):
|
|
76
76
|
raise NotImplementedError
|
77
77
|
|
78
78
|
@abstractmethod
|
79
|
-
def put(
|
79
|
+
def put(
|
80
|
+
self, name: str, allow_file_not_found_exc: bool = False
|
81
|
+
) -> List[DataCatalog]:
|
80
82
|
"""
|
81
83
|
Put the file by 'name' from the 'compute_data_folder' in the catalog for the run_id.
|
82
84
|
|
@@ -137,7 +139,9 @@ class DoNothingCatalog(BaseCatalog):
|
|
137
139
|
logger.info("Using a do-nothing catalog, doing nothing in get")
|
138
140
|
return []
|
139
141
|
|
140
|
-
def put(
|
142
|
+
def put(
|
143
|
+
self, name: str, allow_file_not_found_exc: bool = False
|
144
|
+
) -> List[DataCatalog]:
|
141
145
|
"""
|
142
146
|
Does nothing
|
143
147
|
"""
|
runnable/executor.py
CHANGED
@@ -123,6 +123,7 @@ class BaseJobExecutor(BaseExecutor):
|
|
123
123
|
def _sync_catalog(
|
124
124
|
self,
|
125
125
|
catalog_settings: Optional[List[str]],
|
126
|
+
allow_file_not_found_exc: bool = False,
|
126
127
|
) -> Optional[List[DataCatalog]]:
|
127
128
|
"""
|
128
129
|
1). Identify the catalog settings by over-riding node settings with the global settings.
|
@@ -175,7 +176,10 @@ class BasePipelineExecutor(BaseExecutor):
|
|
175
176
|
|
176
177
|
@abstractmethod
|
177
178
|
def _sync_catalog(
|
178
|
-
self,
|
179
|
+
self,
|
180
|
+
stage: str,
|
181
|
+
synced_catalogs=None,
|
182
|
+
allow_file_no_found_exc: bool = False,
|
179
183
|
) -> Optional[List[DataCatalog]]:
|
180
184
|
"""
|
181
185
|
1). Identify the catalog settings by over-riding node settings with the global settings.
|
@@ -1,26 +1,26 @@
|
|
1
1
|
extensions/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
2
|
extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
3
|
extensions/catalog/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
extensions/catalog/any_path.py,sha256=
|
4
|
+
extensions/catalog/any_path.py,sha256=atB5gWPRX6ptW6zwYeCVb_fh0qhs7WAFO9HIsnMZl98,7350
|
5
5
|
extensions/catalog/file_system.py,sha256=T_qFPFfrmykoAMc1rjNi_DBb437me8WPRcFglwAK744,1767
|
6
6
|
extensions/catalog/minio.py,sha256=R3GvfCxN1GTcs4bQIAWh79_GHDTVd14gnpKlzwFeKUI,2363
|
7
7
|
extensions/catalog/pyproject.toml,sha256=lLNxY6v04c8I5QK_zKw_E6sJTArSJRA_V-79ktaA3Hk,279
|
8
8
|
extensions/catalog/s3.py,sha256=Sw5t8_kVRprn3uGGJCiHn7M9zw1CLaCOFj6YErtfG0o,287
|
9
9
|
extensions/job_executor/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
|
-
extensions/job_executor/__init__.py,sha256=
|
11
|
-
extensions/job_executor/k8s.py,sha256=
|
10
|
+
extensions/job_executor/__init__.py,sha256=VeLuYCcShCIYT0TNtAXfUF9tOk4ZHoLzdTEvbsz0spM,5870
|
11
|
+
extensions/job_executor/k8s.py,sha256=0V7BL7ERmonVMgCsO-J57cxH__v8KomwukMwepH3qgs,16388
|
12
12
|
extensions/job_executor/k8s_job_spec.yaml,sha256=7aFpxHdO_p6Hkc3YxusUOuAQTD1Myu0yTPX9DrhxbOg,1158
|
13
|
-
extensions/job_executor/local.py,sha256=
|
14
|
-
extensions/job_executor/local_container.py,sha256=
|
13
|
+
extensions/job_executor/local.py,sha256=3ZbCFXBvbLlMp10JTmQJJrjBKG2keHI6SH8hEvmHDkA,2230
|
14
|
+
extensions/job_executor/local_container.py,sha256=1JcLJ0zrNSNHdubrSO9miN54iwvPLHqKMZ08aOC8WWo,6886
|
15
15
|
extensions/job_executor/pyproject.toml,sha256=UIEgiCYHTXcRWSByNMFuKJFKgxTBpQqTqyUecIsb_Vc,286
|
16
16
|
extensions/nodes/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
17
|
extensions/nodes/nodes.py,sha256=s9ub1dqy4qHjRQG6YElCdL7rCOTYNs9RUIrStZ6tEB4,28256
|
18
18
|
extensions/nodes/pyproject.toml,sha256=YTu-ETN3JNFSkMzzWeOwn4m-O2nbRH-PmiPBALDCUw4,278
|
19
|
-
extensions/nodes/torch.py,sha256=
|
19
|
+
extensions/nodes/torch.py,sha256=id0_HVkRcqL9_DPOI-b53vaDwRgVfGB-zZS3yrRej9g,6318
|
20
20
|
extensions/nodes/torch_config.py,sha256=yDvDADpnLhQsNtfH8qIztLHQ2LhYiOJEWljxpH9GZzs,1222
|
21
21
|
extensions/pipeline_executor/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
|
-
extensions/pipeline_executor/__init__.py,sha256=
|
23
|
-
extensions/pipeline_executor/argo.py,sha256
|
22
|
+
extensions/pipeline_executor/__init__.py,sha256=wfigTL2T9OHrmE8b2Ydmb8h6hr-oF--Yc2FectC7WaY,24623
|
23
|
+
extensions/pipeline_executor/argo.py,sha256=AEGSWVZulBL6EsvbVCaeBeTl2m_t5ymc6RFpMKhivis,37946
|
24
24
|
extensions/pipeline_executor/local.py,sha256=6oWUJ6b6NvIkpeQJBoCT1hbfX4_6WCB4HzMgHZ4ik1A,1887
|
25
25
|
extensions/pipeline_executor/local_container.py,sha256=3kZ2QCsrq_YjH9dcAz8v05knKShQ_JtbIU-IA_-G538,12724
|
26
26
|
extensions/pipeline_executor/mocked.py,sha256=0sMmypuvstBIv9uQg-WAcPrF3oOFpeEXNi6N8Nzdnl0,5680
|
@@ -41,14 +41,14 @@ extensions/secrets/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
|
|
41
41
|
extensions/secrets/dotenv.py,sha256=nADHXI6KJ_LUYOIe5EbtYH-21OBebSNVr0Pjb1GlZ7w,1573
|
42
42
|
extensions/secrets/pyproject.toml,sha256=mLJNImNcBlbLKHh-0ugVWT9V83R4RibyyYDtBCSqVF4,282
|
43
43
|
runnable/__init__.py,sha256=swvqdCjeddn40o4zjsluyahdVcU0r1arSRrxmRsvFEQ,673
|
44
|
-
runnable/catalog.py,sha256=
|
44
|
+
runnable/catalog.py,sha256=4msQxLhLKlsDDrHFnGauPYe-Or-q9g8_RYCn_4dpxaU,4466
|
45
45
|
runnable/cli.py,sha256=3BiKSj95h2Drn__YlchMPZ5rBMafuRb2OGIsVpbsO5Y,8788
|
46
46
|
runnable/context.py,sha256=by5uepmuCP0dmM9BmsliXihSes5QEFejwAsmekcqylE,1388
|
47
47
|
runnable/datastore.py,sha256=ZobM1aVkgeUJ2fZYt63IFDsoNzObwc93hdByegS5YKQ,32396
|
48
48
|
runnable/defaults.py,sha256=3o9IVGryyCE6PoQTOoaIaHHTbJGEzmdXMcwzOhwAYoI,3518
|
49
49
|
runnable/entrypoints.py,sha256=cDbhtmLUWdBh9K6hNusfQpSd5NadcX8V1K2JEDf_YAg,18984
|
50
50
|
runnable/exceptions.py,sha256=LFbp0-Qxg2PAMLEVt7w2whhBxSG-5pzUEv5qN-Rc4_c,3003
|
51
|
-
runnable/executor.py,sha256=
|
51
|
+
runnable/executor.py,sha256=UOsYJ3NkTGw4FTR0iePX7AOJzY7vODhZ62aqrwVMO1c,15143
|
52
52
|
runnable/graph.py,sha256=poQz5zcvq89ju_u5sYlunQLPbHnXTaUmjcvstPwvT4U,16536
|
53
53
|
runnable/names.py,sha256=vn92Kv9ANROYSZX6Z4z1v_WA3WiEdIYmG6KEStBFZug,8134
|
54
54
|
runnable/nodes.py,sha256=d1eLttMAcV7CTwTEqOuNwZqItANoLUkXJ73Xp-srlyI,17811
|
@@ -58,8 +58,8 @@ runnable/sdk.py,sha256=NZVQGaL4Zm2hwloRmqEgp8UPbBg9hY1abQGYnOgniPI,35128
|
|
58
58
|
runnable/secrets.py,sha256=4L_dBFxTgr8r_hHUD6RlZEtqaOHDRsFG5PXO5wlvMI0,2324
|
59
59
|
runnable/tasks.py,sha256=Qb1IhVxHv68E7vf3M3YCf7MGRHyjmsEEYBpEpiZ4mRI,29062
|
60
60
|
runnable/utils.py,sha256=hBr7oGwGL2VgfITlQCTz-a1iwvvf7Mfl-HY8UdENZac,19929
|
61
|
-
runnable-0.30.
|
62
|
-
runnable-0.30.
|
63
|
-
runnable-0.30.
|
64
|
-
runnable-0.30.
|
65
|
-
runnable-0.30.
|
61
|
+
runnable-0.30.4.dist-info/METADATA,sha256=S-5zecrqE4tU5MW4Fe1-2F-Q_hLU7fAXZ2oo9xVRRUw,10115
|
62
|
+
runnable-0.30.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
63
|
+
runnable-0.30.4.dist-info/entry_points.txt,sha256=PrjKrlfXPZaV_7hz8orGu4FDnatLqnhPOXljyllszdw,1880
|
64
|
+
runnable-0.30.4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
65
|
+
runnable-0.30.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|