digitalhub 0.8.1__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 +81 -25
- digitalhub/client/dhcore/enums.py +27 -0
- digitalhub/client/dhcore/env.py +2 -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/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 -91
- 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 +129 -48
- 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.1.dist-info → digitalhub-0.9.0.dist-info}/LICENSE.txt +1 -1
- {digitalhub-0.8.1.dist-info → digitalhub-0.9.0.dist-info}/METADATA +3 -3
- {digitalhub-0.8.1.dist-info → digitalhub-0.9.0.dist-info}/RECORD +116 -114
- 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.1.dist-info → digitalhub-0.9.0.dist-info}/WHEEL +0 -0
- {digitalhub-0.8.1.dist-info → digitalhub-0.9.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from digitalhub.client.api import get_client
|
|
7
|
+
from digitalhub.context.api import build_context
|
|
8
|
+
from digitalhub.entities._base.entity.entity import Entity
|
|
9
|
+
from digitalhub.entities._commons.enums import EntityTypes
|
|
10
|
+
from digitalhub.entities._operations.processor import processor
|
|
11
|
+
from digitalhub.factory.api import build_entity_from_dict
|
|
12
|
+
from digitalhub.utils.exceptions import BackendError, EntityAlreadyExistsError, EntityError
|
|
13
|
+
from digitalhub.utils.generic_utils import get_timestamp
|
|
14
|
+
from digitalhub.utils.io_utils import write_yaml
|
|
15
|
+
from digitalhub.utils.uri_utils import has_local_scheme
|
|
16
|
+
|
|
17
|
+
if typing.TYPE_CHECKING:
|
|
18
|
+
from digitalhub.entities._base.context.entity import ContextEntity
|
|
19
|
+
from digitalhub.entities._base.entity.metadata import Metadata
|
|
20
|
+
from digitalhub.entities._base.entity.spec import Spec
|
|
21
|
+
from digitalhub.entities._base.entity.status import Status
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ProjectEntity(Entity):
|
|
25
|
+
"""
|
|
26
|
+
Base entity for Project entity.
|
|
27
|
+
Used to abstract a bit by handling I/O CRUD.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
name: str,
|
|
33
|
+
kind: str,
|
|
34
|
+
metadata: Metadata,
|
|
35
|
+
spec: Spec,
|
|
36
|
+
status: Status,
|
|
37
|
+
user: str | None = None,
|
|
38
|
+
local: bool = False,
|
|
39
|
+
) -> None:
|
|
40
|
+
super().__init__(kind, metadata, spec, status, user)
|
|
41
|
+
self.id = name
|
|
42
|
+
self.name = name
|
|
43
|
+
self.key = processor.build_project_key(self.name, local=local)
|
|
44
|
+
|
|
45
|
+
self._obj_attr.extend(["id", "name"])
|
|
46
|
+
|
|
47
|
+
# Set client
|
|
48
|
+
self._client = get_client(local)
|
|
49
|
+
|
|
50
|
+
# Set context
|
|
51
|
+
build_context(self)
|
|
52
|
+
|
|
53
|
+
##############################
|
|
54
|
+
# Save / Refresh / Export
|
|
55
|
+
##############################
|
|
56
|
+
|
|
57
|
+
def save(self, update: bool = False) -> ProjectEntity:
|
|
58
|
+
"""
|
|
59
|
+
Save entity into backend.
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
update : bool
|
|
64
|
+
If True, the object will be updated.
|
|
65
|
+
|
|
66
|
+
Returns
|
|
67
|
+
-------
|
|
68
|
+
Project
|
|
69
|
+
Entity saved.
|
|
70
|
+
"""
|
|
71
|
+
if update:
|
|
72
|
+
if self._client.is_local():
|
|
73
|
+
self.metadata.updated = get_timestamp()
|
|
74
|
+
new_obj = processor.update_project_entity(
|
|
75
|
+
entity_type=self.ENTITY_TYPE,
|
|
76
|
+
entity_name=self.name,
|
|
77
|
+
entity_dict=self.to_dict(),
|
|
78
|
+
local=self._client.is_local(),
|
|
79
|
+
)
|
|
80
|
+
else:
|
|
81
|
+
new_obj = processor.create_project_entity(_entity=self)
|
|
82
|
+
self._update_attributes(new_obj)
|
|
83
|
+
return self
|
|
84
|
+
|
|
85
|
+
def refresh(self) -> ProjectEntity:
|
|
86
|
+
"""
|
|
87
|
+
Refresh object from backend.
|
|
88
|
+
|
|
89
|
+
Returns
|
|
90
|
+
-------
|
|
91
|
+
Project
|
|
92
|
+
Project object.
|
|
93
|
+
"""
|
|
94
|
+
new_obj = processor.read_project_entity(
|
|
95
|
+
entity_type=self.ENTITY_TYPE,
|
|
96
|
+
entity_name=self.name,
|
|
97
|
+
local=self._client.is_local(),
|
|
98
|
+
)
|
|
99
|
+
self._update_attributes(new_obj)
|
|
100
|
+
return self
|
|
101
|
+
|
|
102
|
+
def search_entity(
|
|
103
|
+
self,
|
|
104
|
+
query: str | None = None,
|
|
105
|
+
entity_types: list[str] | None = None,
|
|
106
|
+
name: str | None = None,
|
|
107
|
+
kind: str | None = None,
|
|
108
|
+
created: str | None = None,
|
|
109
|
+
updated: str | None = None,
|
|
110
|
+
description: str | None = None,
|
|
111
|
+
labels: list[str] | None = None,
|
|
112
|
+
**kwargs,
|
|
113
|
+
) -> list[ContextEntity]:
|
|
114
|
+
"""
|
|
115
|
+
Search objects from backend.
|
|
116
|
+
|
|
117
|
+
Parameters
|
|
118
|
+
----------
|
|
119
|
+
query : str
|
|
120
|
+
Search query.
|
|
121
|
+
entity_types : list[str]
|
|
122
|
+
Entity types.
|
|
123
|
+
name : str
|
|
124
|
+
Entity name.
|
|
125
|
+
kind : str
|
|
126
|
+
Entity kind.
|
|
127
|
+
created : str
|
|
128
|
+
Entity creation date.
|
|
129
|
+
updated : str
|
|
130
|
+
Entity update date.
|
|
131
|
+
description : str
|
|
132
|
+
Entity description.
|
|
133
|
+
labels : list[str]
|
|
134
|
+
Entity labels.
|
|
135
|
+
**kwargs : dict
|
|
136
|
+
Parameters to pass to the API call.
|
|
137
|
+
|
|
138
|
+
Returns
|
|
139
|
+
-------
|
|
140
|
+
list[ContextEntity]
|
|
141
|
+
List of object instances.
|
|
142
|
+
"""
|
|
143
|
+
objs = processor.search_entity(
|
|
144
|
+
self.name,
|
|
145
|
+
query=query,
|
|
146
|
+
entity_types=entity_types,
|
|
147
|
+
name=name,
|
|
148
|
+
kind=kind,
|
|
149
|
+
created=created,
|
|
150
|
+
updated=updated,
|
|
151
|
+
description=description,
|
|
152
|
+
labels=labels,
|
|
153
|
+
**kwargs,
|
|
154
|
+
)
|
|
155
|
+
self.refresh()
|
|
156
|
+
return objs
|
|
157
|
+
|
|
158
|
+
def export(self) -> str:
|
|
159
|
+
"""
|
|
160
|
+
Export object as a YAML file in the context folder.
|
|
161
|
+
If the objects are not embedded, the objects are exported as a YAML file.
|
|
162
|
+
|
|
163
|
+
Returns
|
|
164
|
+
-------
|
|
165
|
+
str
|
|
166
|
+
Exported filepath.
|
|
167
|
+
"""
|
|
168
|
+
obj = self._refresh_to_dict()
|
|
169
|
+
pth = Path(self.spec.context) / f"{self.ENTITY_TYPE}s-{self.name}.yaml"
|
|
170
|
+
obj = self._export_not_embedded(obj)
|
|
171
|
+
write_yaml(pth, obj)
|
|
172
|
+
return str(pth)
|
|
173
|
+
|
|
174
|
+
def _refresh_to_dict(self) -> dict:
|
|
175
|
+
"""
|
|
176
|
+
Try to refresh object to collect entities related to project.
|
|
177
|
+
|
|
178
|
+
Returns
|
|
179
|
+
-------
|
|
180
|
+
dict
|
|
181
|
+
Entity object in dictionary format.
|
|
182
|
+
"""
|
|
183
|
+
try:
|
|
184
|
+
return self.refresh().to_dict()
|
|
185
|
+
except BackendError:
|
|
186
|
+
return self.to_dict()
|
|
187
|
+
|
|
188
|
+
def _export_not_embedded(self, obj: dict) -> dict:
|
|
189
|
+
"""
|
|
190
|
+
Export project objects if not embedded.
|
|
191
|
+
|
|
192
|
+
Parameters
|
|
193
|
+
----------
|
|
194
|
+
obj : dict
|
|
195
|
+
Project object in dictionary format.
|
|
196
|
+
|
|
197
|
+
Returns
|
|
198
|
+
-------
|
|
199
|
+
dict
|
|
200
|
+
Updatated project object in dictionary format with referenced entities.
|
|
201
|
+
"""
|
|
202
|
+
# Cycle over entity types
|
|
203
|
+
for entity_type in self._get_entity_types():
|
|
204
|
+
# Entity types are stored as a list of entities
|
|
205
|
+
for idx, entity in enumerate(obj.get("spec", {}).get(entity_type, [])):
|
|
206
|
+
# Export entity if not embedded is in metadata, else do nothing
|
|
207
|
+
if not self._is_embedded(entity):
|
|
208
|
+
# Get entity object from backend
|
|
209
|
+
ent = processor.read_context_entity(entity["key"])
|
|
210
|
+
|
|
211
|
+
# Export and store ref in object metadata inside project
|
|
212
|
+
pth = ent.export()
|
|
213
|
+
obj["spec"][entity_type][idx]["metadata"]["ref"] = pth
|
|
214
|
+
|
|
215
|
+
# Return updated object
|
|
216
|
+
return obj
|
|
217
|
+
|
|
218
|
+
def _import_entities(self, obj: dict) -> None:
|
|
219
|
+
"""
|
|
220
|
+
Import project entities.
|
|
221
|
+
|
|
222
|
+
Parameters
|
|
223
|
+
----------
|
|
224
|
+
obj : dict
|
|
225
|
+
Project object in dictionary format.
|
|
226
|
+
|
|
227
|
+
Returns
|
|
228
|
+
-------
|
|
229
|
+
None
|
|
230
|
+
"""
|
|
231
|
+
entity_types = self._get_entity_types()
|
|
232
|
+
|
|
233
|
+
# Cycle over entity types
|
|
234
|
+
for entity_type in entity_types:
|
|
235
|
+
# Entity types are stored as a list of entities
|
|
236
|
+
for entity in obj.get("spec", {}).get(entity_type, []):
|
|
237
|
+
embedded = self._is_embedded(entity)
|
|
238
|
+
ref = entity["metadata"].get("ref")
|
|
239
|
+
|
|
240
|
+
# Import entity if not embedded and there is a ref
|
|
241
|
+
if not embedded and ref is not None:
|
|
242
|
+
# Import entity from local ref
|
|
243
|
+
if has_local_scheme(ref):
|
|
244
|
+
try:
|
|
245
|
+
# Artifacts, Dataitems and Models
|
|
246
|
+
if entity_type in entity_types[:3]:
|
|
247
|
+
processor.import_context_entity(ref)
|
|
248
|
+
|
|
249
|
+
# Functions and Workflows
|
|
250
|
+
elif entity_type in entity_types[3:]:
|
|
251
|
+
processor.import_executable_entity(ref)
|
|
252
|
+
|
|
253
|
+
except FileNotFoundError:
|
|
254
|
+
msg = f"File not found: {ref}."
|
|
255
|
+
raise EntityError(msg)
|
|
256
|
+
|
|
257
|
+
# If entity is embedded, create it and try to save
|
|
258
|
+
elif embedded:
|
|
259
|
+
# It's possible that embedded field in metadata is not shown
|
|
260
|
+
if entity["metadata"].get("embedded") is None:
|
|
261
|
+
entity["metadata"]["embedded"] = True
|
|
262
|
+
|
|
263
|
+
try:
|
|
264
|
+
build_entity_from_dict(entity).save()
|
|
265
|
+
except EntityAlreadyExistsError:
|
|
266
|
+
pass
|
|
267
|
+
|
|
268
|
+
def _load_entities(self, obj: dict) -> None:
|
|
269
|
+
"""
|
|
270
|
+
Load project entities.
|
|
271
|
+
|
|
272
|
+
Parameters
|
|
273
|
+
----------
|
|
274
|
+
obj : dict
|
|
275
|
+
Project object in dictionary format.
|
|
276
|
+
|
|
277
|
+
Returns
|
|
278
|
+
-------
|
|
279
|
+
None
|
|
280
|
+
"""
|
|
281
|
+
entity_types = self._get_entity_types()
|
|
282
|
+
|
|
283
|
+
# Cycle over entity types
|
|
284
|
+
for entity_type in entity_types:
|
|
285
|
+
# Entity types are stored as a list of entities
|
|
286
|
+
for entity in obj.get("spec", {}).get(entity_type, []):
|
|
287
|
+
embedded = self._is_embedded(entity)
|
|
288
|
+
ref = entity["metadata"].get("ref")
|
|
289
|
+
|
|
290
|
+
# Load entity if not embedded and there is a ref
|
|
291
|
+
if not embedded and ref is not None:
|
|
292
|
+
# Load entity from local ref
|
|
293
|
+
if has_local_scheme(ref):
|
|
294
|
+
try:
|
|
295
|
+
# Artifacts, Dataitems and Models
|
|
296
|
+
if entity_type in entity_types[:3]:
|
|
297
|
+
processor.load_context_entity(ref)
|
|
298
|
+
|
|
299
|
+
# Functions and Workflows
|
|
300
|
+
elif entity_type in entity_types[3:]:
|
|
301
|
+
processor.load_executable_entity(ref)
|
|
302
|
+
|
|
303
|
+
except FileNotFoundError:
|
|
304
|
+
msg = f"File not found: {ref}."
|
|
305
|
+
raise EntityError(msg)
|
|
306
|
+
|
|
307
|
+
def _is_embedded(self, entity: dict) -> bool:
|
|
308
|
+
"""
|
|
309
|
+
Check if entity is embedded.
|
|
310
|
+
|
|
311
|
+
Parameters
|
|
312
|
+
----------
|
|
313
|
+
entity : dict
|
|
314
|
+
Entity in dictionary format.
|
|
315
|
+
|
|
316
|
+
Returns
|
|
317
|
+
-------
|
|
318
|
+
bool
|
|
319
|
+
True if entity is embedded.
|
|
320
|
+
"""
|
|
321
|
+
metadata_embedded = entity["metadata"].get("embedded", False)
|
|
322
|
+
no_status = entity.get("status", None) is None
|
|
323
|
+
no_spec = entity.get("spec", None) is None
|
|
324
|
+
return metadata_embedded or not (no_status and no_spec)
|
|
325
|
+
|
|
326
|
+
def _get_entity_types(self) -> list[str]:
|
|
327
|
+
"""
|
|
328
|
+
Get entity types.
|
|
329
|
+
|
|
330
|
+
Returns
|
|
331
|
+
-------
|
|
332
|
+
list
|
|
333
|
+
Entity types.
|
|
334
|
+
"""
|
|
335
|
+
return [
|
|
336
|
+
f"{EntityTypes.ARTIFACT.value}s",
|
|
337
|
+
f"{EntityTypes.DATAITEM.value}s",
|
|
338
|
+
f"{EntityTypes.MODEL.value}s",
|
|
339
|
+
f"{EntityTypes.FUNCTION.value}s",
|
|
340
|
+
f"{EntityTypes.WORKFLOW.value}s",
|
|
341
|
+
]
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import typing
|
|
4
4
|
|
|
5
5
|
from digitalhub.entities._base.context.entity import ContextEntity
|
|
6
|
-
from digitalhub.
|
|
6
|
+
from digitalhub.entities._operations.processor import processor
|
|
7
7
|
|
|
8
8
|
if typing.TYPE_CHECKING:
|
|
9
9
|
from digitalhub.entities._base.entity.metadata import Metadata
|
|
@@ -24,26 +24,5 @@ class UnversionedEntity(ContextEntity):
|
|
|
24
24
|
) -> None:
|
|
25
25
|
super().__init__(project, kind, metadata, spec, status, user)
|
|
26
26
|
self.id = uuid
|
|
27
|
-
self.
|
|
28
|
-
self.
|
|
29
|
-
|
|
30
|
-
def export(self, filename: str | None = None) -> str:
|
|
31
|
-
"""
|
|
32
|
-
Export object as a YAML file.
|
|
33
|
-
|
|
34
|
-
Parameters
|
|
35
|
-
----------
|
|
36
|
-
filename : str
|
|
37
|
-
Name of the export YAML file. If not specified, the default value is used.
|
|
38
|
-
|
|
39
|
-
Returns
|
|
40
|
-
-------
|
|
41
|
-
str
|
|
42
|
-
Exported file.
|
|
43
|
-
"""
|
|
44
|
-
obj = self.to_dict()
|
|
45
|
-
if filename is None:
|
|
46
|
-
filename = f"{self.ENTITY_TYPE}-{self.id}.yml"
|
|
47
|
-
pth = self._context().root / filename
|
|
48
|
-
write_yaml(pth, obj)
|
|
49
|
-
return str(pth)
|
|
27
|
+
self.name = uuid
|
|
28
|
+
self.key = processor.build_context_entity_key(project, self.ENTITY_TYPE, kind, uuid)
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import typing
|
|
4
4
|
|
|
5
5
|
from digitalhub.entities._base.context.entity import ContextEntity
|
|
6
|
-
from digitalhub.
|
|
6
|
+
from digitalhub.entities._operations.processor import processor
|
|
7
7
|
|
|
8
8
|
if typing.TYPE_CHECKING:
|
|
9
9
|
from digitalhub.entities._base.entity.metadata import Metadata
|
|
@@ -26,28 +26,4 @@ class VersionedEntity(ContextEntity):
|
|
|
26
26
|
super().__init__(project, kind, metadata, spec, status, user)
|
|
27
27
|
self.name = name
|
|
28
28
|
self.id = uuid
|
|
29
|
-
self.key =
|
|
30
|
-
|
|
31
|
-
# Add attributes to be used in the to_dict method
|
|
32
|
-
self._obj_attr.extend(["name", "id"])
|
|
33
|
-
|
|
34
|
-
def export(self, filename: str | None = None) -> str:
|
|
35
|
-
"""
|
|
36
|
-
Export object as a YAML file.
|
|
37
|
-
|
|
38
|
-
Parameters
|
|
39
|
-
----------
|
|
40
|
-
filename : str
|
|
41
|
-
Name of the export YAML file. If not specified, the default value is used.
|
|
42
|
-
|
|
43
|
-
Returns
|
|
44
|
-
-------
|
|
45
|
-
str
|
|
46
|
-
Exported file.
|
|
47
|
-
"""
|
|
48
|
-
obj = self.to_dict()
|
|
49
|
-
if filename is None:
|
|
50
|
-
filename = f"{self.ENTITY_TYPE}-{self.name}-{self.id}.yml"
|
|
51
|
-
pth = self._context().root / filename
|
|
52
|
-
write_yaml(pth, obj)
|
|
53
|
-
return str(pth)
|
|
29
|
+
self.key = processor.build_context_entity_key(project, self.ENTITY_TYPE, kind, name, uuid)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class EntityTypes(Enum):
|
|
7
|
+
"""
|
|
8
|
+
Entity types.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
PROJECT = "project"
|
|
12
|
+
ARTIFACT = "artifact"
|
|
13
|
+
DATAITEM = "dataitem"
|
|
14
|
+
MODEL = "model"
|
|
15
|
+
SECRET = "secret"
|
|
16
|
+
FUNCTION = "function"
|
|
17
|
+
WORKFLOW = "workflow"
|
|
18
|
+
TASK = "task"
|
|
19
|
+
RUN = "run"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Relationship(Enum):
|
|
23
|
+
"""
|
|
24
|
+
Relationship enumeration.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
PRODUCEDBY = "produced_by"
|
|
28
|
+
CONSUMES = "consumes"
|
|
29
|
+
RUN_OF = "run_of"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class State(Enum):
|
|
33
|
+
"""
|
|
34
|
+
State enumeration.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
BUILT = "BUILT"
|
|
38
|
+
CANCELLED = "CANCELLED"
|
|
39
|
+
COMPLETED = "COMPLETED"
|
|
40
|
+
CREATED = "CREATED"
|
|
41
|
+
CREATING = "CREATING"
|
|
42
|
+
DELETED = "DELETED"
|
|
43
|
+
DELETING = "DELETING"
|
|
44
|
+
ERROR = "ERROR"
|
|
45
|
+
FSM_ERROR = "FSM_ERROR"
|
|
46
|
+
IDLE = "IDLE"
|
|
47
|
+
NONE = "NONE"
|
|
48
|
+
ONLINE = "ONLINE"
|
|
49
|
+
PENDING = "PENDING"
|
|
50
|
+
READY = "READY"
|
|
51
|
+
RESUME = "RESUME"
|
|
52
|
+
RUN_ERROR = "RUN_ERROR"
|
|
53
|
+
RUNNING = "RUNNING"
|
|
54
|
+
STOP = "STOP"
|
|
55
|
+
STOPPED = "STOPPED"
|
|
56
|
+
SUCCESS = "SUCCESS"
|
|
57
|
+
UNKNOWN = "UNKNOWN"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class ApiCategories(Enum):
|
|
61
|
+
"""
|
|
62
|
+
Entity categories.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
BASE = "base"
|
|
66
|
+
CONTEXT = "context"
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class BackendOperations(Enum):
|
|
70
|
+
"""
|
|
71
|
+
Backend operations.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
CREATE = "create"
|
|
75
|
+
READ = "read"
|
|
76
|
+
UPDATE = "update"
|
|
77
|
+
DELETE = "delete"
|
|
78
|
+
LIST = "list"
|
|
79
|
+
LIST_FIRST = "list_first"
|
|
80
|
+
STOP = "stop"
|
|
81
|
+
RESUME = "resume"
|
|
82
|
+
DATA = "data"
|
|
83
|
+
FILES = "files"
|
|
84
|
+
LOGS = "logs"
|
|
85
|
+
SEARCH = "search"
|
|
86
|
+
SHARE = "share"
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class EntityKinds(Enum):
|
|
90
|
+
"""
|
|
91
|
+
Entity kinds.
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
PROJECT_PROJECT = "project"
|
|
95
|
+
ARTIFACT_ARTIFACT = "artifact"
|
|
96
|
+
DATAITEM_DATAITEM = "dataitem"
|
|
97
|
+
DATAITEM_TABLE = "table"
|
|
98
|
+
DATAITEM_ICEBERG = "iceberg"
|
|
99
|
+
MODEL_MODEL = "model"
|
|
100
|
+
MODEL_MLFLOW = "mlflow"
|
|
101
|
+
MODEL_HUGGINGFACE = "huggingface"
|
|
102
|
+
MODEL_SKLEARN = "sklearn"
|
|
103
|
+
SECRET_SECRET = "secret"
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from digitalhub.entities._commons.enums import EntityTypes
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def parse_entity_key(key: str) -> tuple[str]:
|
|
7
|
+
"""
|
|
8
|
+
Parse the entity key. Returns project, entity type, kind, name and uuid.
|
|
9
|
+
|
|
10
|
+
Parameters
|
|
11
|
+
----------
|
|
12
|
+
key : str
|
|
13
|
+
The entity key.
|
|
14
|
+
|
|
15
|
+
Returns
|
|
16
|
+
-------
|
|
17
|
+
tuple[str]
|
|
18
|
+
Project, entity type, kind, name and uuid.
|
|
19
|
+
"""
|
|
20
|
+
try:
|
|
21
|
+
# Remove "store://" from the key
|
|
22
|
+
key = key.replace("store://", "")
|
|
23
|
+
|
|
24
|
+
# Split the key into parts
|
|
25
|
+
parts = key.split("/")
|
|
26
|
+
|
|
27
|
+
# The project is the first part
|
|
28
|
+
project = parts[0]
|
|
29
|
+
|
|
30
|
+
# The entity type is the second part
|
|
31
|
+
entity_type = parts[1]
|
|
32
|
+
|
|
33
|
+
# The kind is the third part
|
|
34
|
+
kind = parts[2]
|
|
35
|
+
|
|
36
|
+
# Tasks and runs have no name and uuid
|
|
37
|
+
if entity_type in (EntityTypes.TASK.value, EntityTypes.RUN.value):
|
|
38
|
+
name = None
|
|
39
|
+
uuid = parts[3]
|
|
40
|
+
|
|
41
|
+
# The name and uuid are separated by a colon in the last part
|
|
42
|
+
else:
|
|
43
|
+
name, uuid = parts[3].split(":")
|
|
44
|
+
|
|
45
|
+
return project, entity_type, kind, name, uuid
|
|
46
|
+
except Exception as e:
|
|
47
|
+
raise ValueError("Invalid key format.") from e
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def get_entity_type_from_key(key: str) -> str:
|
|
51
|
+
"""
|
|
52
|
+
Get entity type from key.
|
|
53
|
+
|
|
54
|
+
Parameters
|
|
55
|
+
----------
|
|
56
|
+
key : str
|
|
57
|
+
The key of the entity.
|
|
58
|
+
|
|
59
|
+
Returns
|
|
60
|
+
-------
|
|
61
|
+
str
|
|
62
|
+
The entity type.
|
|
63
|
+
"""
|
|
64
|
+
_, entity_type, _, _, _ = parse_entity_key(key)
|
|
65
|
+
return entity_type
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def get_project_from_key(key: str) -> str:
|
|
69
|
+
"""
|
|
70
|
+
Get project from key.
|
|
71
|
+
|
|
72
|
+
Parameters
|
|
73
|
+
----------
|
|
74
|
+
key : str
|
|
75
|
+
The key of the entity.
|
|
76
|
+
|
|
77
|
+
Returns
|
|
78
|
+
-------
|
|
79
|
+
str
|
|
80
|
+
The project.
|
|
81
|
+
"""
|
|
82
|
+
project, _, _, _, _ = parse_entity_key(key)
|
|
83
|
+
return project
|