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,652 @@
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.entities._commons.utils import is_valid_key, sanitize_unversioned_key
10
+ from digitalhub.entities._processors.utils import (
11
+ get_context,
12
+ get_context_from_identifier,
13
+ parse_identifier,
14
+ )
15
+ from digitalhub.factory.entity import entity_factory
16
+ from digitalhub.stores.client.enums import ApiCategories, BackendOperations
17
+
18
+ if typing.TYPE_CHECKING:
19
+ from digitalhub.context.context import Context
20
+ from digitalhub.entities._base.context.entity import ContextEntity
21
+ from digitalhub.entities._base.unversioned.entity import UnversionedEntity
22
+
23
+
24
+ class ContextEntityCRUDProcessor:
25
+ """
26
+ Processor for core CRUD operations on context entities.
27
+
28
+ Handles creation, reading, updating, deletion, and listing of
29
+ context-level entities within projects.
30
+ """
31
+
32
+ def _create_context_entity(
33
+ self,
34
+ context: Context,
35
+ entity_type: str,
36
+ entity_dict: dict,
37
+ ) -> dict:
38
+ """
39
+ Create a context entity in the backend.
40
+
41
+ Builds the appropriate API endpoint and sends a create request
42
+ to the backend for context-level entities within a project.
43
+
44
+ Parameters
45
+ ----------
46
+ context : Context
47
+ The project context instance.
48
+ entity_type : str
49
+ The type of entity to create (e.g., 'artifact', 'function').
50
+ entity_dict : dict
51
+ The entity data dictionary to create.
52
+
53
+ Returns
54
+ -------
55
+ dict
56
+ The created entity data returned from the backend.
57
+ """
58
+ api = context.client.build_api(
59
+ ApiCategories.CONTEXT.value,
60
+ BackendOperations.CREATE.value,
61
+ project=context.name,
62
+ entity_type=entity_type,
63
+ )
64
+ return context.client.create_object(api, entity_dict)
65
+
66
+ def create_context_entity(
67
+ self,
68
+ _entity: ContextEntity | None = None,
69
+ **kwargs,
70
+ ) -> ContextEntity:
71
+ """
72
+ Create a context entity in the backend.
73
+
74
+ Creates a new context entity either from an existing entity object
75
+ or by building one from the provided parameters. Handles entity
76
+ creation within a project context.
77
+
78
+ Parameters
79
+ ----------
80
+ _entity : ContextEntity
81
+ An existing context entity object to create. If None,
82
+ a new entity will be built from kwargs.
83
+ **kwargs : dict
84
+ Parameters for entity creation, including 'project' and
85
+ entity-specific parameters.
86
+
87
+ Returns
88
+ -------
89
+ ContextEntity
90
+ The created context entity with backend data populated.
91
+ """
92
+ if _entity is not None:
93
+ context = _entity._context()
94
+ obj = _entity
95
+ else:
96
+ context = get_context(kwargs["project"])
97
+ obj: ContextEntity = entity_factory.build_entity_from_params(**kwargs)
98
+ new_obj = self._create_context_entity(context, obj.ENTITY_TYPE, obj.to_dict())
99
+ return entity_factory.build_entity_from_dict(new_obj)
100
+
101
+ def _read_context_entity(
102
+ self,
103
+ context: Context,
104
+ identifier: str,
105
+ entity_type: str | None = None,
106
+ project: str | None = None,
107
+ entity_id: str | None = None,
108
+ **kwargs,
109
+ ) -> dict:
110
+ """
111
+ Read a context entity from the backend.
112
+
113
+ Retrieves entity data from the backend using either entity ID
114
+ for direct access or entity name for latest version lookup.
115
+ Handles both specific version reads and latest version queries.
116
+
117
+ Parameters
118
+ ----------
119
+ context : Context
120
+ The project context instance.
121
+ identifier : str
122
+ Entity key (store://...) or entity name identifier.
123
+ entity_type : str
124
+ The type of entity to read.
125
+ project : str
126
+ Project name (used for identifier parsing).
127
+ entity_id : str
128
+ Specific entity ID to read.
129
+ **kwargs : dict
130
+ Additional parameters to pass to the API call.
131
+
132
+ Returns
133
+ -------
134
+ dict
135
+ The entity data retrieved from the backend.
136
+ """
137
+ project, entity_type, _, entity_name, entity_id = parse_identifier(
138
+ identifier,
139
+ project=project,
140
+ entity_type=entity_type,
141
+ entity_id=entity_id,
142
+ )
143
+
144
+ if entity_id is None:
145
+ kwargs["name"] = entity_name
146
+ kwargs = context.client.build_parameters(
147
+ ApiCategories.CONTEXT.value,
148
+ BackendOperations.READ.value,
149
+ **kwargs,
150
+ )
151
+
152
+ if entity_id is None:
153
+ api = context.client.build_api(
154
+ ApiCategories.CONTEXT.value,
155
+ BackendOperations.LIST.value,
156
+ project=context.name,
157
+ entity_type=entity_type,
158
+ )
159
+ return context.client.list_first_object(api, **kwargs)
160
+
161
+ api = context.client.build_api(
162
+ ApiCategories.CONTEXT.value,
163
+ BackendOperations.READ.value,
164
+ project=context.name,
165
+ entity_type=entity_type,
166
+ entity_id=entity_id,
167
+ )
168
+ return context.client.read_object(api, **kwargs)
169
+
170
+ def read_context_entity(
171
+ self,
172
+ identifier: str,
173
+ entity_type: str | None = None,
174
+ project: str | None = None,
175
+ entity_id: str | None = None,
176
+ **kwargs,
177
+ ) -> ContextEntity:
178
+ """
179
+ Read a context entity from the backend.
180
+
181
+ Retrieves entity data from the backend and constructs a context
182
+ entity object. Handles post-processing for metrics and file info.
183
+
184
+ Parameters
185
+ ----------
186
+ identifier : str
187
+ Entity key (store://...) or entity name identifier.
188
+ entity_type : str
189
+ The type of entity to read.
190
+ project : str
191
+ Project name for context resolution.
192
+ entity_id : str
193
+ Specific entity ID to read.
194
+ **kwargs : dict
195
+ Additional parameters to pass to the API call.
196
+
197
+ Returns
198
+ -------
199
+ ContextEntity
200
+ The context entity object populated with backend data.
201
+ """
202
+ context = get_context_from_identifier(identifier, project)
203
+ obj = self._read_context_entity(
204
+ context,
205
+ identifier,
206
+ entity_type=entity_type,
207
+ project=project,
208
+ entity_id=entity_id,
209
+ **kwargs,
210
+ )
211
+ entity = entity_factory.build_entity_from_dict(obj)
212
+ return self._post_process_get(entity)
213
+
214
+ def read_unversioned_entity(
215
+ self,
216
+ identifier: str,
217
+ entity_type: str | None = None,
218
+ project: str | None = None,
219
+ entity_id: str | None = None,
220
+ **kwargs,
221
+ ) -> UnversionedEntity:
222
+ """
223
+ Read an unversioned entity from the backend.
224
+
225
+ Retrieves unversioned entity data (runs, tasks) from the backend.
226
+ Handles identifier parsing for entities that don't follow the
227
+ standard versioned naming convention.
228
+
229
+ Parameters
230
+ ----------
231
+ identifier : str
232
+ Entity key (store://...) or entity ID.
233
+ entity_type : str
234
+ The type of entity to read.
235
+ project : str
236
+ Project name for context resolution.
237
+ entity_id : str
238
+ Specific entity ID to read.
239
+ **kwargs : dict
240
+ Additional parameters to pass to the API call.
241
+
242
+ Returns
243
+ -------
244
+ UnversionedEntity
245
+ The unversioned entity object populated with backend data.
246
+ """
247
+ if not is_valid_key(identifier):
248
+ entity_id = identifier
249
+ else:
250
+ identifier = sanitize_unversioned_key(identifier)
251
+ return self.read_context_entity(
252
+ identifier,
253
+ entity_type=entity_type,
254
+ project=project,
255
+ entity_id=entity_id,
256
+ **kwargs,
257
+ )
258
+
259
+ def _read_context_entity_versions(
260
+ self,
261
+ context: Context,
262
+ identifier: str,
263
+ entity_type: str | None = None,
264
+ project: str | None = None,
265
+ **kwargs,
266
+ ) -> list[dict]:
267
+ """
268
+ Read all versions of a context entity from the backend.
269
+
270
+ Retrieves all available versions of a named entity from the
271
+ backend using the entity name identifier.
272
+
273
+ Parameters
274
+ ----------
275
+ context : Context
276
+ The project context instance.
277
+ identifier : str
278
+ Entity key (store://...) or entity name identifier.
279
+ entity_type : str
280
+ The type of entity to read versions for.
281
+ project : str
282
+ Project name (used for identifier parsing).
283
+ **kwargs : dict
284
+ Additional parameters to pass to the API call.
285
+
286
+ Returns
287
+ -------
288
+ list[dict]
289
+ List of entity data dictionaries for all versions.
290
+ """
291
+ project, entity_type, _, entity_name, _ = parse_identifier(
292
+ identifier,
293
+ project=project,
294
+ entity_type=entity_type,
295
+ )
296
+
297
+ kwargs = context.client.build_parameters(
298
+ ApiCategories.CONTEXT.value,
299
+ BackendOperations.READ_ALL_VERSIONS.value,
300
+ name=entity_name,
301
+ **kwargs,
302
+ )
303
+
304
+ api = context.client.build_api(
305
+ ApiCategories.CONTEXT.value,
306
+ BackendOperations.LIST.value,
307
+ project=context.name,
308
+ entity_type=entity_type,
309
+ )
310
+ return context.client.list_objects(api, **kwargs)
311
+
312
+ def read_context_entity_versions(
313
+ self,
314
+ identifier: str,
315
+ entity_type: str | None = None,
316
+ project: str | None = None,
317
+ **kwargs,
318
+ ) -> list[ContextEntity]:
319
+ """
320
+ Read all versions of a context entity from the backend.
321
+
322
+ Retrieves all available versions of a named entity and constructs
323
+ context entity objects for each version. Applies post-processing
324
+ for metrics and file info.
325
+
326
+ Parameters
327
+ ----------
328
+ identifier : str
329
+ Entity key (store://...) or entity name identifier.
330
+ entity_type : str
331
+ The type of entity to read versions for.
332
+ project : str
333
+ Project name for context resolution.
334
+ **kwargs : dict
335
+ Additional parameters to pass to the API call.
336
+
337
+ Returns
338
+ -------
339
+ list[ContextEntity]
340
+ List of context entity objects for all versions.
341
+ """
342
+ context = get_context_from_identifier(identifier, project)
343
+ objs = self._read_context_entity_versions(
344
+ context,
345
+ identifier,
346
+ entity_type=entity_type,
347
+ project=project,
348
+ **kwargs,
349
+ )
350
+ objects = []
351
+ for o in objs:
352
+ entity: ContextEntity = entity_factory.build_entity_from_dict(o)
353
+ entity = self._post_process_get(entity)
354
+ objects.append(entity)
355
+ return objects
356
+
357
+ def _list_context_entities(
358
+ self,
359
+ context: Context,
360
+ entity_type: str,
361
+ **kwargs,
362
+ ) -> list[dict]:
363
+ """
364
+ List context entities from the backend.
365
+
366
+ Retrieves a list of entities of a specific type from the backend
367
+ within the project context.
368
+
369
+ Parameters
370
+ ----------
371
+ context : Context
372
+ The project context instance.
373
+ entity_type : str
374
+ The type of entities to list.
375
+ **kwargs : dict
376
+ Additional parameters to pass to the API call for filtering
377
+ or pagination.
378
+
379
+ Returns
380
+ -------
381
+ list[dict]
382
+ List of entity data dictionaries from the backend.
383
+ """
384
+ kwargs = context.client.build_parameters(
385
+ ApiCategories.CONTEXT.value,
386
+ BackendOperations.LIST.value,
387
+ **kwargs,
388
+ )
389
+ api = context.client.build_api(
390
+ ApiCategories.CONTEXT.value,
391
+ BackendOperations.LIST.value,
392
+ project=context.name,
393
+ entity_type=entity_type,
394
+ )
395
+ return context.client.list_objects(api, **kwargs)
396
+
397
+ def list_context_entities(
398
+ self,
399
+ project: str,
400
+ entity_type: str,
401
+ **kwargs,
402
+ ) -> list[ContextEntity]:
403
+ """
404
+ List all latest version context entities from the backend.
405
+
406
+ Retrieves a list of entities of a specific type from the backend
407
+ and constructs context entity objects. Only returns the latest
408
+ version of each entity. Applies post-processing for metrics and
409
+ file info.
410
+
411
+ Parameters
412
+ ----------
413
+ project : str
414
+ The project name to list entities from.
415
+ entity_type : str
416
+ The type of entities to list.
417
+ **kwargs : dict
418
+ Additional parameters to pass to the API call for filtering
419
+ or pagination.
420
+
421
+ Returns
422
+ -------
423
+ list[ContextEntity]
424
+ List of context entity objects (latest versions only).
425
+ """
426
+ context = get_context(project)
427
+ objs = self._list_context_entities(context, entity_type, **kwargs)
428
+ objects = []
429
+ for o in objs:
430
+ entity: ContextEntity = entity_factory.build_entity_from_dict(o)
431
+ entity = self._post_process_get(entity)
432
+ objects.append(entity)
433
+ return objects
434
+
435
+ def _update_context_entity(
436
+ self,
437
+ context: Context,
438
+ entity_type: str,
439
+ entity_id: str,
440
+ entity_dict: dict,
441
+ **kwargs,
442
+ ) -> dict:
443
+ """
444
+ Update a context entity in the backend.
445
+
446
+ Updates an existing context entity with new data. Entity
447
+ specifications are typically immutable, so this primarily
448
+ updates status and metadata.
449
+
450
+ Parameters
451
+ ----------
452
+ context : Context
453
+ The project context instance.
454
+ entity_type : str
455
+ The type of entity to update.
456
+ entity_id : str
457
+ The unique identifier of the entity to update.
458
+ entity_dict : dict
459
+ The updated entity data dictionary.
460
+ **kwargs : dict
461
+ Additional parameters to pass to the API call.
462
+
463
+ Returns
464
+ -------
465
+ dict
466
+ Response data from the backend update operation.
467
+ """
468
+ api = context.client.build_api(
469
+ ApiCategories.CONTEXT.value,
470
+ BackendOperations.UPDATE.value,
471
+ project=context.name,
472
+ entity_type=entity_type,
473
+ entity_id=entity_id,
474
+ )
475
+ return context.client.update_object(api, entity_dict, **kwargs)
476
+
477
+ def update_context_entity(
478
+ self,
479
+ project: str,
480
+ entity_type: str,
481
+ entity_id: str,
482
+ entity_dict: dict,
483
+ **kwargs,
484
+ ) -> ContextEntity:
485
+ """
486
+ Update a context entity in the backend.
487
+
488
+ Updates an existing context entity with new data and returns
489
+ the updated context entity object. Entity specifications are
490
+ typically immutable.
491
+
492
+ Parameters
493
+ ----------
494
+ project : str
495
+ The project name containing the entity.
496
+ entity_type : str
497
+ The type of entity to update.
498
+ entity_id : str
499
+ The unique identifier of the entity to update.
500
+ entity_dict : dict
501
+ The updated entity data dictionary.
502
+ **kwargs : dict
503
+ Additional parameters to pass to the API call.
504
+
505
+ Returns
506
+ -------
507
+ ContextEntity
508
+ The updated context entity object.
509
+ """
510
+ context = get_context(project)
511
+ obj = self._update_context_entity(
512
+ context,
513
+ entity_type,
514
+ entity_id,
515
+ entity_dict,
516
+ **kwargs,
517
+ )
518
+ return entity_factory.build_entity_from_dict(obj)
519
+
520
+ def _delete_context_entity(
521
+ self,
522
+ context: Context,
523
+ identifier: str,
524
+ entity_type: str | None = None,
525
+ project: str | None = None,
526
+ entity_id: str | None = None,
527
+ **kwargs,
528
+ ) -> dict:
529
+ """
530
+ Delete a context entity from the backend.
531
+
532
+ Removes an entity from the backend, with options for deleting
533
+ specific versions or all versions of a named entity. Handles
534
+ cascade deletion if supported.
535
+
536
+ Parameters
537
+ ----------
538
+ context : Context
539
+ The project context instance.
540
+ identifier : str
541
+ Entity key (store://...) or entity name identifier.
542
+ entity_type : str
543
+ The type of entity to delete.
544
+ project : str
545
+ Project name (used for identifier parsing).
546
+ entity_id : str
547
+ Specific entity ID to delete.
548
+ **kwargs : dict
549
+ Additional parameters including:
550
+ - 'delete_all_versions': delete all versions of named entity
551
+ - 'cascade': cascade deletion options
552
+
553
+ Returns
554
+ -------
555
+ dict
556
+ Response data from the backend delete operation.
557
+ """
558
+ project, entity_type, _, entity_name, entity_id = parse_identifier(
559
+ identifier,
560
+ project=project,
561
+ entity_type=entity_type,
562
+ entity_id=entity_id,
563
+ )
564
+
565
+ delete_all_versions: bool = kwargs.pop("delete_all_versions", False)
566
+ if delete_all_versions:
567
+ op = BackendOperations.DELETE_ALL_VERSIONS.value
568
+ kwargs["name"] = entity_name
569
+ else:
570
+ if entity_id is None:
571
+ raise ValueError("If `delete_all_versions` is False, `entity_id` must be provided.")
572
+ op = BackendOperations.DELETE.value
573
+
574
+ kwargs = context.client.build_parameters(
575
+ ApiCategories.CONTEXT.value,
576
+ op,
577
+ **kwargs,
578
+ )
579
+
580
+ api = context.client.build_api(
581
+ ApiCategories.CONTEXT.value,
582
+ op,
583
+ project=context.name,
584
+ entity_type=entity_type,
585
+ entity_id=entity_id,
586
+ )
587
+ return context.client.delete_object(api, **kwargs)
588
+
589
+ def delete_context_entity(
590
+ self,
591
+ identifier: str,
592
+ project: str | None = None,
593
+ entity_type: str | None = None,
594
+ entity_id: str | None = None,
595
+ **kwargs,
596
+ ) -> dict:
597
+ """
598
+ Delete a context entity from the backend.
599
+
600
+ Removes an entity from the backend with support for deleting
601
+ specific versions or all versions of a named entity.
602
+
603
+ Parameters
604
+ ----------
605
+ identifier : str
606
+ Entity key (store://...) or entity name identifier.
607
+ project : str
608
+ Project name for context resolution.
609
+ entity_type : str
610
+ The type of entity to delete.
611
+ entity_id : str
612
+ Specific entity ID to delete.
613
+ **kwargs : dict
614
+ Additional parameters including deletion options.
615
+
616
+ Returns
617
+ -------
618
+ dict
619
+ Response data from the backend delete operation.
620
+ """
621
+ context = get_context_from_identifier(identifier, project)
622
+ return self._delete_context_entity(
623
+ context,
624
+ identifier,
625
+ entity_type,
626
+ context.name,
627
+ entity_id,
628
+ **kwargs,
629
+ )
630
+
631
+ def _post_process_get(self, entity: ContextEntity) -> ContextEntity:
632
+ """
633
+ Post-process a retrieved context entity.
634
+
635
+ Applies additional processing to entities after retrieval,
636
+ including loading metrics and file information if available.
637
+
638
+ Parameters
639
+ ----------
640
+ entity : ContextEntity
641
+ The entity to post-process.
642
+
643
+ Returns
644
+ -------
645
+ ContextEntity
646
+ The post-processed entity with additional data loaded.
647
+ """
648
+ if hasattr(entity.status, "metrics"):
649
+ entity._get_metrics()
650
+ if hasattr(entity.status, "files"):
651
+ entity._get_files_info()
652
+ return entity