digitalhub 0.8.0__py3-none-any.whl → 0.8.0b1__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 +4 -5
- digitalhub/client/builder.py +58 -3
- digitalhub/client/{dhcore/client.py → objects/dhcore.py} +60 -48
- digitalhub/client/{local/client.py → objects/local.py} +2 -2
- digitalhub/context/builder.py +85 -1
- digitalhub/context/context.py +1 -1
- digitalhub/datastores/builder.py +37 -13
- digitalhub/datastores/{_base/datastore.py → objects/base.py} +3 -3
- digitalhub/datastores/{local/datastore.py → objects/local.py} +2 -10
- digitalhub/datastores/{remote/datastore.py → objects/remote.py} +1 -9
- digitalhub/datastores/{s3/datastore.py → objects/s3.py} +2 -10
- digitalhub/datastores/{sql/datastore.py → objects/sql.py} +2 -10
- digitalhub/entities/_base/{_base/entity.py → base.py} +1 -1
- digitalhub/entities/_base/crud.py +389 -247
- digitalhub/entities/_base/entity/{entity.py → base.py} +34 -8
- digitalhub/entities/_base/{context/entity.py → entity/context.py} +6 -6
- digitalhub/entities/_base/{executable/entity.py → entity/executable.py} +36 -61
- digitalhub/entities/_base/{material/entity.py → entity/material.py} +6 -6
- digitalhub/entities/_base/entity/unversioned.py +87 -0
- digitalhub/entities/_base/entity/versioned.py +94 -0
- digitalhub/entities/_base/{entity/metadata.py → metadata.py} +2 -2
- digitalhub/entities/_base/{entity/spec.py → spec/base.py} +11 -11
- digitalhub/entities/_base/{material/spec.py → spec/material.py} +3 -3
- digitalhub/entities/_base/{entity/status.py → status/base.py} +3 -14
- digitalhub/entities/_base/{material/status.py → status/material.py} +1 -1
- digitalhub/entities/_builders/metadata.py +60 -0
- digitalhub/entities/_builders/spec.py +43 -0
- digitalhub/entities/_builders/status.py +62 -0
- digitalhub/entities/{_base/entity/_constructors → _builders}/uuid.py +11 -4
- digitalhub/entities/artifact/builder.py +133 -0
- digitalhub/entities/artifact/crud.py +48 -22
- digitalhub/entities/artifact/{_base/entity.py → entity/_base.py} +5 -5
- digitalhub/entities/artifact/entity/artifact.py +9 -0
- digitalhub/entities/artifact/{artifact/spec.py → spec.py} +16 -4
- digitalhub/entities/artifact/{artifact/status.py → status.py} +1 -1
- digitalhub/entities/dataitem/builder.py +144 -0
- digitalhub/entities/dataitem/crud.py +52 -29
- digitalhub/entities/dataitem/{_base/entity.py → entity/_base.py} +5 -5
- digitalhub/entities/dataitem/entity/dataitem.py +9 -0
- digitalhub/entities/dataitem/entity/iceberg.py +7 -0
- digitalhub/entities/dataitem/{table/entity.py → entity/table.py} +4 -25
- digitalhub/entities/dataitem/spec.py +61 -0
- digitalhub/entities/dataitem/status.py +38 -0
- digitalhub/entities/function/builder.py +86 -0
- digitalhub/entities/function/crud.py +43 -17
- digitalhub/entities/function/{_base/entity.py → entity.py} +12 -9
- digitalhub/entities/function/{_base/models.py → models.py} +1 -1
- digitalhub/entities/function/spec.py +81 -0
- digitalhub/entities/function/status.py +9 -0
- digitalhub/entities/model/builder.py +152 -0
- digitalhub/entities/model/crud.py +48 -21
- digitalhub/entities/model/{_base/entity.py → entity/_base.py} +5 -5
- digitalhub/entities/model/entity/huggingface.py +9 -0
- digitalhub/entities/model/{mlflow/utils.py → entity/mlflow.py} +10 -1
- digitalhub/entities/model/entity/model.py +9 -0
- digitalhub/entities/model/entity/sklearn.py +9 -0
- digitalhub/entities/model/spec.py +146 -0
- digitalhub/entities/model/status.py +33 -0
- digitalhub/entities/project/builder.py +82 -0
- digitalhub/entities/project/crud.py +12 -19
- digitalhub/entities/project/{_base/entity.py → entity.py} +102 -120
- digitalhub/entities/project/{_base/spec.py → spec.py} +4 -4
- digitalhub/entities/project/status.py +9 -0
- digitalhub/entities/registries.py +48 -0
- digitalhub/entities/run/builder.py +77 -0
- digitalhub/entities/run/crud.py +33 -20
- digitalhub/entities/run/{_base/entity.py → entity.py} +189 -35
- digitalhub/entities/run/spec.py +153 -0
- digitalhub/entities/run/status.py +114 -0
- digitalhub/entities/secret/builder.py +93 -0
- digitalhub/entities/secret/crud.py +31 -27
- digitalhub/entities/secret/{_base/entity.py → entity.py} +7 -8
- digitalhub/entities/secret/{_base/spec.py → spec.py} +4 -4
- digitalhub/entities/secret/status.py +9 -0
- digitalhub/entities/task/builder.py +74 -0
- digitalhub/entities/task/crud.py +33 -20
- digitalhub/entities/task/{_base/entity.py → entity.py} +8 -9
- digitalhub/entities/task/{_base/models.py → models.py} +0 -9
- digitalhub/entities/task/{_base/spec.py → spec.py} +7 -9
- digitalhub/entities/task/status.py +9 -0
- digitalhub/entities/{utils/utils.py → utils.py} +2 -20
- digitalhub/entities/workflow/builder.py +91 -0
- digitalhub/entities/workflow/crud.py +43 -17
- digitalhub/entities/workflow/{_base/entity.py → entity.py} +12 -9
- digitalhub/entities/workflow/spec.py +15 -0
- digitalhub/entities/workflow/status.py +9 -0
- digitalhub/readers/builder.py +54 -0
- digitalhub/readers/{pandas/reader.py → objects/pandas.py} +1 -1
- digitalhub/readers/registry.py +15 -0
- digitalhub/registry/models.py +87 -0
- digitalhub/registry/registry.py +74 -0
- digitalhub/registry/utils.py +150 -0
- digitalhub/runtimes/{_base.py → base.py} +65 -3
- digitalhub/runtimes/builder.py +40 -19
- digitalhub/runtimes/kind_registry.py +170 -0
- digitalhub/stores/builder.py +52 -6
- digitalhub/stores/{local/store.py → objects/local.py} +1 -1
- digitalhub/stores/{remote/store.py → objects/remote.py} +1 -1
- digitalhub/stores/{s3/store.py → objects/s3.py} +1 -1
- digitalhub/stores/{sql/store.py → objects/sql.py} +1 -1
- digitalhub/{client/dhcore/utils.py → utils/env_utils.py} +14 -2
- digitalhub/utils/exceptions.py +0 -12
- digitalhub/utils/generic_utils.py +42 -18
- digitalhub/utils/io_utils.py +2 -39
- {digitalhub-0.8.0.dist-info → digitalhub-0.8.0b1.dist-info}/METADATA +2 -3
- digitalhub-0.8.0b1.dist-info/RECORD +161 -0
- {digitalhub-0.8.0.dist-info → digitalhub-0.8.0b1.dist-info}/WHEEL +1 -1
- test/test_crud_artifacts.py +96 -0
- test/test_crud_dataitems.py +96 -0
- test/test_crud_functions.py +1 -1
- test/test_crud_runs.py +1 -1
- test/test_crud_tasks.py +1 -1
- digitalhub/client/api.py +0 -63
- digitalhub/client/dhcore/env.py +0 -21
- digitalhub/client/dhcore/models.py +0 -46
- digitalhub/context/api.py +0 -93
- digitalhub/datastores/api.py +0 -37
- digitalhub/entities/_base/api_utils.py +0 -620
- digitalhub/entities/_base/entity/_constructors/metadata.py +0 -44
- digitalhub/entities/_base/entity/_constructors/spec.py +0 -33
- digitalhub/entities/_base/entity/_constructors/status.py +0 -52
- digitalhub/entities/_base/entity/builder.py +0 -175
- digitalhub/entities/_base/executable/__init__.py +0 -0
- digitalhub/entities/_base/material/__init__.py +0 -0
- digitalhub/entities/_base/runtime_entity/__init__.py +0 -0
- digitalhub/entities/_base/runtime_entity/builder.py +0 -106
- digitalhub/entities/_base/unversioned/__init__.py +0 -0
- digitalhub/entities/_base/unversioned/builder.py +0 -66
- digitalhub/entities/_base/unversioned/entity.py +0 -49
- digitalhub/entities/_base/versioned/__init__.py +0 -0
- digitalhub/entities/_base/versioned/builder.py +0 -68
- digitalhub/entities/_base/versioned/entity.py +0 -53
- digitalhub/entities/artifact/_base/__init__.py +0 -0
- digitalhub/entities/artifact/_base/builder.py +0 -86
- digitalhub/entities/artifact/_base/spec.py +0 -15
- digitalhub/entities/artifact/_base/status.py +0 -9
- digitalhub/entities/artifact/artifact/__init__.py +0 -0
- digitalhub/entities/artifact/artifact/builder.py +0 -18
- digitalhub/entities/artifact/artifact/entity.py +0 -32
- digitalhub/entities/builders.py +0 -63
- digitalhub/entities/dataitem/_base/__init__.py +0 -0
- digitalhub/entities/dataitem/_base/builder.py +0 -86
- digitalhub/entities/dataitem/_base/spec.py +0 -15
- digitalhub/entities/dataitem/_base/status.py +0 -20
- digitalhub/entities/dataitem/dataitem/__init__.py +0 -0
- digitalhub/entities/dataitem/dataitem/builder.py +0 -18
- digitalhub/entities/dataitem/dataitem/entity.py +0 -32
- digitalhub/entities/dataitem/dataitem/spec.py +0 -15
- digitalhub/entities/dataitem/dataitem/status.py +0 -9
- digitalhub/entities/dataitem/iceberg/__init__.py +0 -0
- digitalhub/entities/dataitem/iceberg/builder.py +0 -18
- digitalhub/entities/dataitem/iceberg/entity.py +0 -32
- digitalhub/entities/dataitem/iceberg/spec.py +0 -15
- digitalhub/entities/dataitem/iceberg/status.py +0 -9
- digitalhub/entities/dataitem/table/__init__.py +0 -0
- digitalhub/entities/dataitem/table/builder.py +0 -18
- digitalhub/entities/dataitem/table/spec.py +0 -25
- digitalhub/entities/dataitem/table/status.py +0 -9
- digitalhub/entities/function/_base/__init__.py +0 -0
- digitalhub/entities/function/_base/builder.py +0 -79
- digitalhub/entities/function/_base/spec.py +0 -15
- digitalhub/entities/function/_base/status.py +0 -9
- digitalhub/entities/model/_base/__init__.py +0 -0
- digitalhub/entities/model/_base/builder.py +0 -86
- digitalhub/entities/model/_base/spec.py +0 -49
- digitalhub/entities/model/_base/status.py +0 -9
- digitalhub/entities/model/huggingface/__init__.py +0 -0
- digitalhub/entities/model/huggingface/builder.py +0 -18
- digitalhub/entities/model/huggingface/entity.py +0 -32
- digitalhub/entities/model/huggingface/spec.py +0 -36
- digitalhub/entities/model/huggingface/status.py +0 -9
- digitalhub/entities/model/mlflow/__init__.py +0 -0
- digitalhub/entities/model/mlflow/builder.py +0 -18
- digitalhub/entities/model/mlflow/entity.py +0 -32
- digitalhub/entities/model/mlflow/spec.py +0 -44
- digitalhub/entities/model/mlflow/status.py +0 -9
- digitalhub/entities/model/model/__init__.py +0 -0
- digitalhub/entities/model/model/builder.py +0 -18
- digitalhub/entities/model/model/entity.py +0 -32
- digitalhub/entities/model/model/spec.py +0 -15
- digitalhub/entities/model/model/status.py +0 -9
- digitalhub/entities/model/sklearn/__init__.py +0 -0
- digitalhub/entities/model/sklearn/builder.py +0 -18
- digitalhub/entities/model/sklearn/entity.py +0 -32
- digitalhub/entities/model/sklearn/spec.py +0 -15
- digitalhub/entities/model/sklearn/status.py +0 -9
- digitalhub/entities/project/_base/__init__.py +0 -0
- digitalhub/entities/project/_base/builder.py +0 -128
- digitalhub/entities/project/_base/status.py +0 -9
- digitalhub/entities/run/_base/__init__.py +0 -0
- digitalhub/entities/run/_base/builder.py +0 -94
- digitalhub/entities/run/_base/spec.py +0 -50
- digitalhub/entities/run/_base/status.py +0 -9
- digitalhub/entities/secret/_base/__init__.py +0 -0
- digitalhub/entities/secret/_base/builder.py +0 -81
- digitalhub/entities/secret/_base/status.py +0 -9
- digitalhub/entities/task/_base/__init__.py +0 -0
- digitalhub/entities/task/_base/builder.py +0 -91
- digitalhub/entities/task/_base/status.py +0 -9
- digitalhub/entities/utils/__init__.py +0 -0
- digitalhub/entities/workflow/_base/__init__.py +0 -0
- digitalhub/entities/workflow/_base/builder.py +0 -79
- digitalhub/entities/workflow/_base/spec.py +0 -15
- digitalhub/entities/workflow/_base/status.py +0 -9
- digitalhub/factory/__init__.py +0 -0
- digitalhub/factory/api.py +0 -277
- digitalhub/factory/factory.py +0 -268
- digitalhub/factory/utils.py +0 -90
- digitalhub/readers/_base/__init__.py +0 -0
- digitalhub/readers/_base/builder.py +0 -26
- digitalhub/readers/api.py +0 -80
- digitalhub/readers/factory.py +0 -133
- digitalhub/readers/pandas/__init__.py +0 -0
- digitalhub/readers/pandas/builder.py +0 -29
- digitalhub/stores/_base/__init__.py +0 -0
- digitalhub/stores/api.py +0 -54
- digitalhub/stores/local/__init__.py +0 -0
- digitalhub/stores/remote/__init__.py +0 -0
- digitalhub/stores/s3/__init__.py +0 -0
- digitalhub/stores/sql/__init__.py +0 -0
- digitalhub/utils/s3_utils.py +0 -58
- digitalhub-0.8.0.dist-info/RECORD +0 -231
- test/local/CRUD/test_artifacts.py +0 -96
- test/local/CRUD/test_dataitems.py +0 -96
- test/local/CRUD/test_models.py +0 -95
- /digitalhub/client/{_base → objects}/__init__.py +0 -0
- /digitalhub/client/{_base/client.py → objects/base.py} +0 -0
- /digitalhub/{client/dhcore → datastores/objects}/__init__.py +0 -0
- /digitalhub/entities/{utils → _base}/api.py +0 -0
- /digitalhub/{client/local → entities/_base/spec}/__init__.py +0 -0
- /digitalhub/entities/{utils → _base}/state.py +0 -0
- /digitalhub/{datastores/_base → entities/_base/status}/__init__.py +0 -0
- /digitalhub/{datastores/local → entities/_builders}/__init__.py +0 -0
- /digitalhub/entities/{_base/entity/_constructors → _builders}/name.py +0 -0
- /digitalhub/{datastores/remote → entities/artifact/entity}/__init__.py +0 -0
- /digitalhub/{datastores/s3 → entities/dataitem/entity}/__init__.py +0 -0
- /digitalhub/entities/dataitem/{table/models.py → models.py} +0 -0
- /digitalhub/entities/{utils/entity_types.py → entity_types.py} +0 -0
- /digitalhub/{datastores/sql → entities/model/entity}/__init__.py +0 -0
- /digitalhub/entities/model/{mlflow/models.py → models.py} +0 -0
- /digitalhub/{entities/_base/_base → readers/objects}/__init__.py +0 -0
- /digitalhub/readers/{_base/reader.py → objects/base.py} +0 -0
- /digitalhub/{entities/_base/context → registry}/__init__.py +0 -0
- /digitalhub/{entities/_base/entity/_constructors → stores/objects}/__init__.py +0 -0
- /digitalhub/stores/{_base/store.py → objects/base.py} +0 -0
- {digitalhub-0.8.0.dist-info → digitalhub-0.8.0b1.dist-info}/LICENSE.txt +0 -0
- {digitalhub-0.8.0.dist-info → digitalhub-0.8.0b1.dist-info}/top_level.txt +0 -0
- /test/{local/imports/test_imports.py → test_imports.py} +0 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from digitalhub.entities._builders.metadata import build_metadata
|
|
4
|
+
from digitalhub.entities._builders.spec import build_spec
|
|
5
|
+
from digitalhub.entities._builders.status import build_status
|
|
6
|
+
from digitalhub.entities._builders.uuid import build_uuid
|
|
7
|
+
from digitalhub.entities.run.entity import Run
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def run_from_parameters(
|
|
11
|
+
project: str,
|
|
12
|
+
kind: str,
|
|
13
|
+
uuid: str | None = None,
|
|
14
|
+
labels: list[str] | None = None,
|
|
15
|
+
task: str | None = None,
|
|
16
|
+
local_execution: bool = False,
|
|
17
|
+
**kwargs,
|
|
18
|
+
) -> Run:
|
|
19
|
+
"""
|
|
20
|
+
Create run.
|
|
21
|
+
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
project : str
|
|
25
|
+
Project name.
|
|
26
|
+
kind : str
|
|
27
|
+
Kind the object.
|
|
28
|
+
uuid : str
|
|
29
|
+
ID of the object (UUID4, e.g. 40f25c4b-d26b-4221-b048-9527aff291e2).
|
|
30
|
+
labels : list[str]
|
|
31
|
+
List of labels.
|
|
32
|
+
task : str
|
|
33
|
+
Name of the task associated with the run.
|
|
34
|
+
local_execution : bool
|
|
35
|
+
Flag to determine if object has local execution.
|
|
36
|
+
**kwargs : dict
|
|
37
|
+
Spec keyword arguments.
|
|
38
|
+
|
|
39
|
+
Returns
|
|
40
|
+
-------
|
|
41
|
+
Run
|
|
42
|
+
Object instance.
|
|
43
|
+
"""
|
|
44
|
+
uuid = build_uuid(uuid)
|
|
45
|
+
metadata = build_metadata(
|
|
46
|
+
kind=kind,
|
|
47
|
+
project=project,
|
|
48
|
+
name=uuid,
|
|
49
|
+
labels=labels,
|
|
50
|
+
)
|
|
51
|
+
spec = build_spec(kind, task=task, local_execution=local_execution, **kwargs)
|
|
52
|
+
status = build_status(kind)
|
|
53
|
+
return Run(
|
|
54
|
+
project=project,
|
|
55
|
+
uuid=uuid,
|
|
56
|
+
kind=kind,
|
|
57
|
+
metadata=metadata,
|
|
58
|
+
spec=spec,
|
|
59
|
+
status=status,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def run_from_dict(obj: dict) -> Run:
|
|
64
|
+
"""
|
|
65
|
+
Create a new object from dictionary.
|
|
66
|
+
|
|
67
|
+
Parameters
|
|
68
|
+
----------
|
|
69
|
+
obj : dict
|
|
70
|
+
Dictionary to create object from.
|
|
71
|
+
|
|
72
|
+
Returns
|
|
73
|
+
-------
|
|
74
|
+
Run
|
|
75
|
+
Object instance.
|
|
76
|
+
"""
|
|
77
|
+
return Run.from_dict(obj)
|
digitalhub/entities/run/crud.py
CHANGED
|
@@ -2,18 +2,15 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import typing
|
|
4
4
|
|
|
5
|
-
from digitalhub.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
)
|
|
12
|
-
from digitalhub.entities.utils.entity_types import EntityTypes
|
|
13
|
-
from digitalhub.utils.exceptions import EntityError
|
|
5
|
+
from digitalhub.context.builder import check_context
|
|
6
|
+
from digitalhub.entities._base.crud import delete_entity_api_ctx, list_entity_api_ctx, read_entity_api_ctx
|
|
7
|
+
from digitalhub.entities.entity_types import EntityTypes
|
|
8
|
+
from digitalhub.entities.run.builder import run_from_dict, run_from_parameters
|
|
9
|
+
from digitalhub.utils.exceptions import EntityAlreadyExistsError, EntityError
|
|
10
|
+
from digitalhub.utils.io_utils import read_yaml
|
|
14
11
|
|
|
15
12
|
if typing.TYPE_CHECKING:
|
|
16
|
-
from digitalhub.entities.run.
|
|
13
|
+
from digitalhub.entities.run.entity import Run
|
|
17
14
|
|
|
18
15
|
|
|
19
16
|
ENTITY_TYPE = EntityTypes.RUN.value
|
|
@@ -38,7 +35,7 @@ def new_run(
|
|
|
38
35
|
kind : str
|
|
39
36
|
Kind the object.
|
|
40
37
|
uuid : str
|
|
41
|
-
ID of the object.
|
|
38
|
+
ID of the object (UUID4, e.g. 40f25c4b-d26b-4221-b048-9527aff291e2).
|
|
42
39
|
labels : list[str]
|
|
43
40
|
List of labels.
|
|
44
41
|
task : str
|
|
@@ -55,11 +52,13 @@ def new_run(
|
|
|
55
52
|
|
|
56
53
|
Examples
|
|
57
54
|
--------
|
|
58
|
-
>>> obj =
|
|
59
|
-
>>>
|
|
60
|
-
>>>
|
|
55
|
+
>>> obj = new_function(project="my-project",
|
|
56
|
+
>>> name="my-function",
|
|
57
|
+
>>> kind="python+run",
|
|
58
|
+
>>> task="task-string"
|
|
61
59
|
"""
|
|
62
|
-
|
|
60
|
+
check_context(project)
|
|
61
|
+
obj = run_from_parameters(
|
|
63
62
|
project=project,
|
|
64
63
|
kind=kind,
|
|
65
64
|
uuid=uuid,
|
|
@@ -68,6 +67,8 @@ def new_run(
|
|
|
68
67
|
local_execution=local_execution,
|
|
69
68
|
**kwargs,
|
|
70
69
|
)
|
|
70
|
+
obj.save()
|
|
71
|
+
return obj
|
|
71
72
|
|
|
72
73
|
|
|
73
74
|
def get_run(
|
|
@@ -101,12 +102,16 @@ def get_run(
|
|
|
101
102
|
>>> obj = get_run("my-run-id"
|
|
102
103
|
>>> project="my-project")
|
|
103
104
|
"""
|
|
104
|
-
|
|
105
|
+
if not identifier.startswith("store://") and project is None:
|
|
106
|
+
raise EntityError("Specify entity key or entity ID combined with project")
|
|
107
|
+
obj = read_entity_api_ctx(
|
|
105
108
|
identifier,
|
|
106
|
-
|
|
109
|
+
ENTITY_TYPE,
|
|
107
110
|
project=project,
|
|
111
|
+
entity_id=identifier,
|
|
108
112
|
**kwargs,
|
|
109
113
|
)
|
|
114
|
+
return run_from_dict(obj)
|
|
110
115
|
|
|
111
116
|
|
|
112
117
|
def list_runs(project: str, **kwargs) -> list[Run]:
|
|
@@ -130,11 +135,12 @@ def list_runs(project: str, **kwargs) -> list[Run]:
|
|
|
130
135
|
>>> objs = list_runs(project="my-project")
|
|
131
136
|
"""
|
|
132
137
|
# TODO more examples: search by function, latest for task and function
|
|
133
|
-
|
|
138
|
+
objs = list_entity_api_ctx(
|
|
134
139
|
project=project,
|
|
135
140
|
entity_type=ENTITY_TYPE,
|
|
136
141
|
**kwargs,
|
|
137
142
|
)
|
|
143
|
+
return [run_from_dict(obj) for obj in objs]
|
|
138
144
|
|
|
139
145
|
|
|
140
146
|
def import_run(file: str) -> Run:
|
|
@@ -155,7 +161,14 @@ def import_run(file: str) -> Run:
|
|
|
155
161
|
-------
|
|
156
162
|
>>> obj = import_run("my-run.yaml")
|
|
157
163
|
"""
|
|
158
|
-
|
|
164
|
+
dict_obj: dict = read_yaml(file)
|
|
165
|
+
obj = run_from_dict(dict_obj)
|
|
166
|
+
try:
|
|
167
|
+
obj.save()
|
|
168
|
+
except EntityAlreadyExistsError:
|
|
169
|
+
pass
|
|
170
|
+
finally:
|
|
171
|
+
return obj
|
|
159
172
|
|
|
160
173
|
|
|
161
174
|
def update_run(entity: Run) -> Run:
|
|
@@ -208,7 +221,7 @@ def delete_run(
|
|
|
208
221
|
"""
|
|
209
222
|
if not identifier.startswith("store://") and project is None:
|
|
210
223
|
raise EntityError("Specify entity key or entity ID combined with project")
|
|
211
|
-
return
|
|
224
|
+
return delete_entity_api_ctx(
|
|
212
225
|
identifier=identifier,
|
|
213
226
|
entity_type=ENTITY_TYPE,
|
|
214
227
|
project=project,
|
|
@@ -2,8 +2,11 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import time
|
|
4
4
|
import typing
|
|
5
|
+
from typing import Any
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
import requests
|
|
8
|
+
|
|
9
|
+
from digitalhub.entities._base.crud import (
|
|
7
10
|
list_entity_api_base,
|
|
8
11
|
list_entity_api_ctx,
|
|
9
12
|
logs_api,
|
|
@@ -11,24 +14,22 @@ from digitalhub.entities._base.api_utils import (
|
|
|
11
14
|
resume_api,
|
|
12
15
|
stop_api,
|
|
13
16
|
)
|
|
14
|
-
from digitalhub.entities._base.unversioned
|
|
15
|
-
from digitalhub.entities.
|
|
16
|
-
from digitalhub.entities.
|
|
17
|
-
from digitalhub.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
get_entity_type_from_kind,
|
|
22
|
-
get_executable_kind,
|
|
23
|
-
)
|
|
17
|
+
from digitalhub.entities._base.entity.unversioned import UnversionedEntity
|
|
18
|
+
from digitalhub.entities._base.state import State
|
|
19
|
+
from digitalhub.entities._builders.spec import build_spec
|
|
20
|
+
from digitalhub.entities._builders.status import build_status
|
|
21
|
+
from digitalhub.entities.entity_types import EntityTypes
|
|
22
|
+
from digitalhub.registry.registry import registry
|
|
23
|
+
from digitalhub.runtimes.builder import build_runtime
|
|
24
24
|
from digitalhub.utils.exceptions import EntityError
|
|
25
25
|
from digitalhub.utils.logger import LOGGER
|
|
26
26
|
|
|
27
27
|
if typing.TYPE_CHECKING:
|
|
28
|
-
from digitalhub.entities._base.entity.
|
|
29
|
-
from digitalhub.entities.
|
|
30
|
-
from digitalhub.entities.run.
|
|
31
|
-
from digitalhub.
|
|
28
|
+
from digitalhub.entities._base.entity.material import MaterialEntity
|
|
29
|
+
from digitalhub.entities._base.metadata import Metadata
|
|
30
|
+
from digitalhub.entities.run.spec import RunSpec
|
|
31
|
+
from digitalhub.entities.run.status import RunStatus
|
|
32
|
+
from digitalhub.runtimes.base import Runtime
|
|
32
33
|
|
|
33
34
|
|
|
34
35
|
class Run(UnversionedEntity):
|
|
@@ -65,9 +66,10 @@ class Run(UnversionedEntity):
|
|
|
65
66
|
-------
|
|
66
67
|
None
|
|
67
68
|
"""
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
runtime = self._get_runtime()
|
|
70
|
+
executable = self._get_executable(runtime)
|
|
71
|
+
task = self._get_task(runtime)
|
|
72
|
+
new_spec = runtime.build(executable, task, self.to_dict())
|
|
71
73
|
self.spec = build_spec(
|
|
72
74
|
self.kind,
|
|
73
75
|
**new_spec,
|
|
@@ -91,7 +93,11 @@ class Run(UnversionedEntity):
|
|
|
91
93
|
self._set_state(State.RUNNING.value)
|
|
92
94
|
self.save(update=True)
|
|
93
95
|
|
|
94
|
-
|
|
96
|
+
# Try to get inputs if they exist
|
|
97
|
+
try:
|
|
98
|
+
self.spec.inputs = self.inputs(as_dict=True)
|
|
99
|
+
except EntityError:
|
|
100
|
+
pass
|
|
95
101
|
|
|
96
102
|
try:
|
|
97
103
|
status = self._get_runtime().run(self.to_dict())
|
|
@@ -141,6 +147,116 @@ class Run(UnversionedEntity):
|
|
|
141
147
|
LOGGER.info(f"Run {self.id} finished in {current:.2f} seconds.")
|
|
142
148
|
return self
|
|
143
149
|
|
|
150
|
+
def inputs(self, as_dict: bool = False) -> list[dict]:
|
|
151
|
+
"""
|
|
152
|
+
Get inputs passed in spec as objects or as dictionaries.
|
|
153
|
+
|
|
154
|
+
Parameters
|
|
155
|
+
----------
|
|
156
|
+
as_dict : bool
|
|
157
|
+
If True, return inputs as dictionaries.
|
|
158
|
+
|
|
159
|
+
Returns
|
|
160
|
+
-------
|
|
161
|
+
list[dict]
|
|
162
|
+
List of input objects.
|
|
163
|
+
"""
|
|
164
|
+
try:
|
|
165
|
+
return self.spec.get_inputs(as_dict=as_dict)
|
|
166
|
+
except AttributeError:
|
|
167
|
+
msg = f"Run of type {self.kind} has no inputs."
|
|
168
|
+
raise EntityError(msg)
|
|
169
|
+
|
|
170
|
+
def results(self) -> dict:
|
|
171
|
+
"""
|
|
172
|
+
Get results from runtime execution.
|
|
173
|
+
|
|
174
|
+
Returns
|
|
175
|
+
-------
|
|
176
|
+
dict
|
|
177
|
+
Results.
|
|
178
|
+
"""
|
|
179
|
+
try:
|
|
180
|
+
return self.status.get_results()
|
|
181
|
+
except AttributeError:
|
|
182
|
+
msg = f"Run of type {self.kind} has no results."
|
|
183
|
+
raise EntityError(msg)
|
|
184
|
+
|
|
185
|
+
def result(self, key: str) -> Any:
|
|
186
|
+
"""
|
|
187
|
+
Get result from runtime execution by key.
|
|
188
|
+
|
|
189
|
+
Parameters
|
|
190
|
+
----------
|
|
191
|
+
key : str
|
|
192
|
+
Key of the result.
|
|
193
|
+
|
|
194
|
+
Returns
|
|
195
|
+
-------
|
|
196
|
+
Any
|
|
197
|
+
Result.
|
|
198
|
+
"""
|
|
199
|
+
return self.results().get(key)
|
|
200
|
+
|
|
201
|
+
def outputs(self, as_key: bool = False, as_dict: bool = False) -> dict:
|
|
202
|
+
"""
|
|
203
|
+
Get run objects results.
|
|
204
|
+
|
|
205
|
+
Parameters
|
|
206
|
+
----------
|
|
207
|
+
as_key : bool
|
|
208
|
+
If True, return results as keys.
|
|
209
|
+
as_dict : bool
|
|
210
|
+
If True, return results as dictionaries.
|
|
211
|
+
|
|
212
|
+
Returns
|
|
213
|
+
-------
|
|
214
|
+
dict
|
|
215
|
+
List of output objects.
|
|
216
|
+
"""
|
|
217
|
+
try:
|
|
218
|
+
return self.status.get_outputs(as_key=as_key, as_dict=as_dict)
|
|
219
|
+
except AttributeError:
|
|
220
|
+
msg = f"Run of type {self.kind} has no outputs."
|
|
221
|
+
raise EntityError(msg)
|
|
222
|
+
|
|
223
|
+
def output(self, key: str, as_key: bool = False, as_dict: bool = False) -> MaterialEntity | dict | str | None:
|
|
224
|
+
"""
|
|
225
|
+
Get run object result by key.
|
|
226
|
+
|
|
227
|
+
Parameters
|
|
228
|
+
----------
|
|
229
|
+
key : str
|
|
230
|
+
Key of the result.
|
|
231
|
+
as_key : bool
|
|
232
|
+
If True, return result as key.
|
|
233
|
+
as_dict : bool
|
|
234
|
+
If True, return result as dictionary.
|
|
235
|
+
|
|
236
|
+
Returns
|
|
237
|
+
-------
|
|
238
|
+
Entity | dict | str | None
|
|
239
|
+
Result.
|
|
240
|
+
"""
|
|
241
|
+
return self.outputs(as_key=as_key, as_dict=as_dict).get(key)
|
|
242
|
+
|
|
243
|
+
def values(self) -> dict:
|
|
244
|
+
"""
|
|
245
|
+
Get values from runtime execution.
|
|
246
|
+
|
|
247
|
+
Returns
|
|
248
|
+
-------
|
|
249
|
+
dict
|
|
250
|
+
Values from backend.
|
|
251
|
+
"""
|
|
252
|
+
try:
|
|
253
|
+
value_list = getattr(self.spec, "values", [])
|
|
254
|
+
value_list = value_list if value_list is not None else []
|
|
255
|
+
return self.status.get_values(value_list)
|
|
256
|
+
except AttributeError:
|
|
257
|
+
msg = f"Run of type {self.kind} has no values."
|
|
258
|
+
raise EntityError(msg)
|
|
259
|
+
|
|
144
260
|
def logs(self) -> dict:
|
|
145
261
|
"""
|
|
146
262
|
Get object from backend.
|
|
@@ -165,6 +281,11 @@ class Run(UnversionedEntity):
|
|
|
165
281
|
"""
|
|
166
282
|
if not self._context().local and not self.spec.local_execution:
|
|
167
283
|
return stop_api(self.project, self.ENTITY_TYPE, self.id)
|
|
284
|
+
try:
|
|
285
|
+
self.status.stop()
|
|
286
|
+
except AttributeError:
|
|
287
|
+
raise EntityError("Stop is not supported in local execution.")
|
|
288
|
+
return
|
|
168
289
|
|
|
169
290
|
def resume(self) -> None:
|
|
170
291
|
"""
|
|
@@ -176,20 +297,45 @@ class Run(UnversionedEntity):
|
|
|
176
297
|
"""
|
|
177
298
|
if not self._context().local and not self.spec.local_execution:
|
|
178
299
|
return resume_api(self.project, self.ENTITY_TYPE, self.id)
|
|
179
|
-
self.run()
|
|
180
300
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
301
|
+
try:
|
|
302
|
+
self.status.resume()
|
|
303
|
+
except AttributeError:
|
|
304
|
+
raise EntityError("Resume is not supported in local execution.")
|
|
305
|
+
return
|
|
306
|
+
# re-run
|
|
307
|
+
# TODO verify the logic and order
|
|
308
|
+
self.run()
|
|
184
309
|
|
|
185
|
-
def
|
|
310
|
+
def invoke(self, **kwargs) -> requests.Response:
|
|
186
311
|
"""
|
|
187
|
-
|
|
312
|
+
Invoke run.
|
|
313
|
+
|
|
314
|
+
Parameters
|
|
315
|
+
----------
|
|
316
|
+
kwargs
|
|
317
|
+
Keyword arguments to pass to the request.
|
|
188
318
|
|
|
189
319
|
Returns
|
|
190
320
|
-------
|
|
191
|
-
|
|
321
|
+
requests.Response
|
|
322
|
+
Response from service.
|
|
192
323
|
"""
|
|
324
|
+
try:
|
|
325
|
+
if not self._context().local and not self.spec.local_execution:
|
|
326
|
+
local = False
|
|
327
|
+
else:
|
|
328
|
+
local = True
|
|
329
|
+
if kwargs is None:
|
|
330
|
+
kwargs = {}
|
|
331
|
+
return self.status.invoke(local, **kwargs)
|
|
332
|
+
except AttributeError:
|
|
333
|
+
msg = f"Run of type {self.kind} has no invoke operation."
|
|
334
|
+
raise EntityError(msg)
|
|
335
|
+
|
|
336
|
+
##############################
|
|
337
|
+
# Helpers
|
|
338
|
+
##############################
|
|
193
339
|
|
|
194
340
|
def _is_ready_to_run(self) -> bool:
|
|
195
341
|
"""
|
|
@@ -258,18 +404,22 @@ class Run(UnversionedEntity):
|
|
|
258
404
|
"""
|
|
259
405
|
return build_runtime(self.kind, self.project)
|
|
260
406
|
|
|
261
|
-
def _get_executable(self) -> dict:
|
|
407
|
+
def _get_executable(self, runtime: Runtime) -> dict:
|
|
262
408
|
"""
|
|
263
|
-
Get
|
|
264
|
-
|
|
409
|
+
Get object from backend. Reimplemented to avoid circular imports.
|
|
410
|
+
|
|
411
|
+
Parameters
|
|
412
|
+
----------
|
|
413
|
+
runtime : Runtime
|
|
414
|
+
Runtime object.
|
|
265
415
|
|
|
266
416
|
Returns
|
|
267
417
|
-------
|
|
268
418
|
dict
|
|
269
419
|
Executable (function or workflow) from backend.
|
|
270
420
|
"""
|
|
271
|
-
exec_kind = get_executable_kind(
|
|
272
|
-
entity_type =
|
|
421
|
+
exec_kind = runtime.get_executable_kind()
|
|
422
|
+
entity_type = registry.get_entity_type(exec_kind)
|
|
273
423
|
splitted = self.spec.task.split("/")
|
|
274
424
|
exec_name = splitted[-1].split(":")[0]
|
|
275
425
|
exec_id = splitted[-1].split(":")[1]
|
|
@@ -280,17 +430,21 @@ class Run(UnversionedEntity):
|
|
|
280
430
|
entity_id=exec_id,
|
|
281
431
|
)
|
|
282
432
|
|
|
283
|
-
def _get_task(self) -> dict:
|
|
433
|
+
def _get_task(self, runtime: Runtime) -> dict:
|
|
284
434
|
"""
|
|
285
|
-
Get object from backend. Reimplemented to avoid
|
|
286
|
-
|
|
435
|
+
Get object from backend. Reimplemented to avoid circular imports.
|
|
436
|
+
|
|
437
|
+
Parameters
|
|
438
|
+
----------
|
|
439
|
+
runtime : Runtime
|
|
440
|
+
Runtime object.
|
|
287
441
|
|
|
288
442
|
Returns
|
|
289
443
|
-------
|
|
290
444
|
dict
|
|
291
445
|
Task from backend.
|
|
292
446
|
"""
|
|
293
|
-
executable_kind = get_executable_kind(
|
|
447
|
+
executable_kind = runtime.get_executable_kind()
|
|
294
448
|
exec_string = f"{executable_kind}://{self.spec.task.split('://')[1]}"
|
|
295
449
|
|
|
296
450
|
# Local backend
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing
|
|
4
|
+
|
|
5
|
+
from digitalhub.entities._base.spec.base import Spec, SpecParams
|
|
6
|
+
from digitalhub.entities.artifact.crud import get_artifact
|
|
7
|
+
from digitalhub.entities.dataitem.crud import get_dataitem
|
|
8
|
+
from digitalhub.entities.entity_types import EntityTypes
|
|
9
|
+
from digitalhub.entities.model.crud import get_model
|
|
10
|
+
from digitalhub.entities.task.models import K8s
|
|
11
|
+
from digitalhub.entities.utils import parse_entity_key
|
|
12
|
+
|
|
13
|
+
if typing.TYPE_CHECKING:
|
|
14
|
+
from digitalhub.entities._base.entity.base import Entity
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
ENTITY_FUNC = {
|
|
18
|
+
EntityTypes.ARTIFACT.value: get_artifact,
|
|
19
|
+
EntityTypes.DATAITEM.value: get_dataitem,
|
|
20
|
+
EntityTypes.MODEL.value: get_model,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class RunSpec(Spec):
|
|
25
|
+
"""Run specification."""
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
task: str,
|
|
30
|
+
local_execution: bool = False,
|
|
31
|
+
function: str | None = None,
|
|
32
|
+
node_selector: dict | None = None,
|
|
33
|
+
volumes: list | None = None,
|
|
34
|
+
resources: dict | None = None,
|
|
35
|
+
affinity: dict | None = None,
|
|
36
|
+
tolerations: list | None = None,
|
|
37
|
+
envs: list | None = None,
|
|
38
|
+
secrets: list | None = None,
|
|
39
|
+
profile: str | None = None,
|
|
40
|
+
**kwargs,
|
|
41
|
+
) -> None:
|
|
42
|
+
self.task = task
|
|
43
|
+
self.local_execution = local_execution
|
|
44
|
+
self.function = function
|
|
45
|
+
self.node_selector = node_selector
|
|
46
|
+
self.volumes = volumes
|
|
47
|
+
self.resources = resources
|
|
48
|
+
self.affinity = affinity
|
|
49
|
+
self.tolerations = tolerations
|
|
50
|
+
self.envs = envs
|
|
51
|
+
self.secrets = secrets
|
|
52
|
+
self.profile = profile
|
|
53
|
+
|
|
54
|
+
def get_inputs(self, as_dict: bool = False) -> dict:
|
|
55
|
+
"""
|
|
56
|
+
Get inputs.
|
|
57
|
+
|
|
58
|
+
Returns
|
|
59
|
+
-------
|
|
60
|
+
dict
|
|
61
|
+
The inputs.
|
|
62
|
+
"""
|
|
63
|
+
inputs = {}
|
|
64
|
+
if not hasattr(self, "inputs") or self.inputs is None:
|
|
65
|
+
return inputs
|
|
66
|
+
|
|
67
|
+
for parameter, item in self.inputs.items():
|
|
68
|
+
parameter_type = self._parse_parameter(parameter)
|
|
69
|
+
|
|
70
|
+
# Get entity from key
|
|
71
|
+
if parameter_type == "key":
|
|
72
|
+
key = self._collect_key(item)
|
|
73
|
+
entity = self._collect_entity(key)
|
|
74
|
+
if as_dict:
|
|
75
|
+
entity = entity.to_dict()
|
|
76
|
+
inputs[parameter] = entity
|
|
77
|
+
|
|
78
|
+
# Create entity from parameter
|
|
79
|
+
elif parameter_type == "create":
|
|
80
|
+
raise NotImplementedError
|
|
81
|
+
|
|
82
|
+
return inputs
|
|
83
|
+
|
|
84
|
+
@staticmethod
|
|
85
|
+
def _parse_parameter(parameter: str) -> str:
|
|
86
|
+
"""
|
|
87
|
+
Parse parameter.
|
|
88
|
+
|
|
89
|
+
Parameters
|
|
90
|
+
----------
|
|
91
|
+
parameter : str
|
|
92
|
+
Parameter.
|
|
93
|
+
|
|
94
|
+
Returns
|
|
95
|
+
-------
|
|
96
|
+
str
|
|
97
|
+
The parsed parameter.
|
|
98
|
+
"""
|
|
99
|
+
if len(parameter.split(":")) == 1:
|
|
100
|
+
return "key"
|
|
101
|
+
return "create"
|
|
102
|
+
|
|
103
|
+
@staticmethod
|
|
104
|
+
def _collect_key(item: str | dict) -> str:
|
|
105
|
+
"""
|
|
106
|
+
Collect key from item.
|
|
107
|
+
|
|
108
|
+
Parameters
|
|
109
|
+
----------
|
|
110
|
+
item : str | dict
|
|
111
|
+
Key or dict representation of the entity.
|
|
112
|
+
|
|
113
|
+
Returns
|
|
114
|
+
-------
|
|
115
|
+
str
|
|
116
|
+
The key.
|
|
117
|
+
"""
|
|
118
|
+
if isinstance(item, str):
|
|
119
|
+
return item
|
|
120
|
+
return item.get("key")
|
|
121
|
+
|
|
122
|
+
@staticmethod
|
|
123
|
+
def _collect_entity(key: str) -> Entity:
|
|
124
|
+
"""
|
|
125
|
+
Collect entity from key.
|
|
126
|
+
|
|
127
|
+
Parameters
|
|
128
|
+
----------
|
|
129
|
+
key : str
|
|
130
|
+
Key of the entity.
|
|
131
|
+
|
|
132
|
+
Returns
|
|
133
|
+
-------
|
|
134
|
+
Entity
|
|
135
|
+
The entity.
|
|
136
|
+
"""
|
|
137
|
+
_, entity_type, _, _, _ = parse_entity_key(key)
|
|
138
|
+
return ENTITY_FUNC[entity_type](key)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class RunParams(SpecParams, K8s):
|
|
142
|
+
"""
|
|
143
|
+
Run parameters.
|
|
144
|
+
"""
|
|
145
|
+
|
|
146
|
+
function: str = None
|
|
147
|
+
"""The function associated with the run."""
|
|
148
|
+
|
|
149
|
+
task: str = None
|
|
150
|
+
"""The task string associated with the run."""
|
|
151
|
+
|
|
152
|
+
local_execution: bool = False
|
|
153
|
+
"""Flag to indicate if the run will be executed locally."""
|