digitalhub 0.7.0b2__py3-none-any.whl → 0.8.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 +63 -93
- digitalhub/client/__init__.py +0 -0
- digitalhub/client/_base/__init__.py +0 -0
- digitalhub/client/_base/client.py +56 -0
- digitalhub/client/api.py +63 -0
- digitalhub/client/builder.py +50 -0
- digitalhub/client/dhcore/__init__.py +0 -0
- digitalhub/client/dhcore/client.py +669 -0
- digitalhub/client/dhcore/env.py +21 -0
- digitalhub/client/dhcore/models.py +46 -0
- digitalhub/client/dhcore/utils.py +111 -0
- digitalhub/client/local/__init__.py +0 -0
- digitalhub/client/local/client.py +533 -0
- digitalhub/context/__init__.py +0 -0
- digitalhub/context/api.py +93 -0
- digitalhub/context/builder.py +94 -0
- digitalhub/context/context.py +136 -0
- digitalhub/datastores/__init__.py +0 -0
- digitalhub/datastores/_base/__init__.py +0 -0
- digitalhub/datastores/_base/datastore.py +85 -0
- digitalhub/datastores/api.py +37 -0
- digitalhub/datastores/builder.py +110 -0
- digitalhub/datastores/local/__init__.py +0 -0
- digitalhub/datastores/local/datastore.py +50 -0
- digitalhub/datastores/remote/__init__.py +0 -0
- digitalhub/datastores/remote/datastore.py +31 -0
- digitalhub/datastores/s3/__init__.py +0 -0
- digitalhub/datastores/s3/datastore.py +46 -0
- digitalhub/datastores/sql/__init__.py +0 -0
- digitalhub/datastores/sql/datastore.py +68 -0
- digitalhub/entities/__init__.py +0 -0
- digitalhub/entities/_base/__init__.py +0 -0
- digitalhub/entities/_base/_base/__init__.py +0 -0
- digitalhub/entities/_base/_base/entity.py +82 -0
- digitalhub/entities/_base/api_utils.py +620 -0
- digitalhub/entities/_base/context/__init__.py +0 -0
- digitalhub/entities/_base/context/entity.py +118 -0
- digitalhub/entities/_base/crud.py +468 -0
- digitalhub/entities/_base/entity/__init__.py +0 -0
- digitalhub/entities/_base/entity/_constructors/__init__.py +0 -0
- digitalhub/entities/_base/entity/_constructors/metadata.py +44 -0
- digitalhub/entities/_base/entity/_constructors/name.py +31 -0
- digitalhub/entities/_base/entity/_constructors/spec.py +33 -0
- digitalhub/entities/_base/entity/_constructors/status.py +52 -0
- digitalhub/entities/_base/entity/_constructors/uuid.py +26 -0
- digitalhub/entities/_base/entity/builder.py +175 -0
- digitalhub/entities/_base/entity/entity.py +106 -0
- digitalhub/entities/_base/entity/metadata.py +59 -0
- digitalhub/entities/_base/entity/spec.py +58 -0
- digitalhub/entities/_base/entity/status.py +43 -0
- digitalhub/entities/_base/executable/__init__.py +0 -0
- digitalhub/entities/_base/executable/entity.py +405 -0
- digitalhub/entities/_base/material/__init__.py +0 -0
- digitalhub/entities/_base/material/entity.py +214 -0
- digitalhub/entities/_base/material/spec.py +22 -0
- digitalhub/entities/_base/material/status.py +49 -0
- digitalhub/entities/_base/runtime_entity/__init__.py +0 -0
- digitalhub/entities/_base/runtime_entity/builder.py +106 -0
- digitalhub/entities/_base/unversioned/__init__.py +0 -0
- digitalhub/entities/_base/unversioned/builder.py +66 -0
- digitalhub/entities/_base/unversioned/entity.py +49 -0
- digitalhub/entities/_base/versioned/__init__.py +0 -0
- digitalhub/entities/_base/versioned/builder.py +68 -0
- digitalhub/entities/_base/versioned/entity.py +53 -0
- digitalhub/entities/artifact/__init__.py +0 -0
- digitalhub/entities/artifact/_base/__init__.py +0 -0
- digitalhub/entities/artifact/_base/builder.py +86 -0
- digitalhub/entities/artifact/_base/entity.py +39 -0
- digitalhub/entities/artifact/_base/spec.py +15 -0
- digitalhub/entities/artifact/_base/status.py +9 -0
- digitalhub/entities/artifact/artifact/__init__.py +0 -0
- digitalhub/entities/artifact/artifact/builder.py +18 -0
- digitalhub/entities/artifact/artifact/entity.py +32 -0
- digitalhub/entities/artifact/artifact/spec.py +27 -0
- digitalhub/entities/artifact/artifact/status.py +15 -0
- digitalhub/entities/artifact/crud.py +332 -0
- digitalhub/entities/builders.py +63 -0
- digitalhub/entities/dataitem/__init__.py +0 -0
- digitalhub/entities/dataitem/_base/__init__.py +0 -0
- digitalhub/entities/dataitem/_base/builder.py +86 -0
- digitalhub/entities/dataitem/_base/entity.py +75 -0
- digitalhub/entities/dataitem/_base/spec.py +15 -0
- digitalhub/entities/dataitem/_base/status.py +20 -0
- digitalhub/entities/dataitem/crud.py +372 -0
- digitalhub/entities/dataitem/dataitem/__init__.py +0 -0
- digitalhub/entities/dataitem/dataitem/builder.py +18 -0
- digitalhub/entities/dataitem/dataitem/entity.py +32 -0
- digitalhub/entities/dataitem/dataitem/spec.py +15 -0
- digitalhub/entities/dataitem/dataitem/status.py +9 -0
- digitalhub/entities/dataitem/iceberg/__init__.py +0 -0
- digitalhub/entities/dataitem/iceberg/builder.py +18 -0
- digitalhub/entities/dataitem/iceberg/entity.py +32 -0
- digitalhub/entities/dataitem/iceberg/spec.py +15 -0
- digitalhub/entities/dataitem/iceberg/status.py +9 -0
- digitalhub/entities/dataitem/table/__init__.py +0 -0
- digitalhub/entities/dataitem/table/builder.py +18 -0
- digitalhub/entities/dataitem/table/entity.py +146 -0
- digitalhub/entities/dataitem/table/models.py +62 -0
- digitalhub/entities/dataitem/table/spec.py +25 -0
- digitalhub/entities/dataitem/table/status.py +9 -0
- digitalhub/entities/function/__init__.py +0 -0
- digitalhub/entities/function/_base/__init__.py +0 -0
- digitalhub/entities/function/_base/builder.py +79 -0
- digitalhub/entities/function/_base/entity.py +98 -0
- digitalhub/entities/function/_base/models.py +118 -0
- digitalhub/entities/function/_base/spec.py +15 -0
- digitalhub/entities/function/_base/status.py +9 -0
- digitalhub/entities/function/crud.py +279 -0
- digitalhub/entities/model/__init__.py +0 -0
- digitalhub/entities/model/_base/__init__.py +0 -0
- digitalhub/entities/model/_base/builder.py +86 -0
- digitalhub/entities/model/_base/entity.py +34 -0
- digitalhub/entities/model/_base/spec.py +49 -0
- digitalhub/entities/model/_base/status.py +9 -0
- digitalhub/entities/model/crud.py +331 -0
- digitalhub/entities/model/huggingface/__init__.py +0 -0
- digitalhub/entities/model/huggingface/builder.py +18 -0
- digitalhub/entities/model/huggingface/entity.py +32 -0
- digitalhub/entities/model/huggingface/spec.py +36 -0
- digitalhub/entities/model/huggingface/status.py +9 -0
- digitalhub/entities/model/mlflow/__init__.py +0 -0
- digitalhub/entities/model/mlflow/builder.py +18 -0
- digitalhub/entities/model/mlflow/entity.py +32 -0
- digitalhub/entities/model/mlflow/models.py +26 -0
- digitalhub/entities/model/mlflow/spec.py +44 -0
- digitalhub/entities/model/mlflow/status.py +9 -0
- digitalhub/entities/model/mlflow/utils.py +81 -0
- digitalhub/entities/model/model/__init__.py +0 -0
- digitalhub/entities/model/model/builder.py +18 -0
- digitalhub/entities/model/model/entity.py +32 -0
- digitalhub/entities/model/model/spec.py +15 -0
- digitalhub/entities/model/model/status.py +9 -0
- digitalhub/entities/model/sklearn/__init__.py +0 -0
- digitalhub/entities/model/sklearn/builder.py +18 -0
- digitalhub/entities/model/sklearn/entity.py +32 -0
- digitalhub/entities/model/sklearn/spec.py +15 -0
- digitalhub/entities/model/sklearn/status.py +9 -0
- digitalhub/entities/project/__init__.py +0 -0
- digitalhub/entities/project/_base/__init__.py +0 -0
- digitalhub/entities/project/_base/builder.py +128 -0
- digitalhub/entities/project/_base/entity.py +2078 -0
- digitalhub/entities/project/_base/spec.py +50 -0
- digitalhub/entities/project/_base/status.py +9 -0
- digitalhub/entities/project/crud.py +357 -0
- digitalhub/entities/run/__init__.py +0 -0
- digitalhub/entities/run/_base/__init__.py +0 -0
- digitalhub/entities/run/_base/builder.py +94 -0
- digitalhub/entities/run/_base/entity.py +307 -0
- digitalhub/entities/run/_base/spec.py +50 -0
- digitalhub/entities/run/_base/status.py +9 -0
- digitalhub/entities/run/crud.py +219 -0
- digitalhub/entities/secret/__init__.py +0 -0
- digitalhub/entities/secret/_base/__init__.py +0 -0
- digitalhub/entities/secret/_base/builder.py +81 -0
- digitalhub/entities/secret/_base/entity.py +74 -0
- digitalhub/entities/secret/_base/spec.py +35 -0
- digitalhub/entities/secret/_base/status.py +9 -0
- digitalhub/entities/secret/crud.py +290 -0
- digitalhub/entities/task/__init__.py +0 -0
- digitalhub/entities/task/_base/__init__.py +0 -0
- digitalhub/entities/task/_base/builder.py +91 -0
- digitalhub/entities/task/_base/entity.py +136 -0
- digitalhub/entities/task/_base/models.py +208 -0
- digitalhub/entities/task/_base/spec.py +53 -0
- digitalhub/entities/task/_base/status.py +9 -0
- digitalhub/entities/task/crud.py +228 -0
- digitalhub/entities/utils/__init__.py +0 -0
- digitalhub/entities/utils/api.py +346 -0
- digitalhub/entities/utils/entity_types.py +19 -0
- digitalhub/entities/utils/state.py +31 -0
- digitalhub/entities/utils/utils.py +202 -0
- digitalhub/entities/workflow/__init__.py +0 -0
- digitalhub/entities/workflow/_base/__init__.py +0 -0
- digitalhub/entities/workflow/_base/builder.py +79 -0
- digitalhub/entities/workflow/_base/entity.py +74 -0
- digitalhub/entities/workflow/_base/spec.py +15 -0
- digitalhub/entities/workflow/_base/status.py +9 -0
- digitalhub/entities/workflow/crud.py +278 -0
- digitalhub/factory/__init__.py +0 -0
- digitalhub/factory/api.py +277 -0
- digitalhub/factory/factory.py +268 -0
- digitalhub/factory/utils.py +90 -0
- digitalhub/readers/__init__.py +0 -0
- digitalhub/readers/_base/__init__.py +0 -0
- digitalhub/readers/_base/builder.py +26 -0
- digitalhub/readers/_base/reader.py +70 -0
- digitalhub/readers/api.py +80 -0
- digitalhub/readers/factory.py +133 -0
- digitalhub/readers/pandas/__init__.py +0 -0
- digitalhub/readers/pandas/builder.py +29 -0
- digitalhub/readers/pandas/reader.py +207 -0
- digitalhub/runtimes/__init__.py +0 -0
- digitalhub/runtimes/_base.py +102 -0
- digitalhub/runtimes/builder.py +32 -0
- digitalhub/stores/__init__.py +0 -0
- digitalhub/stores/_base/__init__.py +0 -0
- digitalhub/stores/_base/store.py +189 -0
- digitalhub/stores/api.py +54 -0
- digitalhub/stores/builder.py +211 -0
- digitalhub/stores/local/__init__.py +0 -0
- digitalhub/stores/local/store.py +230 -0
- digitalhub/stores/remote/__init__.py +0 -0
- digitalhub/stores/remote/store.py +143 -0
- digitalhub/stores/s3/__init__.py +0 -0
- digitalhub/stores/s3/store.py +563 -0
- digitalhub/stores/sql/__init__.py +0 -0
- digitalhub/stores/sql/store.py +328 -0
- digitalhub/utils/__init__.py +0 -0
- digitalhub/utils/data_utils.py +127 -0
- digitalhub/utils/exceptions.py +67 -0
- digitalhub/utils/file_utils.py +204 -0
- digitalhub/utils/generic_utils.py +183 -0
- digitalhub/utils/git_utils.py +148 -0
- digitalhub/utils/io_utils.py +116 -0
- digitalhub/utils/logger.py +17 -0
- digitalhub/utils/s3_utils.py +58 -0
- digitalhub/utils/uri_utils.py +56 -0
- {digitalhub-0.7.0b2.dist-info → digitalhub-0.8.0.dist-info}/METADATA +30 -13
- digitalhub-0.8.0.dist-info/RECORD +231 -0
- {digitalhub-0.7.0b2.dist-info → digitalhub-0.8.0.dist-info}/WHEEL +1 -1
- test/local/CRUD/test_artifacts.py +96 -0
- test/local/CRUD/test_dataitems.py +96 -0
- test/local/CRUD/test_models.py +95 -0
- test/test_crud_functions.py +1 -1
- test/test_crud_runs.py +1 -1
- test/test_crud_tasks.py +1 -1
- digitalhub-0.7.0b2.dist-info/RECORD +0 -14
- test/test_crud_artifacts.py +0 -96
- test/test_crud_dataitems.py +0 -96
- {digitalhub-0.7.0b2.dist-info → digitalhub-0.8.0.dist-info}/LICENSE.txt +0 -0
- {digitalhub-0.7.0b2.dist-info → digitalhub-0.8.0.dist-info}/top_level.txt +0 -0
- /test/{test_imports.py → local/imports/test_imports.py} +0 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
import typing
|
|
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
|
+
from digitalhub.entities._base.unversioned.entity import UnversionedEntity
|
|
15
|
+
from digitalhub.entities.utils.entity_types import EntityTypes
|
|
16
|
+
from digitalhub.entities.utils.state import State
|
|
17
|
+
from digitalhub.factory.api import (
|
|
18
|
+
build_runtime,
|
|
19
|
+
build_spec,
|
|
20
|
+
build_status,
|
|
21
|
+
get_entity_type_from_kind,
|
|
22
|
+
get_executable_kind,
|
|
23
|
+
)
|
|
24
|
+
from digitalhub.utils.exceptions import EntityError
|
|
25
|
+
from digitalhub.utils.logger import LOGGER
|
|
26
|
+
|
|
27
|
+
if typing.TYPE_CHECKING:
|
|
28
|
+
from digitalhub.entities._base.entity.metadata import Metadata
|
|
29
|
+
from digitalhub.entities.run._base.spec import RunSpec
|
|
30
|
+
from digitalhub.entities.run._base.status import RunStatus
|
|
31
|
+
from digitalhub.runtimes._base import Runtime
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Run(UnversionedEntity):
|
|
35
|
+
"""
|
|
36
|
+
A class representing a run.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
ENTITY_TYPE = EntityTypes.RUN.value
|
|
40
|
+
|
|
41
|
+
def __init__(
|
|
42
|
+
self,
|
|
43
|
+
project: str,
|
|
44
|
+
uuid: str,
|
|
45
|
+
kind: str,
|
|
46
|
+
metadata: Metadata,
|
|
47
|
+
spec: RunSpec,
|
|
48
|
+
status: RunStatus,
|
|
49
|
+
user: str | None = None,
|
|
50
|
+
) -> None:
|
|
51
|
+
super().__init__(project, uuid, kind, metadata, spec, status, user)
|
|
52
|
+
|
|
53
|
+
self.spec: RunSpec
|
|
54
|
+
self.status: RunStatus
|
|
55
|
+
|
|
56
|
+
##############################
|
|
57
|
+
# Run Methods
|
|
58
|
+
##############################
|
|
59
|
+
|
|
60
|
+
def build(self) -> None:
|
|
61
|
+
"""
|
|
62
|
+
Build run.
|
|
63
|
+
|
|
64
|
+
Returns
|
|
65
|
+
-------
|
|
66
|
+
None
|
|
67
|
+
"""
|
|
68
|
+
executable = self._get_executable()
|
|
69
|
+
task = self._get_task()
|
|
70
|
+
new_spec = self._get_runtime().build(executable, task, self.to_dict())
|
|
71
|
+
self.spec = build_spec(
|
|
72
|
+
self.kind,
|
|
73
|
+
**new_spec,
|
|
74
|
+
)
|
|
75
|
+
self._set_state(State.BUILT.value)
|
|
76
|
+
self.save()
|
|
77
|
+
|
|
78
|
+
def run(self) -> Run:
|
|
79
|
+
"""
|
|
80
|
+
Run run.
|
|
81
|
+
|
|
82
|
+
Returns
|
|
83
|
+
-------
|
|
84
|
+
Run
|
|
85
|
+
Run object.
|
|
86
|
+
"""
|
|
87
|
+
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
|
+
|
|
94
|
+
self._setup_execution()
|
|
95
|
+
|
|
96
|
+
try:
|
|
97
|
+
status = self._get_runtime().run(self.to_dict())
|
|
98
|
+
except Exception as e:
|
|
99
|
+
self.refresh()
|
|
100
|
+
if self.spec.local_execution:
|
|
101
|
+
self._set_state(State.ERROR.value)
|
|
102
|
+
self._set_message(str(e))
|
|
103
|
+
self.save(update=True)
|
|
104
|
+
raise e
|
|
105
|
+
|
|
106
|
+
self.refresh()
|
|
107
|
+
if not self.spec.local_execution:
|
|
108
|
+
status.pop("state", None)
|
|
109
|
+
new_status = {**self.status.to_dict(), **status}
|
|
110
|
+
self._set_status(new_status)
|
|
111
|
+
self.save(update=True)
|
|
112
|
+
return self
|
|
113
|
+
|
|
114
|
+
def wait(self, log_info: bool = True) -> Run:
|
|
115
|
+
"""
|
|
116
|
+
Wait for run to finish.
|
|
117
|
+
|
|
118
|
+
Parameters
|
|
119
|
+
----------
|
|
120
|
+
log_info : bool
|
|
121
|
+
If True, log information.
|
|
122
|
+
|
|
123
|
+
Returns
|
|
124
|
+
-------
|
|
125
|
+
Run
|
|
126
|
+
Run object.
|
|
127
|
+
"""
|
|
128
|
+
start = time.time()
|
|
129
|
+
while True:
|
|
130
|
+
if log_info:
|
|
131
|
+
LOGGER.info(f"Waiting for run {self.id} to finish...")
|
|
132
|
+
self.refresh()
|
|
133
|
+
time.sleep(5)
|
|
134
|
+
if self.status.state in [
|
|
135
|
+
State.STOPPED.value,
|
|
136
|
+
State.ERROR.value,
|
|
137
|
+
State.COMPLETED.value,
|
|
138
|
+
]:
|
|
139
|
+
if log_info:
|
|
140
|
+
current = time.time() - start
|
|
141
|
+
LOGGER.info(f"Run {self.id} finished in {current:.2f} seconds.")
|
|
142
|
+
return self
|
|
143
|
+
|
|
144
|
+
def logs(self) -> dict:
|
|
145
|
+
"""
|
|
146
|
+
Get object from backend.
|
|
147
|
+
Returns empty dictionary if context is local.
|
|
148
|
+
|
|
149
|
+
Returns
|
|
150
|
+
-------
|
|
151
|
+
dict
|
|
152
|
+
Logs from backend.
|
|
153
|
+
"""
|
|
154
|
+
if self._context().local:
|
|
155
|
+
return {}
|
|
156
|
+
return logs_api(self.project, self.ENTITY_TYPE, self.id)
|
|
157
|
+
|
|
158
|
+
def stop(self) -> None:
|
|
159
|
+
"""
|
|
160
|
+
Stop run.
|
|
161
|
+
|
|
162
|
+
Returns
|
|
163
|
+
-------
|
|
164
|
+
None
|
|
165
|
+
"""
|
|
166
|
+
if not self._context().local and not self.spec.local_execution:
|
|
167
|
+
return stop_api(self.project, self.ENTITY_TYPE, self.id)
|
|
168
|
+
|
|
169
|
+
def resume(self) -> None:
|
|
170
|
+
"""
|
|
171
|
+
Resume run.
|
|
172
|
+
|
|
173
|
+
Returns
|
|
174
|
+
-------
|
|
175
|
+
None
|
|
176
|
+
"""
|
|
177
|
+
if not self._context().local and not self.spec.local_execution:
|
|
178
|
+
return resume_api(self.project, self.ENTITY_TYPE, self.id)
|
|
179
|
+
self.run()
|
|
180
|
+
|
|
181
|
+
##############################
|
|
182
|
+
# Helpers
|
|
183
|
+
##############################
|
|
184
|
+
|
|
185
|
+
def _setup_execution(self) -> None:
|
|
186
|
+
"""
|
|
187
|
+
Setup run execution. In base class, nothing to do.
|
|
188
|
+
|
|
189
|
+
Returns
|
|
190
|
+
-------
|
|
191
|
+
None
|
|
192
|
+
"""
|
|
193
|
+
|
|
194
|
+
def _is_ready_to_run(self) -> bool:
|
|
195
|
+
"""
|
|
196
|
+
Check if run is in a state ready for running (BUILT or STOPPED).
|
|
197
|
+
|
|
198
|
+
Returns
|
|
199
|
+
-------
|
|
200
|
+
bool
|
|
201
|
+
True if run is in runnable state, False otherwise.
|
|
202
|
+
"""
|
|
203
|
+
return (self.status.state == State.BUILT.value) or (self.status.state == State.STOPPED.value)
|
|
204
|
+
|
|
205
|
+
def _set_status(self, status: dict) -> None:
|
|
206
|
+
"""
|
|
207
|
+
Set run status.
|
|
208
|
+
|
|
209
|
+
Parameters
|
|
210
|
+
----------
|
|
211
|
+
status : dict
|
|
212
|
+
Status to set.
|
|
213
|
+
|
|
214
|
+
Returns
|
|
215
|
+
-------
|
|
216
|
+
None
|
|
217
|
+
"""
|
|
218
|
+
self.status: RunStatus = build_status(self.kind, **status)
|
|
219
|
+
|
|
220
|
+
def _set_state(self, state: str) -> None:
|
|
221
|
+
"""
|
|
222
|
+
Update run state.
|
|
223
|
+
|
|
224
|
+
Parameters
|
|
225
|
+
----------
|
|
226
|
+
state : str
|
|
227
|
+
State to set.
|
|
228
|
+
|
|
229
|
+
Returns
|
|
230
|
+
-------
|
|
231
|
+
None
|
|
232
|
+
"""
|
|
233
|
+
self.status.state = state
|
|
234
|
+
|
|
235
|
+
def _set_message(self, message: str) -> None:
|
|
236
|
+
"""
|
|
237
|
+
Update run message.
|
|
238
|
+
|
|
239
|
+
Parameters
|
|
240
|
+
----------
|
|
241
|
+
message : str
|
|
242
|
+
Message to set.
|
|
243
|
+
|
|
244
|
+
Returns
|
|
245
|
+
-------
|
|
246
|
+
None
|
|
247
|
+
"""
|
|
248
|
+
self.status.message = message
|
|
249
|
+
|
|
250
|
+
def _get_runtime(self) -> Runtime:
|
|
251
|
+
"""
|
|
252
|
+
Build runtime to build run or execute it.
|
|
253
|
+
|
|
254
|
+
Returns
|
|
255
|
+
-------
|
|
256
|
+
Runtime
|
|
257
|
+
Runtime object.
|
|
258
|
+
"""
|
|
259
|
+
return build_runtime(self.kind, self.project)
|
|
260
|
+
|
|
261
|
+
def _get_executable(self) -> dict:
|
|
262
|
+
"""
|
|
263
|
+
Get executable object from backend. Reimplemented to avoid
|
|
264
|
+
circular imports.
|
|
265
|
+
|
|
266
|
+
Returns
|
|
267
|
+
-------
|
|
268
|
+
dict
|
|
269
|
+
Executable (function or workflow) from backend.
|
|
270
|
+
"""
|
|
271
|
+
exec_kind = get_executable_kind(self.kind)
|
|
272
|
+
entity_type = get_entity_type_from_kind(exec_kind)
|
|
273
|
+
splitted = self.spec.task.split("/")
|
|
274
|
+
exec_name = splitted[-1].split(":")[0]
|
|
275
|
+
exec_id = splitted[-1].split(":")[1]
|
|
276
|
+
return read_entity_api_ctx(
|
|
277
|
+
exec_name,
|
|
278
|
+
entity_type=entity_type,
|
|
279
|
+
project=self.project,
|
|
280
|
+
entity_id=exec_id,
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
def _get_task(self) -> dict:
|
|
284
|
+
"""
|
|
285
|
+
Get object from backend. Reimplemented to avoid
|
|
286
|
+
circular imports.
|
|
287
|
+
|
|
288
|
+
Returns
|
|
289
|
+
-------
|
|
290
|
+
dict
|
|
291
|
+
Task from backend.
|
|
292
|
+
"""
|
|
293
|
+
executable_kind = get_executable_kind(self.kind)
|
|
294
|
+
exec_string = f"{executable_kind}://{self.spec.task.split('://')[1]}"
|
|
295
|
+
|
|
296
|
+
# Local backend
|
|
297
|
+
if self._context().local:
|
|
298
|
+
tasks = list_entity_api_base(self._context().client, EntityTypes.TASK.value)
|
|
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]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from digitalhub.entities._base.entity.spec import Spec, SpecValidator
|
|
4
|
+
from digitalhub.entities.task._base.models import K8s
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class RunSpec(Spec):
|
|
8
|
+
"""RunSpec specifications."""
|
|
9
|
+
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
task: str,
|
|
13
|
+
local_execution: bool = False,
|
|
14
|
+
function: str | None = None,
|
|
15
|
+
node_selector: dict | None = None,
|
|
16
|
+
volumes: list | None = None,
|
|
17
|
+
resources: dict | None = None,
|
|
18
|
+
affinity: dict | None = None,
|
|
19
|
+
tolerations: list | None = None,
|
|
20
|
+
envs: list | None = None,
|
|
21
|
+
secrets: list | None = None,
|
|
22
|
+
profile: str | None = None,
|
|
23
|
+
**kwargs,
|
|
24
|
+
) -> None:
|
|
25
|
+
self.task = task
|
|
26
|
+
self.local_execution = local_execution
|
|
27
|
+
self.function = function
|
|
28
|
+
self.node_selector = node_selector
|
|
29
|
+
self.volumes = volumes
|
|
30
|
+
self.resources = resources
|
|
31
|
+
self.affinity = affinity
|
|
32
|
+
self.tolerations = tolerations
|
|
33
|
+
self.envs = envs
|
|
34
|
+
self.secrets = secrets
|
|
35
|
+
self.profile = profile
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class RunValidator(SpecValidator, K8s):
|
|
39
|
+
"""
|
|
40
|
+
RunValidator validator.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
function: str = None
|
|
44
|
+
"""The function associated with the run."""
|
|
45
|
+
|
|
46
|
+
task: str = None
|
|
47
|
+
"""The task string associated with the run."""
|
|
48
|
+
|
|
49
|
+
local_execution: bool = False
|
|
50
|
+
"""Flag to indicate if the run will be executed locally."""
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing
|
|
4
|
+
|
|
5
|
+
from digitalhub.entities._base.crud import (
|
|
6
|
+
delete_entity,
|
|
7
|
+
get_unversioned_entity,
|
|
8
|
+
import_context_entity,
|
|
9
|
+
list_context_entities,
|
|
10
|
+
new_context_entity,
|
|
11
|
+
)
|
|
12
|
+
from digitalhub.entities.utils.entity_types import EntityTypes
|
|
13
|
+
from digitalhub.utils.exceptions import EntityError
|
|
14
|
+
|
|
15
|
+
if typing.TYPE_CHECKING:
|
|
16
|
+
from digitalhub.entities.run._base.entity import Run
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
ENTITY_TYPE = EntityTypes.RUN.value
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def new_run(
|
|
23
|
+
project: str,
|
|
24
|
+
kind: str,
|
|
25
|
+
uuid: str | None = None,
|
|
26
|
+
labels: list[str] | None = None,
|
|
27
|
+
task: str | None = None,
|
|
28
|
+
local_execution: bool = False,
|
|
29
|
+
**kwargs,
|
|
30
|
+
) -> Run:
|
|
31
|
+
"""
|
|
32
|
+
Create a new object.
|
|
33
|
+
|
|
34
|
+
Parameters
|
|
35
|
+
----------
|
|
36
|
+
project : str
|
|
37
|
+
Project name.
|
|
38
|
+
kind : str
|
|
39
|
+
Kind the object.
|
|
40
|
+
uuid : str
|
|
41
|
+
ID of the object.
|
|
42
|
+
labels : list[str]
|
|
43
|
+
List of labels.
|
|
44
|
+
task : str
|
|
45
|
+
Name of the task associated with the run.
|
|
46
|
+
local_execution : bool
|
|
47
|
+
Flag to determine if object has local execution.
|
|
48
|
+
**kwargs : dict
|
|
49
|
+
Spec keyword arguments.
|
|
50
|
+
|
|
51
|
+
Returns
|
|
52
|
+
-------
|
|
53
|
+
Run
|
|
54
|
+
Object instance.
|
|
55
|
+
|
|
56
|
+
Examples
|
|
57
|
+
--------
|
|
58
|
+
>>> obj = new_run(project="my-project",
|
|
59
|
+
>>> kind="python+run",
|
|
60
|
+
>>> task="task-string")
|
|
61
|
+
"""
|
|
62
|
+
return new_context_entity(
|
|
63
|
+
project=project,
|
|
64
|
+
kind=kind,
|
|
65
|
+
uuid=uuid,
|
|
66
|
+
labels=labels,
|
|
67
|
+
task=task,
|
|
68
|
+
local_execution=local_execution,
|
|
69
|
+
**kwargs,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def get_run(
|
|
74
|
+
identifier: str,
|
|
75
|
+
project: str | None = None,
|
|
76
|
+
**kwargs,
|
|
77
|
+
) -> Run:
|
|
78
|
+
"""
|
|
79
|
+
Get object from backend.
|
|
80
|
+
|
|
81
|
+
Parameters
|
|
82
|
+
----------
|
|
83
|
+
identifier : str
|
|
84
|
+
Entity key (store://...) or entity ID.
|
|
85
|
+
project : str
|
|
86
|
+
Project name.
|
|
87
|
+
**kwargs : dict
|
|
88
|
+
Parameters to pass to the API call.
|
|
89
|
+
|
|
90
|
+
Returns
|
|
91
|
+
-------
|
|
92
|
+
Run
|
|
93
|
+
Object instance.
|
|
94
|
+
|
|
95
|
+
Examples
|
|
96
|
+
--------
|
|
97
|
+
Using entity key:
|
|
98
|
+
>>> obj = get_run("store://my-run-key")
|
|
99
|
+
|
|
100
|
+
Using entity ID:
|
|
101
|
+
>>> obj = get_run("my-run-id"
|
|
102
|
+
>>> project="my-project")
|
|
103
|
+
"""
|
|
104
|
+
return get_unversioned_entity(
|
|
105
|
+
identifier,
|
|
106
|
+
entity_type=ENTITY_TYPE,
|
|
107
|
+
project=project,
|
|
108
|
+
**kwargs,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def list_runs(project: str, **kwargs) -> list[Run]:
|
|
113
|
+
"""
|
|
114
|
+
List all latest version objects from backend.
|
|
115
|
+
|
|
116
|
+
Parameters
|
|
117
|
+
----------
|
|
118
|
+
project : str
|
|
119
|
+
Project name.
|
|
120
|
+
**kwargs : dict
|
|
121
|
+
Parameters to pass to the API call.
|
|
122
|
+
|
|
123
|
+
Returns
|
|
124
|
+
-------
|
|
125
|
+
list[Run]
|
|
126
|
+
List of object instances.
|
|
127
|
+
|
|
128
|
+
Examples
|
|
129
|
+
--------
|
|
130
|
+
>>> objs = list_runs(project="my-project")
|
|
131
|
+
"""
|
|
132
|
+
# TODO more examples: search by function, latest for task and function
|
|
133
|
+
return list_context_entities(
|
|
134
|
+
project=project,
|
|
135
|
+
entity_type=ENTITY_TYPE,
|
|
136
|
+
**kwargs,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def import_run(file: str) -> Run:
|
|
141
|
+
"""
|
|
142
|
+
Get object from file.
|
|
143
|
+
|
|
144
|
+
Parameters
|
|
145
|
+
----------
|
|
146
|
+
file : str
|
|
147
|
+
Path to YAML file.
|
|
148
|
+
|
|
149
|
+
Returns
|
|
150
|
+
-------
|
|
151
|
+
Run
|
|
152
|
+
Object instance.
|
|
153
|
+
|
|
154
|
+
Example
|
|
155
|
+
-------
|
|
156
|
+
>>> obj = import_run("my-run.yaml")
|
|
157
|
+
"""
|
|
158
|
+
return import_context_entity(file)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def update_run(entity: Run) -> Run:
|
|
162
|
+
"""
|
|
163
|
+
Update object. Note that object spec are immutable.
|
|
164
|
+
|
|
165
|
+
Parameters
|
|
166
|
+
----------
|
|
167
|
+
entity : Run
|
|
168
|
+
Object to update.
|
|
169
|
+
|
|
170
|
+
Returns
|
|
171
|
+
-------
|
|
172
|
+
Run
|
|
173
|
+
Entity updated.
|
|
174
|
+
|
|
175
|
+
Examples
|
|
176
|
+
--------
|
|
177
|
+
>>> obj = update_run(obj)
|
|
178
|
+
"""
|
|
179
|
+
return entity.save(update=True)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def delete_run(
|
|
183
|
+
identifier: str,
|
|
184
|
+
project: str | None = None,
|
|
185
|
+
**kwargs,
|
|
186
|
+
) -> dict:
|
|
187
|
+
"""
|
|
188
|
+
Delete object from backend.
|
|
189
|
+
|
|
190
|
+
Parameters
|
|
191
|
+
----------
|
|
192
|
+
identifier : str
|
|
193
|
+
Entity key (store://...) or entity ID.
|
|
194
|
+
project : str
|
|
195
|
+
Project name.
|
|
196
|
+
**kwargs : dict
|
|
197
|
+
Parameters to pass to the API call.
|
|
198
|
+
|
|
199
|
+
Returns
|
|
200
|
+
-------
|
|
201
|
+
dict
|
|
202
|
+
Response from backend.
|
|
203
|
+
|
|
204
|
+
Examples
|
|
205
|
+
--------
|
|
206
|
+
>>> obj = delete_run("store://my-run-key")
|
|
207
|
+
>>> obj = delete_run("my-run-id", project="my-project")
|
|
208
|
+
"""
|
|
209
|
+
if not identifier.startswith("store://") and project is None:
|
|
210
|
+
raise EntityError("Specify entity key or entity ID combined with project")
|
|
211
|
+
return delete_entity(
|
|
212
|
+
identifier=identifier,
|
|
213
|
+
entity_type=ENTITY_TYPE,
|
|
214
|
+
project=project,
|
|
215
|
+
entity_id=identifier,
|
|
216
|
+
**kwargs,
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
# TODO read logs
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from digitalhub.entities._base.versioned.builder import VersionedBuilder
|
|
4
|
+
from digitalhub.entities.secret._base.entity import Secret
|
|
5
|
+
from digitalhub.entities.secret._base.spec import SecretSpec, SecretValidator
|
|
6
|
+
from digitalhub.entities.secret._base.status import SecretStatus
|
|
7
|
+
from digitalhub.entities.utils.entity_types import EntityTypes
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SecretSecretBuilder(VersionedBuilder):
|
|
11
|
+
"""
|
|
12
|
+
SecretSecretBuilder builder.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
ENTITY_TYPE = EntityTypes.SECRET.value
|
|
16
|
+
ENTITY_CLASS = Secret
|
|
17
|
+
ENTITY_SPEC_CLASS = SecretSpec
|
|
18
|
+
ENTITY_SPEC_VALIDATOR = SecretValidator
|
|
19
|
+
ENTITY_STATUS_CLASS = SecretStatus
|
|
20
|
+
ENTITY_KIND = "secret"
|
|
21
|
+
|
|
22
|
+
def build(
|
|
23
|
+
self,
|
|
24
|
+
kind: str,
|
|
25
|
+
project: str,
|
|
26
|
+
name: str,
|
|
27
|
+
uuid: str | None = None,
|
|
28
|
+
description: str | None = None,
|
|
29
|
+
labels: list[str] | None = None,
|
|
30
|
+
**kwargs,
|
|
31
|
+
) -> Secret:
|
|
32
|
+
"""
|
|
33
|
+
Create a new object.
|
|
34
|
+
|
|
35
|
+
Parameters
|
|
36
|
+
----------
|
|
37
|
+
project : str
|
|
38
|
+
Project name.
|
|
39
|
+
name : str
|
|
40
|
+
Object name.
|
|
41
|
+
kind : str
|
|
42
|
+
Kind the object.
|
|
43
|
+
uuid : str
|
|
44
|
+
ID of the object.
|
|
45
|
+
description : str
|
|
46
|
+
Description of the object (human readable).
|
|
47
|
+
labels : list[str]
|
|
48
|
+
List of labels.
|
|
49
|
+
**kwargs : dict
|
|
50
|
+
Spec keyword arguments.
|
|
51
|
+
|
|
52
|
+
Returns
|
|
53
|
+
-------
|
|
54
|
+
Secret
|
|
55
|
+
Object instance.
|
|
56
|
+
"""
|
|
57
|
+
name = self.build_name(name)
|
|
58
|
+
uuid = self.build_uuid(uuid)
|
|
59
|
+
metadata = self.build_metadata(
|
|
60
|
+
project=project,
|
|
61
|
+
name=name,
|
|
62
|
+
description=description,
|
|
63
|
+
labels=labels,
|
|
64
|
+
)
|
|
65
|
+
path = f"secret://{name}"
|
|
66
|
+
provider = "kubernetes"
|
|
67
|
+
spec = self.build_spec(
|
|
68
|
+
path=path,
|
|
69
|
+
provider=provider,
|
|
70
|
+
**kwargs,
|
|
71
|
+
)
|
|
72
|
+
status = self.build_status()
|
|
73
|
+
return self.build_entity(
|
|
74
|
+
project=project,
|
|
75
|
+
name=name,
|
|
76
|
+
uuid=uuid,
|
|
77
|
+
kind=kind,
|
|
78
|
+
metadata=metadata,
|
|
79
|
+
spec=spec,
|
|
80
|
+
status=status,
|
|
81
|
+
)
|