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.

Files changed (134) hide show
  1. digitalhub/__init__.py +19 -2
  2. digitalhub/client/_base/api_builder.py +16 -0
  3. digitalhub/client/_base/client.py +67 -0
  4. digitalhub/client/_base/key_builder.py +52 -0
  5. digitalhub/client/api.py +2 -38
  6. digitalhub/client/dhcore/api_builder.py +100 -0
  7. digitalhub/client/dhcore/client.py +81 -25
  8. digitalhub/client/dhcore/enums.py +27 -0
  9. digitalhub/client/dhcore/env.py +2 -2
  10. digitalhub/client/dhcore/key_builder.py +58 -0
  11. digitalhub/client/dhcore/utils.py +17 -17
  12. digitalhub/client/local/api_builder.py +100 -0
  13. digitalhub/client/local/client.py +22 -0
  14. digitalhub/client/local/key_builder.py +58 -0
  15. digitalhub/context/api.py +3 -38
  16. digitalhub/context/builder.py +10 -23
  17. digitalhub/context/context.py +20 -92
  18. digitalhub/entities/_base/context/entity.py +30 -22
  19. digitalhub/entities/_base/entity/_constructors/metadata.py +12 -1
  20. digitalhub/entities/_base/entity/_constructors/name.py +1 -1
  21. digitalhub/entities/_base/entity/_constructors/spec.py +1 -1
  22. digitalhub/entities/_base/entity/_constructors/status.py +3 -2
  23. digitalhub/entities/_base/entity/builder.py +6 -1
  24. digitalhub/entities/_base/entity/entity.py +32 -10
  25. digitalhub/entities/_base/entity/metadata.py +22 -0
  26. digitalhub/entities/_base/entity/spec.py +7 -2
  27. digitalhub/entities/_base/executable/entity.py +8 -8
  28. digitalhub/entities/_base/material/entity.py +49 -17
  29. digitalhub/entities/_base/material/status.py +0 -31
  30. digitalhub/entities/_base/material/utils.py +106 -0
  31. digitalhub/entities/_base/project/entity.py +341 -0
  32. digitalhub/entities/_base/unversioned/entity.py +3 -24
  33. digitalhub/entities/_base/versioned/entity.py +2 -26
  34. digitalhub/entities/_commons/enums.py +103 -0
  35. digitalhub/entities/_commons/utils.py +83 -0
  36. digitalhub/entities/_operations/processor.py +1873 -0
  37. digitalhub/entities/artifact/_base/builder.py +1 -1
  38. digitalhub/entities/artifact/_base/entity.py +1 -1
  39. digitalhub/entities/artifact/artifact/builder.py +2 -1
  40. digitalhub/entities/artifact/crud.py +46 -29
  41. digitalhub/entities/artifact/utils.py +62 -0
  42. digitalhub/entities/dataitem/_base/builder.py +1 -1
  43. digitalhub/entities/dataitem/_base/entity.py +6 -6
  44. digitalhub/entities/dataitem/crud.py +50 -66
  45. digitalhub/entities/dataitem/dataitem/builder.py +2 -1
  46. digitalhub/entities/dataitem/iceberg/builder.py +2 -1
  47. digitalhub/entities/dataitem/table/builder.py +2 -1
  48. digitalhub/entities/dataitem/table/entity.py +5 -10
  49. digitalhub/entities/dataitem/table/models.py +4 -5
  50. digitalhub/entities/dataitem/utils.py +137 -0
  51. digitalhub/entities/function/_base/builder.py +1 -1
  52. digitalhub/entities/function/_base/entity.py +6 -2
  53. digitalhub/entities/function/crud.py +36 -17
  54. digitalhub/entities/model/_base/builder.py +1 -1
  55. digitalhub/entities/model/_base/entity.py +1 -1
  56. digitalhub/entities/model/crud.py +46 -29
  57. digitalhub/entities/model/huggingface/builder.py +2 -1
  58. digitalhub/entities/model/huggingface/spec.py +4 -2
  59. digitalhub/entities/model/mlflow/builder.py +2 -1
  60. digitalhub/entities/model/mlflow/models.py +17 -9
  61. digitalhub/entities/model/mlflow/spec.py +6 -1
  62. digitalhub/entities/model/mlflow/utils.py +4 -2
  63. digitalhub/entities/model/model/builder.py +2 -1
  64. digitalhub/entities/model/sklearn/builder.py +2 -1
  65. digitalhub/entities/model/utils.py +62 -0
  66. digitalhub/entities/project/_base/builder.py +2 -2
  67. digitalhub/entities/project/_base/entity.py +82 -272
  68. digitalhub/entities/project/crud.py +110 -91
  69. digitalhub/entities/project/utils.py +35 -0
  70. digitalhub/entities/run/_base/builder.py +3 -1
  71. digitalhub/entities/run/_base/entity.py +52 -54
  72. digitalhub/entities/run/_base/spec.py +15 -7
  73. digitalhub/entities/run/crud.py +35 -17
  74. digitalhub/entities/secret/_base/builder.py +2 -2
  75. digitalhub/entities/secret/_base/entity.py +4 -10
  76. digitalhub/entities/secret/crud.py +36 -21
  77. digitalhub/entities/task/_base/builder.py +14 -14
  78. digitalhub/entities/task/_base/entity.py +21 -14
  79. digitalhub/entities/task/_base/models.py +35 -6
  80. digitalhub/entities/task/_base/spec.py +50 -13
  81. digitalhub/entities/task/_base/utils.py +18 -0
  82. digitalhub/entities/task/crud.py +35 -15
  83. digitalhub/entities/workflow/_base/builder.py +1 -1
  84. digitalhub/entities/workflow/_base/entity.py +22 -6
  85. digitalhub/entities/workflow/crud.py +36 -17
  86. digitalhub/factory/utils.py +1 -1
  87. digitalhub/readers/_base/reader.py +2 -2
  88. digitalhub/readers/_commons/enums.py +13 -0
  89. digitalhub/readers/api.py +3 -2
  90. digitalhub/readers/factory.py +12 -6
  91. digitalhub/readers/pandas/reader.py +20 -8
  92. digitalhub/runtimes/_base.py +0 -7
  93. digitalhub/runtimes/enums.py +12 -0
  94. digitalhub/stores/_base/store.py +59 -11
  95. digitalhub/stores/builder.py +5 -5
  96. digitalhub/stores/local/store.py +43 -4
  97. digitalhub/stores/remote/store.py +31 -5
  98. digitalhub/stores/s3/store.py +129 -48
  99. digitalhub/stores/sql/store.py +122 -47
  100. digitalhub/utils/exceptions.py +6 -0
  101. digitalhub/utils/file_utils.py +60 -2
  102. digitalhub/utils/generic_utils.py +45 -4
  103. digitalhub/utils/io_utils.py +18 -0
  104. digitalhub/utils/s3_utils.py +17 -0
  105. digitalhub/utils/uri_utils.py +153 -15
  106. {digitalhub-0.8.1.dist-info → digitalhub-0.9.0.dist-info}/LICENSE.txt +1 -1
  107. {digitalhub-0.8.1.dist-info → digitalhub-0.9.0.dist-info}/METADATA +3 -3
  108. {digitalhub-0.8.1.dist-info → digitalhub-0.9.0.dist-info}/RECORD +116 -114
  109. test/local/instances/test_validate.py +55 -0
  110. test/testkfp.py +4 -1
  111. digitalhub/datastores/_base/datastore.py +0 -85
  112. digitalhub/datastores/api.py +0 -37
  113. digitalhub/datastores/builder.py +0 -110
  114. digitalhub/datastores/local/datastore.py +0 -50
  115. digitalhub/datastores/remote/__init__.py +0 -0
  116. digitalhub/datastores/remote/datastore.py +0 -31
  117. digitalhub/datastores/s3/__init__.py +0 -0
  118. digitalhub/datastores/s3/datastore.py +0 -46
  119. digitalhub/datastores/sql/__init__.py +0 -0
  120. digitalhub/datastores/sql/datastore.py +0 -68
  121. digitalhub/entities/_base/api_utils.py +0 -620
  122. digitalhub/entities/_base/crud.py +0 -468
  123. digitalhub/entities/function/_base/models.py +0 -118
  124. digitalhub/entities/utils/__init__.py +0 -0
  125. digitalhub/entities/utils/api.py +0 -346
  126. digitalhub/entities/utils/entity_types.py +0 -19
  127. digitalhub/entities/utils/state.py +0 -31
  128. digitalhub/entities/utils/utils.py +0 -202
  129. /digitalhub/{context → entities/_base/project}/__init__.py +0 -0
  130. /digitalhub/{datastores → entities/_commons}/__init__.py +0 -0
  131. /digitalhub/{datastores/_base → entities/_operations}/__init__.py +0 -0
  132. /digitalhub/{datastores/local → readers/_commons}/__init__.py +0 -0
  133. {digitalhub-0.8.1.dist-info → digitalhub-0.9.0.dist-info}/WHEEL +0 -0
  134. {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.utils.io_utils import write_yaml
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.key = f"store://{project}/{self.ENTITY_TYPE}/{kind}/{uuid}"
28
- self._obj_attr.extend(["id"])
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.utils.io_utils import write_yaml
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 = f"store://{project}/{self.ENTITY_TYPE}/{kind}/{name}:{uuid}"
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