digitalhub 0.13.0b3__py3-none-any.whl → 0.14.9__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.
Files changed (139) hide show
  1. digitalhub/__init__.py +3 -8
  2. digitalhub/context/api.py +43 -6
  3. digitalhub/context/builder.py +1 -5
  4. digitalhub/context/context.py +28 -13
  5. digitalhub/entities/_base/_base/entity.py +0 -15
  6. digitalhub/entities/_base/context/entity.py +1 -4
  7. digitalhub/entities/_base/entity/builder.py +5 -5
  8. digitalhub/entities/_base/entity/entity.py +0 -8
  9. digitalhub/entities/_base/executable/entity.py +195 -87
  10. digitalhub/entities/_base/material/entity.py +11 -23
  11. digitalhub/entities/_base/material/utils.py +28 -4
  12. digitalhub/entities/_base/runtime_entity/builder.py +53 -18
  13. digitalhub/entities/_base/unversioned/entity.py +1 -1
  14. digitalhub/entities/_base/versioned/entity.py +1 -1
  15. digitalhub/entities/_commons/enums.py +1 -31
  16. digitalhub/entities/_commons/metrics.py +64 -30
  17. digitalhub/entities/_commons/utils.py +119 -30
  18. digitalhub/entities/_constructors/_resources.py +151 -0
  19. digitalhub/entities/{_base/entity/_constructors → _constructors}/name.py +18 -0
  20. digitalhub/entities/_processors/base/crud.py +381 -0
  21. digitalhub/entities/_processors/base/import_export.py +118 -0
  22. digitalhub/entities/_processors/base/processor.py +299 -0
  23. digitalhub/entities/_processors/base/special_ops.py +104 -0
  24. digitalhub/entities/_processors/context/crud.py +652 -0
  25. digitalhub/entities/_processors/context/import_export.py +242 -0
  26. digitalhub/entities/_processors/context/material.py +123 -0
  27. digitalhub/entities/_processors/context/processor.py +400 -0
  28. digitalhub/entities/_processors/context/special_ops.py +476 -0
  29. digitalhub/entities/_processors/processors.py +12 -0
  30. digitalhub/entities/_processors/utils.py +38 -102
  31. digitalhub/entities/artifact/crud.py +58 -22
  32. digitalhub/entities/artifact/utils.py +28 -13
  33. digitalhub/entities/builders.py +2 -0
  34. digitalhub/entities/dataitem/crud.py +63 -20
  35. digitalhub/entities/dataitem/table/entity.py +27 -22
  36. digitalhub/entities/dataitem/utils.py +82 -32
  37. digitalhub/entities/function/_base/entity.py +3 -6
  38. digitalhub/entities/function/crud.py +55 -24
  39. digitalhub/entities/model/_base/entity.py +62 -20
  40. digitalhub/entities/model/crud.py +59 -23
  41. digitalhub/entities/model/mlflow/utils.py +29 -20
  42. digitalhub/entities/model/utils.py +28 -13
  43. digitalhub/entities/project/_base/builder.py +0 -6
  44. digitalhub/entities/project/_base/entity.py +337 -164
  45. digitalhub/entities/project/_base/spec.py +4 -4
  46. digitalhub/entities/project/crud.py +28 -71
  47. digitalhub/entities/project/utils.py +7 -3
  48. digitalhub/entities/run/_base/builder.py +0 -4
  49. digitalhub/entities/run/_base/entity.py +70 -63
  50. digitalhub/entities/run/crud.py +79 -26
  51. digitalhub/entities/secret/_base/entity.py +1 -5
  52. digitalhub/entities/secret/crud.py +31 -28
  53. digitalhub/entities/task/_base/builder.py +0 -4
  54. digitalhub/entities/task/_base/entity.py +5 -5
  55. digitalhub/entities/task/_base/models.py +13 -16
  56. digitalhub/entities/task/crud.py +61 -29
  57. digitalhub/entities/trigger/_base/entity.py +1 -5
  58. digitalhub/entities/trigger/crud.py +89 -30
  59. digitalhub/entities/workflow/_base/entity.py +3 -8
  60. digitalhub/entities/workflow/crud.py +55 -24
  61. digitalhub/factory/entity.py +283 -0
  62. digitalhub/factory/enums.py +18 -0
  63. digitalhub/factory/registry.py +197 -0
  64. digitalhub/factory/runtime.py +44 -0
  65. digitalhub/factory/utils.py +3 -54
  66. digitalhub/runtimes/_base.py +2 -2
  67. digitalhub/stores/client/{dhcore/api_builder.py → api_builder.py} +3 -3
  68. digitalhub/stores/client/builder.py +19 -31
  69. digitalhub/stores/client/client.py +322 -0
  70. digitalhub/stores/client/configurator.py +408 -0
  71. digitalhub/stores/client/enums.py +50 -0
  72. digitalhub/stores/client/{dhcore/error_parser.py → error_parser.py} +0 -4
  73. digitalhub/stores/client/header_manager.py +61 -0
  74. digitalhub/stores/client/http_handler.py +152 -0
  75. digitalhub/stores/client/{_base/key_builder.py → key_builder.py} +14 -14
  76. digitalhub/stores/client/params_builder.py +330 -0
  77. digitalhub/stores/client/response_processor.py +102 -0
  78. digitalhub/stores/client/utils.py +35 -0
  79. digitalhub/stores/{credentials → configurator}/api.py +5 -9
  80. digitalhub/stores/configurator/configurator.py +123 -0
  81. digitalhub/stores/{credentials → configurator}/enums.py +27 -10
  82. digitalhub/stores/configurator/handler.py +213 -0
  83. digitalhub/stores/{credentials → configurator}/ini_module.py +31 -22
  84. digitalhub/stores/data/_base/store.py +0 -20
  85. digitalhub/stores/data/api.py +5 -7
  86. digitalhub/stores/data/builder.py +53 -27
  87. digitalhub/stores/data/local/store.py +0 -103
  88. digitalhub/stores/data/remote/store.py +0 -4
  89. digitalhub/stores/data/s3/configurator.py +39 -77
  90. digitalhub/stores/data/s3/store.py +57 -37
  91. digitalhub/stores/data/sql/configurator.py +66 -46
  92. digitalhub/stores/data/sql/store.py +171 -104
  93. digitalhub/stores/readers/data/factory.py +0 -8
  94. digitalhub/stores/readers/data/pandas/reader.py +9 -19
  95. digitalhub/utils/file_utils.py +0 -17
  96. digitalhub/utils/generic_utils.py +1 -14
  97. digitalhub/utils/git_utils.py +0 -8
  98. digitalhub/utils/io_utils.py +0 -12
  99. digitalhub/utils/store_utils.py +44 -0
  100. {digitalhub-0.13.0b3.dist-info → digitalhub-0.14.9.dist-info}/METADATA +5 -4
  101. {digitalhub-0.13.0b3.dist-info → digitalhub-0.14.9.dist-info}/RECORD +112 -113
  102. {digitalhub-0.13.0b3.dist-info → digitalhub-0.14.9.dist-info}/WHEEL +1 -1
  103. digitalhub/entities/_commons/types.py +0 -9
  104. digitalhub/entities/_processors/base.py +0 -531
  105. digitalhub/entities/_processors/context.py +0 -1299
  106. digitalhub/entities/task/_base/utils.py +0 -22
  107. digitalhub/factory/factory.py +0 -381
  108. digitalhub/stores/client/_base/api_builder.py +0 -34
  109. digitalhub/stores/client/_base/client.py +0 -243
  110. digitalhub/stores/client/_base/params_builder.py +0 -34
  111. digitalhub/stores/client/api.py +0 -36
  112. digitalhub/stores/client/dhcore/client.py +0 -613
  113. digitalhub/stores/client/dhcore/configurator.py +0 -675
  114. digitalhub/stores/client/dhcore/enums.py +0 -34
  115. digitalhub/stores/client/dhcore/key_builder.py +0 -62
  116. digitalhub/stores/client/dhcore/models.py +0 -40
  117. digitalhub/stores/client/dhcore/params_builder.py +0 -278
  118. digitalhub/stores/client/dhcore/utils.py +0 -94
  119. digitalhub/stores/client/local/api_builder.py +0 -116
  120. digitalhub/stores/client/local/client.py +0 -573
  121. digitalhub/stores/client/local/enums.py +0 -15
  122. digitalhub/stores/client/local/key_builder.py +0 -62
  123. digitalhub/stores/client/local/params_builder.py +0 -120
  124. digitalhub/stores/credentials/__init__.py +0 -3
  125. digitalhub/stores/credentials/configurator.py +0 -210
  126. digitalhub/stores/credentials/handler.py +0 -176
  127. digitalhub/stores/credentials/store.py +0 -81
  128. digitalhub/stores/data/enums.py +0 -15
  129. digitalhub/stores/data/s3/utils.py +0 -78
  130. /digitalhub/entities/{_base/entity/_constructors → _constructors}/__init__.py +0 -0
  131. /digitalhub/entities/{_base/entity/_constructors → _constructors}/metadata.py +0 -0
  132. /digitalhub/entities/{_base/entity/_constructors → _constructors}/spec.py +0 -0
  133. /digitalhub/entities/{_base/entity/_constructors → _constructors}/status.py +0 -0
  134. /digitalhub/entities/{_base/entity/_constructors → _constructors}/uuid.py +0 -0
  135. /digitalhub/{stores/client/_base → entities/_processors/base}/__init__.py +0 -0
  136. /digitalhub/{stores/client/dhcore → entities/_processors/context}/__init__.py +0 -0
  137. /digitalhub/stores/{client/local → configurator}/__init__.py +0 -0
  138. {digitalhub-0.13.0b3.dist-info → digitalhub-0.14.9.dist-info}/licenses/AUTHORS +0 -0
  139. {digitalhub-0.13.0b3.dist-info → digitalhub-0.14.9.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,151 @@
1
+ # SPDX-FileCopyrightText: © 2025 DSLab - Fondazione Bruno Kessler
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from __future__ import annotations
6
+
7
+ ANIMALS = [
8
+ "ant",
9
+ "bear",
10
+ "bee",
11
+ "bison",
12
+ "cat",
13
+ "cheetah",
14
+ "cougar",
15
+ "crane",
16
+ "deer",
17
+ "dolphin",
18
+ "duck",
19
+ "eagle",
20
+ "falcon",
21
+ "finch",
22
+ "fox",
23
+ "frog",
24
+ "gecko",
25
+ "hawk",
26
+ "heron",
27
+ "horse",
28
+ "jaguar",
29
+ "koala",
30
+ "leopard",
31
+ "lion",
32
+ "llama",
33
+ "lynx",
34
+ "mole",
35
+ "moose",
36
+ "otter",
37
+ "owl",
38
+ "panda",
39
+ "penguin",
40
+ "rabbit",
41
+ "robin",
42
+ "seal",
43
+ "shark",
44
+ "sparrow",
45
+ "tiger",
46
+ "tortoise",
47
+ "wolf",
48
+ ]
49
+
50
+ ADJECTIVES = [
51
+ "able",
52
+ "agile",
53
+ "alert",
54
+ "alpha",
55
+ "amber",
56
+ "apex",
57
+ "arctic",
58
+ "atomic",
59
+ "balanced",
60
+ "basic",
61
+ "bold",
62
+ "bright",
63
+ "brisk",
64
+ "calm",
65
+ "clever",
66
+ "clear",
67
+ "cloudy",
68
+ "crisp",
69
+ "curious",
70
+ "cyber",
71
+ "daring",
72
+ "deep",
73
+ "delta",
74
+ "digital",
75
+ "dynamic",
76
+ "early",
77
+ "easy",
78
+ "electric",
79
+ "epic",
80
+ "fast",
81
+ "firm",
82
+ "fluent",
83
+ "focused",
84
+ "fresh",
85
+ "friendly",
86
+ "full",
87
+ "future",
88
+ "gentle",
89
+ "global",
90
+ "golden",
91
+ "grand",
92
+ "great",
93
+ "green",
94
+ "happy",
95
+ "high",
96
+ "honest",
97
+ "hyper",
98
+ "ideal",
99
+ "infinite",
100
+ "inner",
101
+ "instant",
102
+ "keen",
103
+ "kind",
104
+ "known",
105
+ "large",
106
+ "light",
107
+ "linear",
108
+ "logical",
109
+ "lucky",
110
+ "lunar",
111
+ "magic",
112
+ "major",
113
+ "mega",
114
+ "mild",
115
+ "modern",
116
+ "neat",
117
+ "noble",
118
+ "open",
119
+ "outer",
120
+ "peak",
121
+ "perfect",
122
+ "plain",
123
+ "prime",
124
+ "pure",
125
+ "quick",
126
+ "quiet",
127
+ "rapid",
128
+ "rare",
129
+ "ready",
130
+ "real",
131
+ "red",
132
+ "right",
133
+ "safe",
134
+ "sharp",
135
+ "silent",
136
+ "simple",
137
+ "smart",
138
+ "solid",
139
+ "solar",
140
+ "speedy",
141
+ "stable",
142
+ "steady",
143
+ "stellar",
144
+ "strong",
145
+ "swift",
146
+ "true",
147
+ "ultra",
148
+ "vast",
149
+ "vital",
150
+ "wise",
151
+ ]
@@ -4,8 +4,12 @@
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
+ import random
8
+
7
9
  from pydantic import BaseModel, Field
8
10
 
11
+ from digitalhub.entities._constructors._resources import ADJECTIVES, ANIMALS
12
+
9
13
  NAME_REGEX = r"^[a-zA-Z0-9._+-]+$"
10
14
 
11
15
 
@@ -33,3 +37,17 @@ def build_name(name: str) -> str:
33
37
  """
34
38
  NameValidator(name=name)
35
39
  return name
40
+
41
+
42
+ def random_name() -> str:
43
+ """
44
+ Generate a random name.
45
+
46
+ Returns
47
+ -------
48
+ str
49
+ The random name.
50
+ """
51
+ adjective = random.choice(ADJECTIVES)
52
+ animal = random.choice(ANIMALS)
53
+ return f"{adjective}-{animal}"
@@ -0,0 +1,381 @@
1
+ # SPDX-FileCopyrightText: © 2025 DSLab - Fondazione Bruno Kessler
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from __future__ import annotations
6
+
7
+ import typing
8
+
9
+ from digitalhub.context.api import delete_context
10
+ from digitalhub.factory.entity import entity_factory
11
+ from digitalhub.stores.client.builder import get_client
12
+ from digitalhub.stores.client.enums import ApiCategories, BackendOperations
13
+
14
+ if typing.TYPE_CHECKING:
15
+ from digitalhub.entities.project._base.entity import Project
16
+ from digitalhub.stores.client.client import Client
17
+
18
+
19
+ class BaseEntityCRUDProcessor:
20
+ """
21
+ Processor for core CRUD operations on base entities.
22
+
23
+ Handles creation, reading, updating, deletion, and listing of
24
+ base-level entities (primarily projects) within the backend.
25
+ """
26
+
27
+ def _create_base_entity(
28
+ self,
29
+ client: Client,
30
+ entity_type: str,
31
+ entity_dict: dict,
32
+ **kwargs,
33
+ ) -> dict:
34
+ """
35
+ Create a base entity in the backend.
36
+
37
+ Builds the appropriate API endpoint and sends a create request
38
+ to the backend for base-level entities.
39
+
40
+ Parameters
41
+ ----------
42
+ client : Client
43
+ The client instance to use for the API call.
44
+ entity_type : str
45
+ The type of entity to create (e.g., 'project').
46
+ entity_dict : dict
47
+ The entity data dictionary to create.
48
+ **kwargs : dict
49
+ Additional parameters to pass to the API call.
50
+
51
+ Returns
52
+ -------
53
+ dict
54
+ The created entity data returned from the backend.
55
+ """
56
+ api = client.build_api(
57
+ ApiCategories.BASE.value,
58
+ BackendOperations.CREATE.value,
59
+ entity_type=entity_type,
60
+ )
61
+ return client.create_object(api, entity_dict, **kwargs)
62
+
63
+ def create_project_entity(
64
+ self,
65
+ _entity: Project | None = None,
66
+ **kwargs,
67
+ ) -> Project:
68
+ """
69
+ Create a project entity in the backend.
70
+
71
+ Creates a new project either from an existing entity object or
72
+ by building one from the provided parameters.
73
+
74
+ Parameters
75
+ ----------
76
+ _entity : Project
77
+ An existing project entity object to create. If None,
78
+ a new entity will be built from kwargs.
79
+ **kwargs : dict
80
+ Parameters for entity creation.
81
+
82
+ Returns
83
+ -------
84
+ Project
85
+ The created project entity with backend data populated.
86
+ """
87
+ if _entity is not None:
88
+ client = _entity._client
89
+ obj = _entity
90
+ else:
91
+ client = get_client()
92
+ obj = entity_factory.build_entity_from_params(**kwargs)
93
+ ent = self._create_base_entity(client, obj.ENTITY_TYPE, obj.to_dict())
94
+ return entity_factory.build_entity_from_dict(ent)
95
+
96
+ def _read_base_entity(
97
+ self,
98
+ client: Client,
99
+ entity_type: str,
100
+ entity_name: str,
101
+ **kwargs,
102
+ ) -> dict:
103
+ """
104
+ Read a base entity from the backend.
105
+
106
+ Builds the appropriate API endpoint and sends a read request
107
+ to retrieve entity data from the backend.
108
+
109
+ Parameters
110
+ ----------
111
+ client : Client
112
+ The client instance to use for the API call.
113
+ entity_type : str
114
+ The type of entity to read (e.g., 'project').
115
+ entity_name : str
116
+ The name identifier of the entity to read.
117
+ **kwargs : dict
118
+ Additional parameters to pass to the API call.
119
+
120
+ Returns
121
+ -------
122
+ dict
123
+ The entity data retrieved from the backend.
124
+ """
125
+ api = client.build_api(
126
+ ApiCategories.BASE.value,
127
+ BackendOperations.READ.value,
128
+ entity_type=entity_type,
129
+ entity_name=entity_name,
130
+ )
131
+ return client.read_object(api, **kwargs)
132
+
133
+ def read_project_entity(
134
+ self,
135
+ entity_type: str,
136
+ entity_name: str,
137
+ **kwargs,
138
+ ) -> Project:
139
+ """
140
+ Read a project entity from the backend.
141
+
142
+ Retrieves project data from the backend and constructs a
143
+ Project entity object with the retrieved data.
144
+
145
+ Parameters
146
+ ----------
147
+ entity_type : str
148
+ The type of entity to read (typically 'project').
149
+ entity_name : str
150
+ The name identifier of the project to read.
151
+ **kwargs : dict
152
+ Additional parameters including 'local' flag and
153
+ API call parameters.
154
+
155
+ Returns
156
+ -------
157
+ Project
158
+ The project entity object populated with backend data.
159
+ """
160
+ client = get_client()
161
+ obj = self._read_base_entity(client, entity_type, entity_name, **kwargs)
162
+ return entity_factory.build_entity_from_dict(obj)
163
+
164
+ def _list_base_entities(
165
+ self,
166
+ client: Client,
167
+ entity_type: str,
168
+ **kwargs,
169
+ ) -> list[dict]:
170
+ """
171
+ List base entities from the backend.
172
+
173
+ Builds the appropriate API endpoint and sends a list request
174
+ to retrieve multiple entities from the backend.
175
+
176
+ Parameters
177
+ ----------
178
+ client : Client
179
+ The client instance to use for the API call.
180
+ entity_type : str
181
+ The type of entities to list (e.g., 'project').
182
+ **kwargs : dict
183
+ Additional parameters to pass to the API call for filtering
184
+ or pagination.
185
+
186
+ Returns
187
+ -------
188
+ list[dict]
189
+ List of entity data dictionaries from the backend.
190
+ """
191
+ api = client.build_api(
192
+ ApiCategories.BASE.value,
193
+ BackendOperations.LIST.value,
194
+ entity_type=entity_type,
195
+ )
196
+ return client.list_objects(api, **kwargs)
197
+
198
+ def list_project_entities(
199
+ self,
200
+ entity_type: str,
201
+ **kwargs,
202
+ ) -> list[Project]:
203
+ """
204
+ List project entities from the backend.
205
+
206
+ Retrieves a list of projects from the backend and converts
207
+ them to Project entity objects.
208
+
209
+ Parameters
210
+ ----------
211
+ entity_type : str
212
+ The type of entities to list (typically 'project').
213
+ **kwargs : dict
214
+ Additional parameters.
215
+
216
+ Returns
217
+ -------
218
+ list[Project]
219
+ List of project entity objects.
220
+ """
221
+ client = get_client()
222
+ objs = self._list_base_entities(client, entity_type, **kwargs)
223
+ entities = []
224
+ for obj in objs:
225
+ ent = entity_factory.build_entity_from_dict(obj)
226
+ entities.append(ent)
227
+ return entities
228
+
229
+ def _update_base_entity(
230
+ self,
231
+ client: Client,
232
+ entity_type: str,
233
+ entity_name: str,
234
+ entity_dict: dict,
235
+ **kwargs,
236
+ ) -> dict:
237
+ """
238
+ Update a base entity in the backend.
239
+
240
+ Builds the appropriate API endpoint and sends an update request
241
+ to modify an existing entity in the backend.
242
+
243
+ Parameters
244
+ ----------
245
+ client : Client
246
+ The client instance to use for the API call.
247
+ entity_type : str
248
+ The type of entity to update (e.g., 'project').
249
+ entity_name : str
250
+ The name identifier of the entity to update.
251
+ entity_dict : dict
252
+ The updated entity data dictionary.
253
+ **kwargs : dict
254
+ Additional parameters to pass to the API call.
255
+
256
+ Returns
257
+ -------
258
+ dict
259
+ The updated entity data returned from the backend.
260
+ """
261
+ api = client.build_api(
262
+ ApiCategories.BASE.value,
263
+ BackendOperations.UPDATE.value,
264
+ entity_type=entity_type,
265
+ entity_name=entity_name,
266
+ )
267
+ return client.update_object(api, entity_dict, **kwargs)
268
+
269
+ def update_project_entity(
270
+ self,
271
+ entity_type: str,
272
+ entity_name: str,
273
+ entity_dict: dict,
274
+ **kwargs,
275
+ ) -> Project:
276
+ """
277
+ Update a project entity in the backend.
278
+
279
+ Updates an existing project with new data and returns the
280
+ updated Project entity object.
281
+
282
+ Parameters
283
+ ----------
284
+ entity_type : str
285
+ The type of entity to update (typically 'project').
286
+ entity_name : str
287
+ The name identifier of the project to update.
288
+ entity_dict : dict
289
+ The updated project data dictionary.
290
+ **kwargs : dict
291
+ Additional parameters.
292
+
293
+ Returns
294
+ -------
295
+ Project
296
+ The updated project entity object.
297
+ """
298
+ client = get_client()
299
+ obj = self._update_base_entity(client, entity_type, entity_name, entity_dict, **kwargs)
300
+ return entity_factory.build_entity_from_dict(obj)
301
+
302
+ def _delete_base_entity(
303
+ self,
304
+ client: Client,
305
+ entity_type: str,
306
+ entity_name: str,
307
+ **kwargs,
308
+ ) -> dict:
309
+ """
310
+ Delete a base entity from the backend.
311
+
312
+ Builds the appropriate API endpoint and parameters, then sends
313
+ a delete request to remove the entity from the backend.
314
+
315
+ Parameters
316
+ ----------
317
+ client : Client
318
+ The client instance to use for the API call.
319
+ entity_type : str
320
+ The type of entity to delete (e.g., 'project').
321
+ entity_name : str
322
+ The name identifier of the entity to delete.
323
+ **kwargs : dict
324
+ Additional parameters to pass to the API call, such as
325
+ cascade deletion options.
326
+
327
+ Returns
328
+ -------
329
+ dict
330
+ Response data from the backend delete operation.
331
+ """
332
+ kwargs = client.build_parameters(
333
+ ApiCategories.BASE.value,
334
+ BackendOperations.DELETE.value,
335
+ **kwargs,
336
+ )
337
+ api = client.build_api(
338
+ ApiCategories.BASE.value,
339
+ BackendOperations.DELETE.value,
340
+ entity_type=entity_type,
341
+ entity_name=entity_name,
342
+ )
343
+ return client.delete_object(api, **kwargs)
344
+
345
+ def delete_project_entity(
346
+ self,
347
+ entity_type: str,
348
+ entity_name: str,
349
+ **kwargs,
350
+ ) -> dict:
351
+ """
352
+ Delete a project entity from the backend.
353
+
354
+ Deletes a project from the backend and optionally cleans up
355
+ the associated context.
356
+
357
+ Parameters
358
+ ----------
359
+ crud_processor : BaseEntityCRUDProcessor
360
+ The CRUD processor instance for entity operations.
361
+ entity_type : str
362
+ The type of entity to delete (typically 'project').
363
+ entity_name : str
364
+ The name identifier of the project to delete.
365
+ **kwargs : dict
366
+ Additional parameters including 'clean_context'.
367
+
368
+ Returns
369
+ -------
370
+ dict
371
+ Response data from the backend delete operation.
372
+ """
373
+ if kwargs.pop("clean_context", True):
374
+ delete_context(entity_name)
375
+ client = get_client()
376
+ return self._delete_base_entity(
377
+ client,
378
+ entity_type,
379
+ entity_name,
380
+ **kwargs,
381
+ )
@@ -0,0 +1,118 @@
1
+ # SPDX-FileCopyrightText: © 2025 DSLab - Fondazione Bruno Kessler
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from __future__ import annotations
6
+
7
+ import typing
8
+ from warnings import warn
9
+
10
+ from digitalhub.factory.entity import entity_factory
11
+ from digitalhub.utils.exceptions import EntityAlreadyExistsError, EntityError, EntityNotExistsError
12
+ from digitalhub.utils.io_utils import read_yaml
13
+
14
+ if typing.TYPE_CHECKING:
15
+ from digitalhub.entities._processors.base.crud import BaseEntityCRUDProcessor
16
+ from digitalhub.entities.project._base.entity import Project
17
+
18
+
19
+ class BaseEntityImportExportProcessor:
20
+ """
21
+ Processor for import and export operations on base entities.
22
+
23
+ Handles loading entities from YAML files and importing/exporting
24
+ entity configurations between local files and the backend.
25
+ """
26
+
27
+ def import_project_entity(
28
+ self,
29
+ crud_processor: BaseEntityCRUDProcessor,
30
+ file: str,
31
+ **kwargs,
32
+ ) -> Project:
33
+ """
34
+ Import a project entity from a YAML file and create it in the backend.
35
+
36
+ Reads project configuration from a YAML file, creates a new project
37
+ entity in the backend, and imports any related entities defined
38
+ in the file. Raises an error if the project already exists.
39
+
40
+ Parameters
41
+ ----------
42
+ crud_processor : BaseEntityCRUDProcessor
43
+ The CRUD processor instance for entity operations.
44
+ file : str
45
+ Path to the YAML file containing project configuration.
46
+ **kwargs : dict
47
+ Additional parameters including 'local' and 'reset_id' flags.
48
+
49
+ Returns
50
+ -------
51
+ Project
52
+ The imported and created project entity.
53
+
54
+ Raises
55
+ ------
56
+ EntityError
57
+ If the project already exists in the backend.
58
+ """
59
+ obj: dict = read_yaml(file)
60
+ obj["status"] = {}
61
+ ent: Project = entity_factory.build_entity_from_dict(obj)
62
+ reset_id = kwargs.pop("reset_id", False)
63
+
64
+ try:
65
+ crud_processor._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
66
+ except EntityAlreadyExistsError:
67
+ msg = f"Entity {ent.name} already exists."
68
+ if reset_id:
69
+ ent._import_entities(obj, reset_id=reset_id)
70
+ warn(f"{msg} Other entities ids have been imported.")
71
+ ent.refresh()
72
+ return ent
73
+ raise EntityError(f"{msg} If you want to update it, use load instead.")
74
+
75
+ # Import related entities
76
+ ent._import_entities(obj, reset_id=reset_id)
77
+ ent.refresh()
78
+ return ent
79
+
80
+ def load_project_entity(
81
+ self,
82
+ crud_processor: BaseEntityCRUDProcessor,
83
+ file: str,
84
+ **kwargs,
85
+ ) -> Project:
86
+ """
87
+ Load a project entity from a YAML file and update it in the backend.
88
+
89
+ Reads project configuration from a YAML file and updates an existing
90
+ project in the backend. If the project doesn't exist, it creates a
91
+ new one. Also loads any related entities defined in the file.
92
+
93
+ Parameters
94
+ ----------
95
+ crud_processor : BaseEntityCRUDProcessor
96
+ The CRUD processor instance for entity operations.
97
+ file : str
98
+ Path to the YAML file containing project configuration.
99
+ **kwargs : dict
100
+ Additional parameters including 'local' flag.
101
+
102
+ Returns
103
+ -------
104
+ Project
105
+ The loaded and updated project entity.
106
+ """
107
+ obj: dict = read_yaml(file)
108
+ ent: Project = entity_factory.build_entity_from_dict(obj)
109
+
110
+ try:
111
+ crud_processor._update_base_entity(ent._client, ent.ENTITY_TYPE, ent.name, ent.to_dict())
112
+ except EntityNotExistsError:
113
+ crud_processor._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
114
+
115
+ # Load related entities
116
+ ent._load_entities(obj)
117
+ ent.refresh()
118
+ return ent