digitalhub 0.8.0b15__py3-none-any.whl → 0.9.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.
Potentially problematic release.
This version of digitalhub might be problematic. Click here for more details.
- digitalhub/__init__.py +19 -2
- digitalhub/client/_base/api_builder.py +16 -0
- digitalhub/client/_base/client.py +67 -0
- digitalhub/client/_base/key_builder.py +52 -0
- digitalhub/client/api.py +2 -38
- digitalhub/client/dhcore/api_builder.py +100 -0
- digitalhub/client/dhcore/client.py +100 -48
- digitalhub/client/dhcore/enums.py +27 -0
- digitalhub/client/dhcore/env.py +4 -2
- digitalhub/client/dhcore/key_builder.py +58 -0
- digitalhub/client/dhcore/utils.py +17 -17
- digitalhub/client/local/api_builder.py +100 -0
- digitalhub/client/local/client.py +22 -0
- digitalhub/client/local/key_builder.py +58 -0
- digitalhub/context/api.py +3 -38
- digitalhub/context/builder.py +10 -23
- digitalhub/context/context.py +20 -92
- digitalhub/entities/_base/context/entity.py +30 -22
- digitalhub/entities/_base/entity/_constructors/metadata.py +12 -1
- digitalhub/entities/_base/entity/_constructors/name.py +1 -1
- digitalhub/entities/_base/entity/_constructors/spec.py +1 -1
- digitalhub/entities/_base/entity/_constructors/status.py +3 -2
- digitalhub/entities/_base/entity/_constructors/uuid.py +1 -1
- digitalhub/entities/_base/entity/builder.py +6 -1
- digitalhub/entities/_base/entity/entity.py +32 -10
- digitalhub/entities/_base/entity/metadata.py +22 -0
- digitalhub/entities/_base/entity/spec.py +7 -2
- digitalhub/entities/_base/executable/entity.py +8 -8
- digitalhub/entities/_base/material/entity.py +49 -17
- digitalhub/entities/_base/material/status.py +0 -31
- digitalhub/entities/_base/material/utils.py +106 -0
- digitalhub/entities/_base/project/entity.py +341 -0
- digitalhub/entities/_base/unversioned/entity.py +3 -24
- digitalhub/entities/_base/versioned/entity.py +2 -26
- digitalhub/entities/_commons/enums.py +103 -0
- digitalhub/entities/_commons/utils.py +83 -0
- digitalhub/entities/_operations/processor.py +1873 -0
- digitalhub/entities/artifact/_base/builder.py +1 -1
- digitalhub/entities/artifact/_base/entity.py +1 -1
- digitalhub/entities/artifact/artifact/builder.py +2 -1
- digitalhub/entities/artifact/crud.py +46 -29
- digitalhub/entities/artifact/utils.py +62 -0
- digitalhub/entities/dataitem/_base/builder.py +1 -1
- digitalhub/entities/dataitem/_base/entity.py +6 -6
- digitalhub/entities/dataitem/crud.py +50 -66
- digitalhub/entities/dataitem/dataitem/builder.py +2 -1
- digitalhub/entities/dataitem/iceberg/builder.py +2 -1
- digitalhub/entities/dataitem/table/builder.py +2 -1
- digitalhub/entities/dataitem/table/entity.py +5 -10
- digitalhub/entities/dataitem/table/models.py +4 -5
- digitalhub/entities/dataitem/utils.py +137 -0
- digitalhub/entities/function/_base/builder.py +1 -1
- digitalhub/entities/function/_base/entity.py +6 -2
- digitalhub/entities/function/crud.py +36 -17
- digitalhub/entities/model/_base/builder.py +1 -1
- digitalhub/entities/model/_base/entity.py +1 -1
- digitalhub/entities/model/crud.py +46 -29
- digitalhub/entities/model/huggingface/builder.py +2 -1
- digitalhub/entities/model/huggingface/spec.py +4 -2
- digitalhub/entities/model/mlflow/builder.py +2 -1
- digitalhub/entities/model/mlflow/models.py +17 -9
- digitalhub/entities/model/mlflow/spec.py +6 -1
- digitalhub/entities/model/mlflow/utils.py +4 -2
- digitalhub/entities/model/model/builder.py +2 -1
- digitalhub/entities/model/sklearn/builder.py +2 -1
- digitalhub/entities/model/utils.py +62 -0
- digitalhub/entities/project/_base/builder.py +2 -2
- digitalhub/entities/project/_base/entity.py +82 -272
- digitalhub/entities/project/crud.py +110 -89
- digitalhub/entities/project/utils.py +35 -0
- digitalhub/entities/run/_base/builder.py +3 -1
- digitalhub/entities/run/_base/entity.py +52 -54
- digitalhub/entities/run/_base/spec.py +15 -7
- digitalhub/entities/run/crud.py +35 -17
- digitalhub/entities/secret/_base/builder.py +2 -2
- digitalhub/entities/secret/_base/entity.py +4 -10
- digitalhub/entities/secret/crud.py +36 -21
- digitalhub/entities/task/_base/builder.py +14 -14
- digitalhub/entities/task/_base/entity.py +21 -14
- digitalhub/entities/task/_base/models.py +35 -6
- digitalhub/entities/task/_base/spec.py +50 -13
- digitalhub/entities/task/_base/utils.py +18 -0
- digitalhub/entities/task/crud.py +35 -15
- digitalhub/entities/workflow/_base/builder.py +1 -1
- digitalhub/entities/workflow/_base/entity.py +22 -6
- digitalhub/entities/workflow/crud.py +36 -17
- digitalhub/factory/utils.py +1 -1
- digitalhub/readers/_base/reader.py +2 -2
- digitalhub/readers/_commons/enums.py +13 -0
- digitalhub/readers/api.py +3 -2
- digitalhub/readers/factory.py +12 -6
- digitalhub/readers/pandas/reader.py +20 -8
- digitalhub/runtimes/_base.py +0 -7
- digitalhub/runtimes/enums.py +12 -0
- digitalhub/stores/_base/store.py +59 -11
- digitalhub/stores/builder.py +5 -5
- digitalhub/stores/local/store.py +43 -4
- digitalhub/stores/remote/store.py +31 -5
- digitalhub/stores/s3/store.py +136 -57
- digitalhub/stores/sql/store.py +122 -47
- digitalhub/utils/exceptions.py +6 -0
- digitalhub/utils/file_utils.py +60 -2
- digitalhub/utils/generic_utils.py +45 -4
- digitalhub/utils/io_utils.py +18 -0
- digitalhub/utils/s3_utils.py +17 -0
- digitalhub/utils/uri_utils.py +153 -15
- {digitalhub-0.8.0b15.dist-info → digitalhub-0.9.0.dist-info}/LICENSE.txt +1 -1
- {digitalhub-0.8.0b15.dist-info → digitalhub-0.9.0.dist-info}/METADATA +11 -11
- {digitalhub-0.8.0b15.dist-info → digitalhub-0.9.0.dist-info}/RECORD +117 -115
- {digitalhub-0.8.0b15.dist-info → digitalhub-0.9.0.dist-info}/WHEEL +1 -1
- test/local/instances/test_validate.py +55 -0
- test/testkfp.py +4 -1
- digitalhub/datastores/_base/datastore.py +0 -85
- digitalhub/datastores/api.py +0 -37
- digitalhub/datastores/builder.py +0 -110
- digitalhub/datastores/local/datastore.py +0 -50
- digitalhub/datastores/remote/__init__.py +0 -0
- digitalhub/datastores/remote/datastore.py +0 -31
- digitalhub/datastores/s3/__init__.py +0 -0
- digitalhub/datastores/s3/datastore.py +0 -46
- digitalhub/datastores/sql/__init__.py +0 -0
- digitalhub/datastores/sql/datastore.py +0 -68
- digitalhub/entities/_base/api_utils.py +0 -620
- digitalhub/entities/_base/crud.py +0 -468
- digitalhub/entities/function/_base/models.py +0 -118
- digitalhub/entities/utils/__init__.py +0 -0
- digitalhub/entities/utils/api.py +0 -346
- digitalhub/entities/utils/entity_types.py +0 -19
- digitalhub/entities/utils/state.py +0 -31
- digitalhub/entities/utils/utils.py +0 -202
- /digitalhub/{context → entities/_base/project}/__init__.py +0 -0
- /digitalhub/{datastores → entities/_commons}/__init__.py +0 -0
- /digitalhub/{datastores/_base → entities/_operations}/__init__.py +0 -0
- /digitalhub/{datastores/local → readers/_commons}/__init__.py +0 -0
- {digitalhub-0.8.0b15.dist-info → digitalhub-0.9.0.dist-info}/top_level.txt +0 -0
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import importlib.util as imputil
|
|
4
3
|
import typing
|
|
5
|
-
from pathlib import Path
|
|
6
4
|
|
|
7
|
-
from digitalhub.
|
|
8
|
-
from digitalhub.
|
|
9
|
-
from digitalhub.entities.
|
|
10
|
-
from digitalhub.
|
|
11
|
-
from digitalhub.factory.api import build_entity_from_dict, build_entity_from_params
|
|
12
|
-
from digitalhub.utils.exceptions import BackendError, EntityAlreadyExistsError, EntityError
|
|
13
|
-
from digitalhub.utils.io_utils import read_yaml
|
|
5
|
+
from digitalhub.entities._commons.enums import EntityTypes
|
|
6
|
+
from digitalhub.entities._operations.processor import processor
|
|
7
|
+
from digitalhub.entities.project.utils import setup_project
|
|
8
|
+
from digitalhub.utils.exceptions import BackendError
|
|
14
9
|
|
|
15
10
|
if typing.TYPE_CHECKING:
|
|
11
|
+
from digitalhub.entities._base.context.entity import ContextEntity
|
|
16
12
|
from digitalhub.entities.project._base.entity import Project
|
|
17
13
|
|
|
18
14
|
|
|
@@ -60,20 +56,19 @@ def new_project(
|
|
|
60
56
|
--------
|
|
61
57
|
>>> obj = new_project("my-project")
|
|
62
58
|
"""
|
|
63
|
-
build_client(local, config)
|
|
64
59
|
if context is None:
|
|
65
|
-
context =
|
|
66
|
-
obj =
|
|
60
|
+
context = "./"
|
|
61
|
+
obj = processor.create_project_entity(
|
|
67
62
|
name=name,
|
|
68
63
|
kind="project",
|
|
69
64
|
description=description,
|
|
70
65
|
labels=labels,
|
|
71
66
|
local=local,
|
|
67
|
+
config=config,
|
|
72
68
|
context=context,
|
|
73
69
|
**kwargs,
|
|
74
70
|
)
|
|
75
|
-
obj
|
|
76
|
-
return _setup_project(obj, setup_kwargs)
|
|
71
|
+
return setup_project(obj, setup_kwargs)
|
|
77
72
|
|
|
78
73
|
|
|
79
74
|
def get_project(
|
|
@@ -108,12 +103,14 @@ def get_project(
|
|
|
108
103
|
--------
|
|
109
104
|
>>> obj = get_project("my-project")
|
|
110
105
|
"""
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
106
|
+
obj = processor.read_project_entity(
|
|
107
|
+
entity_type=ENTITY_TYPE,
|
|
108
|
+
entity_name=name,
|
|
109
|
+
local=local,
|
|
110
|
+
config=config,
|
|
111
|
+
**kwargs,
|
|
112
|
+
)
|
|
113
|
+
return setup_project(obj, setup_kwargs)
|
|
117
114
|
|
|
118
115
|
|
|
119
116
|
def import_project(
|
|
@@ -123,7 +120,7 @@ def import_project(
|
|
|
123
120
|
setup_kwargs: dict | None = None,
|
|
124
121
|
) -> Project:
|
|
125
122
|
"""
|
|
126
|
-
Import object from a YAML file.
|
|
123
|
+
Import object from a YAML file and create a new object into the backend.
|
|
127
124
|
|
|
128
125
|
Parameters
|
|
129
126
|
----------
|
|
@@ -145,40 +142,22 @@ def import_project(
|
|
|
145
142
|
--------
|
|
146
143
|
>>> obj = import_project("my-project.yaml")
|
|
147
144
|
"""
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
dict_obj["local"] = local
|
|
151
|
-
obj = build_entity_from_dict(dict_obj)
|
|
152
|
-
obj = _setup_project(obj, setup_kwargs)
|
|
153
|
-
|
|
154
|
-
try:
|
|
155
|
-
obj.save()
|
|
156
|
-
except EntityAlreadyExistsError:
|
|
157
|
-
pass
|
|
158
|
-
|
|
159
|
-
# Import related entities
|
|
160
|
-
obj._import_entities(dict_obj)
|
|
161
|
-
|
|
162
|
-
return obj
|
|
145
|
+
obj = processor.import_project_entity(file=file, local=local, config=config)
|
|
146
|
+
return setup_project(obj, setup_kwargs)
|
|
163
147
|
|
|
164
148
|
|
|
165
149
|
def load_project(
|
|
166
|
-
|
|
167
|
-
filename: str | None = None,
|
|
150
|
+
file: str,
|
|
168
151
|
local: bool = False,
|
|
169
152
|
config: dict | None = None,
|
|
170
153
|
setup_kwargs: dict | None = None,
|
|
171
|
-
**kwargs,
|
|
172
154
|
) -> Project:
|
|
173
155
|
"""
|
|
174
|
-
Load
|
|
175
|
-
filename must be provided. Name takes precedence over filename.
|
|
156
|
+
Load object from a YAML file and update an existing object into the backend.
|
|
176
157
|
|
|
177
158
|
Parameters
|
|
178
159
|
----------
|
|
179
|
-
|
|
180
|
-
Project name.
|
|
181
|
-
filename : str
|
|
160
|
+
file : str
|
|
182
161
|
Path to YAML file.
|
|
183
162
|
local : bool
|
|
184
163
|
Flag to determine if backend is local.
|
|
@@ -186,8 +165,6 @@ def load_project(
|
|
|
186
165
|
DHCore environment configuration.
|
|
187
166
|
setup_kwargs : dict
|
|
188
167
|
Setup keyword arguments passed to setup_project() function.
|
|
189
|
-
**kwargs : dict
|
|
190
|
-
Keyword arguments.
|
|
191
168
|
|
|
192
169
|
Returns
|
|
193
170
|
-------
|
|
@@ -196,17 +173,29 @@ def load_project(
|
|
|
196
173
|
|
|
197
174
|
Examples
|
|
198
175
|
--------
|
|
199
|
-
|
|
200
|
-
|
|
176
|
+
>>> obj = load_project("my-project.yaml")
|
|
177
|
+
"""
|
|
178
|
+
obj = processor.load_project_entity(file=file, local=local, config=config)
|
|
179
|
+
return setup_project(obj, setup_kwargs)
|
|
201
180
|
|
|
202
|
-
|
|
203
|
-
|
|
181
|
+
|
|
182
|
+
def list_projects(local: bool = False, **kwargs) -> list[Project]:
|
|
183
|
+
"""
|
|
184
|
+
List projects in backend.
|
|
185
|
+
|
|
186
|
+
Parameters
|
|
187
|
+
----------
|
|
188
|
+
local : bool
|
|
189
|
+
Flag to determine if backend is local.
|
|
190
|
+
**kwargs : dict
|
|
191
|
+
Parameters to pass to the API call.
|
|
192
|
+
|
|
193
|
+
Returns
|
|
194
|
+
-------
|
|
195
|
+
list
|
|
196
|
+
List of objects.
|
|
204
197
|
"""
|
|
205
|
-
|
|
206
|
-
return get_project(name=name, local=local, config=config, setup_kwargs=setup_kwargs, **kwargs)
|
|
207
|
-
if filename is not None:
|
|
208
|
-
return import_project(filename, local=local, config=config, setup_kwargs=setup_kwargs)
|
|
209
|
-
raise EntityError("Either name or filename must be provided.")
|
|
198
|
+
return processor.list_project_entities(local=local, **kwargs)
|
|
210
199
|
|
|
211
200
|
|
|
212
201
|
def get_or_create_project(
|
|
@@ -259,7 +248,7 @@ def get_or_create_project(
|
|
|
259
248
|
)
|
|
260
249
|
|
|
261
250
|
|
|
262
|
-
def update_project(entity: Project,
|
|
251
|
+
def update_project(entity: Project, **kwargs) -> Project:
|
|
263
252
|
"""
|
|
264
253
|
Update object. Note that object spec are immutable.
|
|
265
254
|
|
|
@@ -267,8 +256,6 @@ def update_project(entity: Project, local: bool = False, **kwargs) -> Project:
|
|
|
267
256
|
----------
|
|
268
257
|
entity : Project
|
|
269
258
|
Object to update.
|
|
270
|
-
local : bool
|
|
271
|
-
Flag to determine if backend is local.
|
|
272
259
|
**kwargs : dict
|
|
273
260
|
Parameters to pass to the API call.
|
|
274
261
|
|
|
@@ -281,9 +268,13 @@ def update_project(entity: Project, local: bool = False, **kwargs) -> Project:
|
|
|
281
268
|
--------
|
|
282
269
|
>>> obj = update_project(obj)
|
|
283
270
|
"""
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
271
|
+
return processor.update_project_entity(
|
|
272
|
+
entity_type=entity.ENTITY_TYPE,
|
|
273
|
+
entity_name=entity.name,
|
|
274
|
+
entity_dict=entity.to_dict(),
|
|
275
|
+
local=entity.local,
|
|
276
|
+
**kwargs,
|
|
277
|
+
)
|
|
287
278
|
|
|
288
279
|
|
|
289
280
|
def delete_project(
|
|
@@ -303,8 +294,7 @@ def delete_project(
|
|
|
303
294
|
cascade : bool
|
|
304
295
|
Flag to determine if delete is cascading.
|
|
305
296
|
clean_context : bool
|
|
306
|
-
Flag to determine if context will be deleted.
|
|
307
|
-
all its objects are unreacheable.
|
|
297
|
+
Flag to determine if context will be deleted.
|
|
308
298
|
local : bool
|
|
309
299
|
Flag to determine if backend is local.
|
|
310
300
|
**kwargs : dict
|
|
@@ -319,37 +309,68 @@ def delete_project(
|
|
|
319
309
|
--------
|
|
320
310
|
>>> delete_project("my-project")
|
|
321
311
|
"""
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
312
|
+
return processor.delete_project_entity(
|
|
313
|
+
entity_type=ENTITY_TYPE,
|
|
314
|
+
entity_name=name,
|
|
315
|
+
local=local,
|
|
316
|
+
cascade=cascade,
|
|
317
|
+
clean_context=clean_context,
|
|
318
|
+
**kwargs,
|
|
319
|
+
)
|
|
327
320
|
|
|
328
321
|
|
|
329
|
-
def
|
|
322
|
+
def search_entity(
|
|
323
|
+
project_name: str,
|
|
324
|
+
query: str | None = None,
|
|
325
|
+
entity_types: list[str] | None = None,
|
|
326
|
+
name: str | None = None,
|
|
327
|
+
kind: str | None = None,
|
|
328
|
+
created: str | None = None,
|
|
329
|
+
updated: str | None = None,
|
|
330
|
+
description: str | None = None,
|
|
331
|
+
labels: list[str] | None = None,
|
|
332
|
+
**kwargs,
|
|
333
|
+
) -> list[ContextEntity]:
|
|
330
334
|
"""
|
|
331
|
-
Search
|
|
335
|
+
Search objects from backend.
|
|
332
336
|
|
|
333
337
|
Parameters
|
|
334
338
|
----------
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
+
project_name : str
|
|
340
|
+
Project name.
|
|
341
|
+
query : str
|
|
342
|
+
Search query.
|
|
343
|
+
entity_types : list[str]
|
|
344
|
+
Entity types.
|
|
345
|
+
name : str
|
|
346
|
+
Entity name.
|
|
347
|
+
kind : str
|
|
348
|
+
Entity kind.
|
|
349
|
+
created : str
|
|
350
|
+
Entity creation date.
|
|
351
|
+
updated : str
|
|
352
|
+
Entity update date.
|
|
353
|
+
description : str
|
|
354
|
+
Entity description.
|
|
355
|
+
labels : list[str]
|
|
356
|
+
Entity labels.
|
|
357
|
+
**kwargs : dict
|
|
358
|
+
Parameters to pass to the API call.
|
|
339
359
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
360
|
+
Returns
|
|
361
|
+
-------
|
|
362
|
+
list[ContextEntity]
|
|
363
|
+
List of object instances.
|
|
344
364
|
"""
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
365
|
+
return processor.search_entity(
|
|
366
|
+
project_name,
|
|
367
|
+
query=query,
|
|
368
|
+
entity_types=entity_types,
|
|
369
|
+
name=name,
|
|
370
|
+
kind=kind,
|
|
371
|
+
created=created,
|
|
372
|
+
updated=updated,
|
|
373
|
+
description=description,
|
|
374
|
+
labels=labels,
|
|
375
|
+
**kwargs,
|
|
376
|
+
)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from digitalhub.utils.generic_utils import import_function
|
|
7
|
+
|
|
8
|
+
if typing.TYPE_CHECKING:
|
|
9
|
+
from digitalhub.entities.project._base.entity import Project
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def setup_project(project: Project, setup_kwargs: dict | None = None) -> Project:
|
|
13
|
+
"""
|
|
14
|
+
Search for setup_project.py file and launch setup hanlder as project hook.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
project : Project
|
|
19
|
+
The project to scafold.
|
|
20
|
+
setup_kwargs : dict
|
|
21
|
+
Arguments to pass to setup handler.
|
|
22
|
+
|
|
23
|
+
Returns
|
|
24
|
+
-------
|
|
25
|
+
Project
|
|
26
|
+
Set up project.
|
|
27
|
+
"""
|
|
28
|
+
setup_kwargs = setup_kwargs if setup_kwargs is not None else {}
|
|
29
|
+
check_pth = Path(project.spec.context, ".CHECK")
|
|
30
|
+
setup_pth = Path(project.spec.context, "setup_project.py")
|
|
31
|
+
if setup_pth.exists() and not check_pth.exists():
|
|
32
|
+
setup_fnc = import_function(setup_pth, "setup")
|
|
33
|
+
project = setup_fnc(project, **setup_kwargs)
|
|
34
|
+
check_pth.touch()
|
|
35
|
+
return project
|
|
@@ -4,7 +4,7 @@ import typing
|
|
|
4
4
|
|
|
5
5
|
from digitalhub.entities._base.runtime_entity.builder import EntityError, RuntimeEntityBuilder
|
|
6
6
|
from digitalhub.entities._base.unversioned.builder import UnversionedBuilder
|
|
7
|
-
from digitalhub.entities.
|
|
7
|
+
from digitalhub.entities._commons.enums import EntityTypes
|
|
8
8
|
|
|
9
9
|
if typing.TYPE_CHECKING:
|
|
10
10
|
from digitalhub.entities.run._base.entity import Run
|
|
@@ -52,9 +52,11 @@ class RunBuilder(UnversionedBuilder, RuntimeEntityBuilder):
|
|
|
52
52
|
Run
|
|
53
53
|
Object instance.
|
|
54
54
|
"""
|
|
55
|
+
# Check task validity
|
|
55
56
|
if task is None:
|
|
56
57
|
raise EntityError("Missing task in run spec")
|
|
57
58
|
self._check_kind_validity(task)
|
|
59
|
+
|
|
58
60
|
uuid = self.build_uuid(uuid)
|
|
59
61
|
metadata = self.build_metadata(
|
|
60
62
|
project=project,
|
|
@@ -3,17 +3,9 @@ from __future__ import annotations
|
|
|
3
3
|
import time
|
|
4
4
|
import typing
|
|
5
5
|
|
|
6
|
-
from digitalhub.entities._base.api_utils import (
|
|
7
|
-
list_entity_api_base,
|
|
8
|
-
list_entity_api_ctx,
|
|
9
|
-
logs_api,
|
|
10
|
-
read_entity_api_ctx,
|
|
11
|
-
resume_api,
|
|
12
|
-
stop_api,
|
|
13
|
-
)
|
|
14
6
|
from digitalhub.entities._base.unversioned.entity import UnversionedEntity
|
|
15
|
-
from digitalhub.entities.
|
|
16
|
-
from digitalhub.entities.
|
|
7
|
+
from digitalhub.entities._commons.enums import EntityTypes, State
|
|
8
|
+
from digitalhub.entities._operations.processor import processor
|
|
17
9
|
from digitalhub.factory.api import (
|
|
18
10
|
build_runtime,
|
|
19
11
|
build_spec,
|
|
@@ -68,12 +60,9 @@ class Run(UnversionedEntity):
|
|
|
68
60
|
executable = self._get_executable()
|
|
69
61
|
task = self._get_task()
|
|
70
62
|
new_spec = self._get_runtime().build(executable, task, self.to_dict())
|
|
71
|
-
self.spec = build_spec(
|
|
72
|
-
self.kind,
|
|
73
|
-
**new_spec,
|
|
74
|
-
)
|
|
63
|
+
self.spec = build_spec(self.kind, **new_spec)
|
|
75
64
|
self._set_state(State.BUILT.value)
|
|
76
|
-
self.save()
|
|
65
|
+
self.save(update=True)
|
|
77
66
|
|
|
78
67
|
def run(self) -> Run:
|
|
79
68
|
"""
|
|
@@ -85,12 +74,8 @@ class Run(UnversionedEntity):
|
|
|
85
74
|
Run object.
|
|
86
75
|
"""
|
|
87
76
|
self.refresh()
|
|
88
|
-
if self.spec.local_execution:
|
|
89
|
-
if not self._is_ready_to_run():
|
|
90
|
-
raise EntityError("Run is not in a state to run.")
|
|
91
|
-
self._set_state(State.RUNNING.value)
|
|
92
|
-
self.save(update=True)
|
|
93
77
|
|
|
78
|
+
self._start_execution()
|
|
94
79
|
self._setup_execution()
|
|
95
80
|
|
|
96
81
|
try:
|
|
@@ -102,6 +87,8 @@ class Run(UnversionedEntity):
|
|
|
102
87
|
self._set_message(str(e))
|
|
103
88
|
self.save(update=True)
|
|
104
89
|
raise e
|
|
90
|
+
finally:
|
|
91
|
+
self._finish_execution()
|
|
105
92
|
|
|
106
93
|
self.refresh()
|
|
107
94
|
if not self.spec.local_execution:
|
|
@@ -143,17 +130,14 @@ class Run(UnversionedEntity):
|
|
|
143
130
|
|
|
144
131
|
def logs(self) -> dict:
|
|
145
132
|
"""
|
|
146
|
-
Get
|
|
147
|
-
Returns empty dictionary if context is local.
|
|
133
|
+
Get run logs.
|
|
148
134
|
|
|
149
135
|
Returns
|
|
150
136
|
-------
|
|
151
137
|
dict
|
|
152
|
-
|
|
138
|
+
Run logs.
|
|
153
139
|
"""
|
|
154
|
-
|
|
155
|
-
return {}
|
|
156
|
-
return logs_api(self.project, self.ENTITY_TYPE, self.id)
|
|
140
|
+
return processor.read_run_logs(self.project, self.ENTITY_TYPE, self.id)
|
|
157
141
|
|
|
158
142
|
def stop(self) -> None:
|
|
159
143
|
"""
|
|
@@ -163,8 +147,8 @@ class Run(UnversionedEntity):
|
|
|
163
147
|
-------
|
|
164
148
|
None
|
|
165
149
|
"""
|
|
166
|
-
if not self.
|
|
167
|
-
return
|
|
150
|
+
if not self.spec.local_execution:
|
|
151
|
+
return processor.stop_run(self.project, self.ENTITY_TYPE, self.id)
|
|
168
152
|
|
|
169
153
|
def resume(self) -> None:
|
|
170
154
|
"""
|
|
@@ -174,9 +158,8 @@ class Run(UnversionedEntity):
|
|
|
174
158
|
-------
|
|
175
159
|
None
|
|
176
160
|
"""
|
|
177
|
-
if not self.
|
|
178
|
-
return
|
|
179
|
-
self.run()
|
|
161
|
+
if not self.spec.local_execution:
|
|
162
|
+
return processor.resume_run(self.project, self.ENTITY_TYPE, self.id)
|
|
180
163
|
|
|
181
164
|
##############################
|
|
182
165
|
# Helpers
|
|
@@ -184,13 +167,38 @@ class Run(UnversionedEntity):
|
|
|
184
167
|
|
|
185
168
|
def _setup_execution(self) -> None:
|
|
186
169
|
"""
|
|
187
|
-
Setup run execution.
|
|
170
|
+
Setup run execution.
|
|
188
171
|
|
|
189
172
|
Returns
|
|
190
173
|
-------
|
|
191
174
|
None
|
|
192
175
|
"""
|
|
193
176
|
|
|
177
|
+
def _start_execution(self) -> None:
|
|
178
|
+
"""
|
|
179
|
+
Start run execution.
|
|
180
|
+
|
|
181
|
+
Returns
|
|
182
|
+
-------
|
|
183
|
+
None
|
|
184
|
+
"""
|
|
185
|
+
self._context().set_run(f"{self.key}:{self.id}")
|
|
186
|
+
if self.spec.local_execution:
|
|
187
|
+
if not self._is_ready_to_run():
|
|
188
|
+
raise EntityError("Run is not in a state to run.")
|
|
189
|
+
self._set_state(State.RUNNING.value)
|
|
190
|
+
self.save(update=True)
|
|
191
|
+
|
|
192
|
+
def _finish_execution(self) -> None:
|
|
193
|
+
"""
|
|
194
|
+
Finish run execution.
|
|
195
|
+
|
|
196
|
+
Returns
|
|
197
|
+
-------
|
|
198
|
+
None
|
|
199
|
+
"""
|
|
200
|
+
self._context().unset_run()
|
|
201
|
+
|
|
194
202
|
def _is_ready_to_run(self) -> bool:
|
|
195
203
|
"""
|
|
196
204
|
Check if run is in a state ready for running (BUILT or STOPPED).
|
|
@@ -269,16 +277,15 @@ class Run(UnversionedEntity):
|
|
|
269
277
|
Executable (function or workflow) from backend.
|
|
270
278
|
"""
|
|
271
279
|
exec_kind = get_executable_kind(self.kind)
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
exec_name =
|
|
275
|
-
|
|
276
|
-
return read_entity_api_ctx(
|
|
280
|
+
exec_type = get_entity_type_from_kind(exec_kind)
|
|
281
|
+
string_to_split = getattr(self.spec, exec_type)
|
|
282
|
+
exec_name, exec_id = string_to_split.split("://")[-1].split("/")[-1].split(":")
|
|
283
|
+
return processor.read_context_entity(
|
|
277
284
|
exec_name,
|
|
278
|
-
entity_type=
|
|
285
|
+
entity_type=exec_type,
|
|
279
286
|
project=self.project,
|
|
280
287
|
entity_id=exec_id,
|
|
281
|
-
)
|
|
288
|
+
).to_dict()
|
|
282
289
|
|
|
283
290
|
def _get_task(self) -> dict:
|
|
284
291
|
"""
|
|
@@ -290,18 +297,9 @@ class Run(UnversionedEntity):
|
|
|
290
297
|
dict
|
|
291
298
|
Task from backend.
|
|
292
299
|
"""
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
for i in tasks:
|
|
300
|
-
if i.get("spec").get("function") == exec_string:
|
|
301
|
-
return i
|
|
302
|
-
raise EntityError("Task not found.")
|
|
303
|
-
|
|
304
|
-
# Remote backend
|
|
305
|
-
task_kind = self.spec.task.split("://")[0]
|
|
306
|
-
params = {"function": exec_string, "kind": task_kind}
|
|
307
|
-
return list_entity_api_ctx(self.project, EntityTypes.TASK.value, params=params)[0]
|
|
300
|
+
task_id = self.spec.task.split("://")[-1].split("/")[-1]
|
|
301
|
+
return processor.read_unversioned_entity(
|
|
302
|
+
task_id,
|
|
303
|
+
entity_type=EntityTypes.TASK.value,
|
|
304
|
+
project=self.project,
|
|
305
|
+
).to_dict()
|
|
@@ -12,19 +12,23 @@ class RunSpec(Spec):
|
|
|
12
12
|
task: str,
|
|
13
13
|
local_execution: bool = False,
|
|
14
14
|
function: str | None = None,
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
workflow: str | None = None,
|
|
16
|
+
node_selector: list[dict] | None = None,
|
|
17
|
+
volumes: list[dict] | None = None,
|
|
17
18
|
resources: dict | None = None,
|
|
18
19
|
affinity: dict | None = None,
|
|
19
|
-
tolerations: list | None = None,
|
|
20
|
-
envs: list | None = None,
|
|
21
|
-
secrets: list | None = None,
|
|
20
|
+
tolerations: list[dict] | None = None,
|
|
21
|
+
envs: list[dict] | None = None,
|
|
22
|
+
secrets: list[str] | None = None,
|
|
22
23
|
profile: str | None = None,
|
|
24
|
+
runtime_class: str | None = None,
|
|
25
|
+
priority_class: str | None = None,
|
|
23
26
|
**kwargs,
|
|
24
27
|
) -> None:
|
|
25
28
|
self.task = task
|
|
26
29
|
self.local_execution = local_execution
|
|
27
30
|
self.function = function
|
|
31
|
+
self.workflow = workflow
|
|
28
32
|
self.node_selector = node_selector
|
|
29
33
|
self.volumes = volumes
|
|
30
34
|
self.resources = resources
|
|
@@ -33,6 +37,8 @@ class RunSpec(Spec):
|
|
|
33
37
|
self.envs = envs
|
|
34
38
|
self.secrets = secrets
|
|
35
39
|
self.profile = profile
|
|
40
|
+
self.runtime_class = runtime_class
|
|
41
|
+
self.priority_class = priority_class
|
|
36
42
|
|
|
37
43
|
|
|
38
44
|
class RunValidator(SpecValidator, K8s):
|
|
@@ -40,10 +46,12 @@ class RunValidator(SpecValidator, K8s):
|
|
|
40
46
|
RunValidator validator.
|
|
41
47
|
"""
|
|
42
48
|
|
|
49
|
+
# Task parameters
|
|
43
50
|
function: str = None
|
|
44
|
-
|
|
51
|
+
workflow: str = None
|
|
45
52
|
|
|
46
|
-
|
|
53
|
+
# Run parameters
|
|
54
|
+
task: str
|
|
47
55
|
"""The task string associated with the run."""
|
|
48
56
|
|
|
49
57
|
local_execution: bool = False
|