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
@@ -1,1299 +0,0 @@
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 typing import Any
9
-
10
- from digitalhub.entities._commons.enums import ApiCategories, BackendOperations, Relationship, State
11
- from digitalhub.entities._processors.utils import (
12
- get_context_from_identifier,
13
- get_context_from_project,
14
- parse_identifier,
15
- )
16
- from digitalhub.factory.factory import factory
17
- from digitalhub.utils.exceptions import EntityAlreadyExistsError, EntityError, EntityNotExistsError
18
- from digitalhub.utils.io_utils import read_yaml
19
- from digitalhub.utils.types import SourcesOrListOfSources
20
-
21
- if typing.TYPE_CHECKING:
22
- from digitalhub.context.context import Context
23
- from digitalhub.entities._base.context.entity import ContextEntity
24
- from digitalhub.entities._base.executable.entity import ExecutableEntity
25
- from digitalhub.entities._base.material.entity import MaterialEntity
26
- from digitalhub.entities._base.unversioned.entity import UnversionedEntity
27
-
28
-
29
- class ContextEntityOperationsProcessor:
30
- """
31
- Processor for Entity operations.
32
-
33
- This object interacts with the context, check the category of the object,
34
- and then calls the appropriate method to perform the requested operation.
35
- Operations can be CRUD, search, list, etc.
36
- """
37
-
38
- ##############################
39
- # CRUD context entity
40
- ##############################
41
-
42
- def _create_context_entity(
43
- self,
44
- context: Context,
45
- entity_type: str,
46
- entity_dict: dict,
47
- ) -> dict:
48
- """
49
- Create object in backend.
50
-
51
- Parameters
52
- ----------
53
- context : Context
54
- Context instance.
55
- project : str
56
- Project name.
57
- entity_type : str
58
- Entity type.
59
- entity_dict : dict
60
- Object instance.
61
-
62
- Returns
63
- -------
64
- dict
65
- Object instance.
66
- """
67
- api = context.client.build_api(
68
- ApiCategories.CONTEXT.value,
69
- BackendOperations.CREATE.value,
70
- project=context.name,
71
- entity_type=entity_type,
72
- )
73
- return context.client.create_object(api, entity_dict)
74
-
75
- def create_context_entity(
76
- self,
77
- _entity: ContextEntity | None = None,
78
- **kwargs,
79
- ) -> ContextEntity:
80
- """
81
- Create object in backend.
82
-
83
- Parameters
84
- ----------
85
- **kwargs : dict
86
- Parameters to pass to entity builder.
87
-
88
- Returns
89
- -------
90
- ContextEntity
91
- Object instance.
92
- """
93
- if _entity is not None:
94
- context = _entity._context()
95
- obj = _entity
96
- else:
97
- context = get_context_from_project(kwargs["project"])
98
- obj: ContextEntity = factory.build_entity_from_params(**kwargs)
99
- new_obj = self._create_context_entity(context, obj.ENTITY_TYPE, obj.to_dict())
100
- return factory.build_entity_from_dict(new_obj)
101
-
102
- def log_material_entity(
103
- self,
104
- **kwargs,
105
- ) -> MaterialEntity:
106
- """
107
- Create object in backend and upload file.
108
-
109
- Parameters
110
- ----------
111
- **kwargs : dict
112
- Parameters to pass to entity builder.
113
-
114
- Returns
115
- -------
116
- MaterialEntity
117
- Object instance.
118
- """
119
- source: SourcesOrListOfSources = kwargs.pop("source")
120
- context = get_context_from_project(kwargs["project"])
121
- obj = factory.build_entity_from_params(**kwargs)
122
- if context.is_running:
123
- obj.add_relationship(Relationship.PRODUCEDBY.value, context.get_run_ctx())
124
-
125
- new_obj: MaterialEntity = self._create_context_entity(context, obj.ENTITY_TYPE, obj.to_dict())
126
- new_obj = factory.build_entity_from_dict(new_obj)
127
-
128
- new_obj.status.state = State.UPLOADING.value
129
- new_obj = self._update_material_entity(new_obj)
130
-
131
- # Handle file upload
132
- try:
133
- new_obj.upload(source)
134
- uploaded = True
135
- msg = None
136
- except Exception as e:
137
- uploaded = False
138
- msg = str(e.args)
139
-
140
- new_obj.status.message = msg
141
-
142
- # Update status after upload
143
- if uploaded:
144
- new_obj.status.state = State.READY.value
145
- new_obj = self._update_material_entity(new_obj)
146
- else:
147
- new_obj.status.state = State.ERROR.value
148
- new_obj = self._update_material_entity(new_obj)
149
- raise EntityError(msg)
150
-
151
- return new_obj
152
-
153
- def _read_context_entity(
154
- self,
155
- context: Context,
156
- identifier: str,
157
- entity_type: str | None = None,
158
- project: str | None = None,
159
- entity_id: str | None = None,
160
- **kwargs,
161
- ) -> dict:
162
- """
163
- Read object from backend.
164
-
165
- Parameters
166
- ----------
167
- context : Context
168
- Context instance.
169
- identifier : str
170
- Entity key (store://...) or entity name.
171
- entity_type : str
172
- Entity type.
173
- project : str
174
- Project name.
175
- entity_id : str
176
- Entity ID.
177
- **kwargs : dict
178
- Parameters to pass to the API call.
179
-
180
- Returns
181
- -------
182
- dict
183
- Object instance.
184
- """
185
- project, entity_type, _, entity_name, entity_id = parse_identifier(
186
- identifier,
187
- project=project,
188
- entity_type=entity_type,
189
- entity_id=entity_id,
190
- )
191
-
192
- if entity_id is None:
193
- kwargs["entity_name"] = entity_name
194
- kwargs = context.client.build_parameters(
195
- ApiCategories.CONTEXT.value,
196
- BackendOperations.READ.value,
197
- **kwargs,
198
- )
199
-
200
- if entity_id is None:
201
- api = context.client.build_api(
202
- ApiCategories.CONTEXT.value,
203
- BackendOperations.LIST.value,
204
- project=context.name,
205
- entity_type=entity_type,
206
- )
207
- return context.client.list_first_object(api, **kwargs)
208
-
209
- api = context.client.build_api(
210
- ApiCategories.CONTEXT.value,
211
- BackendOperations.READ.value,
212
- project=context.name,
213
- entity_type=entity_type,
214
- entity_id=entity_id,
215
- )
216
- return context.client.read_object(api, **kwargs)
217
-
218
- def read_context_entity(
219
- self,
220
- identifier: str,
221
- entity_type: str | None = None,
222
- project: str | None = None,
223
- entity_id: str | None = None,
224
- **kwargs,
225
- ) -> ContextEntity:
226
- """
227
- Read object from backend.
228
-
229
- Parameters
230
- ----------
231
- identifier : str
232
- Entity key (store://...) or entity name.
233
- entity_type : str
234
- Entity type.
235
- project : str
236
- Project name.
237
- entity_id : str
238
- Entity ID.
239
- **kwargs : dict
240
- Parameters to pass to the API call.
241
-
242
- Returns
243
- -------
244
- VersionedEntity
245
- Object instance.
246
- """
247
- context = get_context_from_identifier(identifier, project)
248
- obj = self._read_context_entity(
249
- context,
250
- identifier,
251
- entity_type=entity_type,
252
- project=project,
253
- entity_id=entity_id,
254
- **kwargs,
255
- )
256
- entity = factory.build_entity_from_dict(obj)
257
- return self._post_process_get(entity)
258
-
259
- def read_unversioned_entity(
260
- self,
261
- identifier: str,
262
- entity_type: str | None = None,
263
- project: str | None = None,
264
- entity_id: str | None = None,
265
- **kwargs,
266
- ) -> UnversionedEntity:
267
- """
268
- Read object from backend.
269
-
270
- Parameters
271
- ----------
272
- identifier : str
273
- Entity key (store://...) or entity name.
274
- entity_type : str
275
- Entity type.
276
- project : str
277
- Project name.
278
- entity_id : str
279
- Entity ID.
280
- **kwargs : dict
281
- Parameters to pass to the API call.
282
-
283
- Returns
284
- -------
285
- UnversionedEntity
286
- Object instance.
287
- """
288
- if not identifier.startswith("store://"):
289
- entity_id = identifier
290
- else:
291
- splt = identifier.split(":")
292
- if len(splt) == 3:
293
- identifier = f"{splt[0]}:{splt[1]}"
294
- return self.read_context_entity(
295
- identifier,
296
- entity_type=entity_type,
297
- project=project,
298
- entity_id=entity_id,
299
- **kwargs,
300
- )
301
-
302
- def import_context_entity(
303
- self,
304
- file: str,
305
- ) -> ContextEntity:
306
- """
307
- Import object from a YAML file and create a new object into the backend.
308
-
309
- Parameters
310
- ----------
311
- file : str
312
- Path to YAML file.
313
-
314
- Returns
315
- -------
316
- ContextEntity
317
- Object instance.
318
- """
319
- dict_obj: dict = read_yaml(file)
320
- dict_obj["status"] = {}
321
- context = get_context_from_project(dict_obj["project"])
322
- obj = factory.build_entity_from_dict(dict_obj)
323
- try:
324
- self._create_context_entity(context, obj.ENTITY_TYPE, obj.to_dict())
325
- except EntityAlreadyExistsError:
326
- raise EntityError(f"Entity {obj.name} already exists. If you want to update it, use load instead.")
327
- return obj
328
-
329
- def import_executable_entity(
330
- self,
331
- file: str,
332
- ) -> ExecutableEntity:
333
- """
334
- Import object from a YAML file and create a new object into the backend.
335
-
336
- Parameters
337
- ----------
338
- file : str
339
- Path to YAML file.
340
-
341
- Returns
342
- -------
343
- ExecutableEntity
344
- Object instance.
345
- """
346
- dict_obj: dict | list[dict] = read_yaml(file)
347
- if isinstance(dict_obj, list):
348
- exec_dict = dict_obj[0]
349
- exec_dict["status"] = {}
350
- tsk_dicts = []
351
- for i in dict_obj[1:]:
352
- i["status"] = {}
353
- tsk_dicts.append(i)
354
- else:
355
- exec_dict = dict_obj
356
- tsk_dicts = []
357
-
358
- context = get_context_from_project(exec_dict["project"])
359
- obj: ExecutableEntity = factory.build_entity_from_dict(exec_dict)
360
- try:
361
- self._create_context_entity(context, obj.ENTITY_TYPE, obj.to_dict())
362
- except EntityAlreadyExistsError:
363
- raise EntityError(f"Entity {obj.name} already exists. If you want to update it, use load instead.")
364
-
365
- obj.import_tasks(tsk_dicts)
366
-
367
- return obj
368
-
369
- def load_context_entity(
370
- self,
371
- file: str,
372
- ) -> ContextEntity:
373
- """
374
- Load object from a YAML file and update an existing object into the backend.
375
-
376
- Parameters
377
- ----------
378
- file : str
379
- Path to YAML file.
380
-
381
- Returns
382
- -------
383
- ContextEntity
384
- Object instance.
385
- """
386
- dict_obj: dict = read_yaml(file)
387
- context = get_context_from_project(dict_obj["project"])
388
- obj: ContextEntity = factory.build_entity_from_dict(dict_obj)
389
- try:
390
- self._update_context_entity(context, obj.ENTITY_TYPE, obj.id, obj.to_dict())
391
- except EntityNotExistsError:
392
- self._create_context_entity(context, obj.ENTITY_TYPE, obj.to_dict())
393
- return obj
394
-
395
- def load_executable_entity(
396
- self,
397
- file: str,
398
- ) -> ExecutableEntity:
399
- """
400
- Load object from a YAML file and update an existing object into the backend.
401
-
402
- Parameters
403
- ----------
404
- file : str
405
- Path to YAML file.
406
-
407
- Returns
408
- -------
409
- ExecutableEntity
410
- Object instance.
411
- """
412
- dict_obj: dict | list[dict] = read_yaml(file)
413
- if isinstance(dict_obj, list):
414
- exec_dict = dict_obj[0]
415
- tsk_dicts = dict_obj[1:]
416
- else:
417
- exec_dict = dict_obj
418
- tsk_dicts = []
419
-
420
- context = get_context_from_project(exec_dict["project"])
421
- obj: ExecutableEntity = factory.build_entity_from_dict(exec_dict)
422
-
423
- try:
424
- self._update_context_entity(context, obj.ENTITY_TYPE, obj.id, obj.to_dict())
425
- except EntityNotExistsError:
426
- self._create_context_entity(context, obj.ENTITY_TYPE, obj.to_dict())
427
- obj.import_tasks(tsk_dicts)
428
- return obj
429
-
430
- def _read_context_entity_versions(
431
- self,
432
- context: Context,
433
- identifier: str,
434
- entity_type: str | None = None,
435
- project: str | None = None,
436
- **kwargs,
437
- ) -> list[dict]:
438
- """
439
- Get all versions object from backend.
440
-
441
- Parameters
442
- ----------
443
- context : Context
444
- Context instance.
445
- identifier : str
446
- Entity key (store://...) or entity name.
447
- entity_type : str
448
- Entity type.
449
- project : str
450
- Project name.
451
- **kwargs : dict
452
- Parameters to pass to the API call.
453
-
454
- Returns
455
- -------
456
- list[dict]
457
- Object instances.
458
- """
459
- project, entity_type, _, entity_name, _ = parse_identifier(
460
- identifier,
461
- project=project,
462
- entity_type=entity_type,
463
- )
464
-
465
- kwargs = context.client.build_parameters(
466
- ApiCategories.CONTEXT.value,
467
- BackendOperations.READ_ALL_VERSIONS.value,
468
- entity_name=entity_name,
469
- **kwargs,
470
- )
471
-
472
- api = context.client.build_api(
473
- ApiCategories.CONTEXT.value,
474
- BackendOperations.LIST.value,
475
- project=context.name,
476
- entity_type=entity_type,
477
- )
478
- return context.client.list_objects(api, **kwargs)
479
-
480
- def read_context_entity_versions(
481
- self,
482
- identifier: str,
483
- entity_type: str | None = None,
484
- project: str | None = None,
485
- **kwargs,
486
- ) -> list[ContextEntity]:
487
- """
488
- Read object versions from backend.
489
-
490
- Parameters
491
- ----------
492
- identifier : str
493
- Entity key (store://...) or entity name.
494
- entity_type : str
495
- Entity type.
496
- project : str
497
- Project name.
498
- **kwargs : dict
499
- Parameters to pass to the API call.
500
-
501
- Returns
502
- -------
503
- list[ContextEntity]
504
- List of object instances.
505
- """
506
- context = get_context_from_identifier(identifier, project)
507
- objs = self._read_context_entity_versions(
508
- context,
509
- identifier,
510
- entity_type=entity_type,
511
- project=project,
512
- **kwargs,
513
- )
514
- objects = []
515
- for o in objs:
516
- entity: ContextEntity = factory.build_entity_from_dict(o)
517
- entity = self._post_process_get(entity)
518
- objects.append(entity)
519
- return objects
520
-
521
- def _list_context_entities(
522
- self,
523
- context: Context,
524
- entity_type: str,
525
- **kwargs,
526
- ) -> list[dict]:
527
- """
528
- List objects from backend.
529
-
530
- Parameters
531
- ----------
532
- context : Context
533
- Context instance.
534
- entity_type : str
535
- Entity type.
536
- **kwargs : dict
537
- Parameters to pass to the API call.
538
-
539
- Returns
540
- -------
541
- list[dict]
542
- List of objects.
543
- """
544
- api = context.client.build_api(
545
- ApiCategories.CONTEXT.value,
546
- BackendOperations.LIST.value,
547
- project=context.name,
548
- entity_type=entity_type,
549
- )
550
- return context.client.list_objects(api, **kwargs)
551
-
552
- def list_context_entities(
553
- self,
554
- project: str,
555
- entity_type: str,
556
- **kwargs,
557
- ) -> list[ContextEntity]:
558
- """
559
- List all latest version objects from backend.
560
-
561
- Parameters
562
- ----------
563
- project : str
564
- Project name.
565
- entity_type : str
566
- Entity type.
567
- **kwargs : dict
568
- Parameters to pass to the API call.
569
-
570
- Returns
571
- -------
572
- list[ContextEntity]
573
- List of object instances.
574
- """
575
- context = get_context_from_project(project)
576
- objs = self._list_context_entities(context, entity_type, **kwargs)
577
- objects = []
578
- for o in objs:
579
- entity: ContextEntity = factory.build_entity_from_dict(o)
580
- entity = self._post_process_get(entity)
581
- objects.append(entity)
582
- return objects
583
-
584
- def _update_material_entity(
585
- self,
586
- new_obj: MaterialEntity,
587
- ) -> dict:
588
- """
589
- Update material object shortcut.
590
-
591
- Parameters
592
- ----------
593
- new_obj : MaterialEntity
594
- Object instance.
595
-
596
- Returns
597
- -------
598
- dict
599
- Response from backend.
600
- """
601
- return self.update_context_entity(
602
- new_obj.project,
603
- new_obj.ENTITY_TYPE,
604
- new_obj.id,
605
- new_obj.to_dict(),
606
- )
607
-
608
- def _update_context_entity(
609
- self,
610
- context: Context,
611
- entity_type: str,
612
- entity_id: str,
613
- entity_dict: dict,
614
- **kwargs,
615
- ) -> dict:
616
- """
617
- Update object. Note that object spec are immutable.
618
-
619
- Parameters
620
- ----------
621
- context : Context
622
- Context instance.
623
- entity_type : str
624
- Entity type.
625
- entity_id : str
626
- Entity ID.
627
- entity_dict : dict
628
- Entity dictionary.
629
- **kwargs : dict
630
- Parameters to pass to the API call.
631
-
632
- Returns
633
- -------
634
- dict
635
- Response from backend.
636
- """
637
- api = context.client.build_api(
638
- ApiCategories.CONTEXT.value,
639
- BackendOperations.UPDATE.value,
640
- project=context.name,
641
- entity_type=entity_type,
642
- entity_id=entity_id,
643
- )
644
- return context.client.update_object(api, entity_dict, **kwargs)
645
-
646
- def update_context_entity(
647
- self,
648
- project: str,
649
- entity_type: str,
650
- entity_id: str,
651
- entity_dict: dict,
652
- **kwargs,
653
- ) -> ContextEntity:
654
- """
655
- Update object. Note that object spec are immutable.
656
-
657
- Parameters
658
- ----------
659
- project : str
660
- Project name.
661
- entity_type : str
662
- Entity type.
663
- entity_id : str
664
- Entity ID.
665
- entity_dict : dict
666
- Entity dictionary.
667
- **kwargs : dict
668
- Parameters to pass to the API call.
669
-
670
- Returns
671
- -------
672
- ContextEntity
673
- Object instance.
674
- """
675
- context = get_context_from_project(project)
676
- obj = self._update_context_entity(
677
- context,
678
- entity_type,
679
- entity_id,
680
- entity_dict,
681
- **kwargs,
682
- )
683
- return factory.build_entity_from_dict(obj)
684
-
685
- def _delete_context_entity(
686
- self,
687
- context: Context,
688
- identifier: str,
689
- entity_type: str | None = None,
690
- project: str | None = None,
691
- entity_id: str | None = None,
692
- **kwargs,
693
- ) -> dict:
694
- """
695
- Delete object from backend.
696
-
697
- Parameters
698
- ----------
699
- context : Context
700
- Context instance.
701
- identifier : str
702
- Entity key (store://...) or entity name.
703
- entity_type : str
704
- Entity type.
705
- project : str
706
- Project name.
707
- entity_id : str
708
- Entity ID.
709
- **kwargs : dict
710
- Parameters to pass to the API call.
711
-
712
- Returns
713
- -------
714
- dict
715
- Response from backend.
716
- """
717
- project, entity_type, _, entity_name, entity_id = parse_identifier(
718
- identifier,
719
- project=project,
720
- entity_type=entity_type,
721
- entity_id=entity_id,
722
- )
723
-
724
- delete_all_versions: bool = kwargs.pop("delete_all_versions", False)
725
- kwargs = context.client.build_parameters(
726
- ApiCategories.CONTEXT.value,
727
- BackendOperations.DELETE.value,
728
- entity_id=entity_id,
729
- entity_name=entity_name,
730
- cascade=kwargs.pop("cascade", None),
731
- delete_all_versions=delete_all_versions,
732
- **kwargs,
733
- )
734
-
735
- if delete_all_versions:
736
- api = context.client.build_api(
737
- ApiCategories.CONTEXT.value,
738
- BackendOperations.LIST.value,
739
- project=context.name,
740
- entity_type=entity_type,
741
- )
742
- else:
743
- api = context.client.build_api(
744
- ApiCategories.CONTEXT.value,
745
- BackendOperations.DELETE.value,
746
- project=context.name,
747
- entity_type=entity_type,
748
- entity_id=entity_id,
749
- )
750
- return context.client.delete_object(api, **kwargs)
751
-
752
- def delete_context_entity(
753
- self,
754
- identifier: str,
755
- project: str | None = None,
756
- entity_type: str | None = None,
757
- entity_id: str | None = None,
758
- **kwargs,
759
- ) -> dict:
760
- """
761
- Delete object from backend.
762
-
763
- Parameters
764
- ----------
765
- identifier : str
766
- Entity key (store://...) or entity name.
767
- project : str
768
- Project name.
769
- entity_type : str
770
- Entity type.
771
- entity_id : str
772
- Entity ID.
773
- **kwargs : dict
774
- Parameters to pass to the API call.
775
-
776
- Returns
777
- -------
778
- dict
779
- Response from backend.
780
- """
781
- context = get_context_from_identifier(identifier, project)
782
- return self._delete_context_entity(
783
- context,
784
- identifier,
785
- entity_type,
786
- context.name,
787
- entity_id,
788
- **kwargs,
789
- )
790
-
791
- def _post_process_get(self, entity: ContextEntity) -> ContextEntity:
792
- """
793
- Post process get (files, metrics).
794
-
795
- Parameters
796
- ----------
797
- entity : ContextEntity
798
- Entity to post process.
799
-
800
- Returns
801
- -------
802
- ContextEntity
803
- Post processed entity.
804
- """
805
- if hasattr(entity.status, "metrics"):
806
- entity._get_metrics()
807
- if hasattr(entity.status, "files"):
808
- entity._get_files_info()
809
- return entity
810
-
811
- ##############################
812
- # Context entity operations
813
- ##############################
814
-
815
- def _build_context_entity_key(
816
- self,
817
- context: Context,
818
- entity_type: str,
819
- entity_kind: str,
820
- entity_name: str,
821
- entity_id: str | None = None,
822
- ) -> str:
823
- """
824
- Build object key.
825
-
826
- Parameters
827
- ----------
828
- context : Context
829
- Context instance.
830
- entity_type : str
831
- Entity type.
832
- entity_kind : str
833
- Entity kind.
834
- entity_name : str
835
- Entity name.
836
- entity_id : str
837
- Entity ID.
838
-
839
- Returns
840
- -------
841
- str
842
- Object key.
843
- """
844
- return context.client.build_key(
845
- ApiCategories.CONTEXT.value,
846
- project=context.name,
847
- entity_type=entity_type,
848
- entity_kind=entity_kind,
849
- entity_name=entity_name,
850
- entity_id=entity_id,
851
- )
852
-
853
- def build_context_entity_key(
854
- self,
855
- project: str,
856
- entity_type: str,
857
- entity_kind: str,
858
- entity_name: str,
859
- entity_id: str | None = None,
860
- ) -> str:
861
- """
862
- Build object key.
863
-
864
- Parameters
865
- ----------
866
- project : str
867
- Project name.
868
- entity_type : str
869
- Entity type.
870
- entity_kind : str
871
- Entity kind.
872
- entity_name : str
873
- Entity name.
874
- entity_id : str
875
- Entity ID.
876
-
877
- Returns
878
- -------
879
- str
880
- Object key.
881
- """
882
- context = get_context_from_project(project)
883
- return self._build_context_entity_key(context, entity_type, entity_kind, entity_name, entity_id)
884
-
885
- def read_secret_data(
886
- self,
887
- project: str,
888
- entity_type: str,
889
- **kwargs,
890
- ) -> dict:
891
- """
892
- Get data from backend.
893
-
894
- Parameters
895
- ----------
896
- project : str
897
- Project name.
898
- entity_type : str
899
- Entity type.
900
- **kwargs : dict
901
- Parameters to pass to the API call.
902
-
903
- Returns
904
- -------
905
- dict
906
- Response from backend.
907
- """
908
- context = get_context_from_project(project)
909
- api = context.client.build_api(
910
- ApiCategories.CONTEXT.value,
911
- BackendOperations.DATA.value,
912
- project=context.name,
913
- entity_type=entity_type,
914
- )
915
- return context.client.read_object(api, **kwargs)
916
-
917
- def update_secret_data(
918
- self,
919
- project: str,
920
- entity_type: str,
921
- data: dict,
922
- **kwargs,
923
- ) -> None:
924
- """
925
- Set data in backend.
926
-
927
- Parameters
928
- ----------
929
- project : str
930
- Project name.
931
- entity_type : str
932
- Entity type.
933
- data : dict
934
- Data dictionary.
935
- **kwargs : dict
936
- Parameters to pass to the API call.
937
-
938
- Returns
939
- -------
940
- None
941
- """
942
- context = get_context_from_project(project)
943
- api = context.client.build_api(
944
- ApiCategories.CONTEXT.value,
945
- BackendOperations.DATA.value,
946
- project=context.name,
947
- entity_type=entity_type,
948
- )
949
- context.client.update_object(api, data, **kwargs)
950
-
951
- def read_run_logs(
952
- self,
953
- project: str,
954
- entity_type: str,
955
- entity_id: str,
956
- **kwargs,
957
- ) -> dict:
958
- """
959
- Get logs from backend.
960
-
961
- Parameters
962
- ----------
963
- project : str
964
- Project name.
965
- entity_type : str
966
- Entity type.
967
- entity_id : str
968
- Entity ID.
969
- **kwargs : dict
970
- Parameters to pass to the API call.
971
-
972
- Returns
973
- -------
974
- dict
975
- Response from backend.
976
- """
977
- context = get_context_from_project(project)
978
- api = context.client.build_api(
979
- ApiCategories.CONTEXT.value,
980
- BackendOperations.LOGS.value,
981
- project=context.name,
982
- entity_type=entity_type,
983
- entity_id=entity_id,
984
- )
985
- return context.client.read_object(api, **kwargs)
986
-
987
- def stop_entity(
988
- self,
989
- project: str,
990
- entity_type: str,
991
- entity_id: str,
992
- **kwargs,
993
- ) -> None:
994
- """
995
- Stop object in backend.
996
-
997
- Parameters
998
- ----------
999
- project : str
1000
- Project name.
1001
- entity_type : str
1002
- Entity type.
1003
- entity_id : str
1004
- Entity ID.
1005
- **kwargs : dict
1006
- Parameters to pass to the API call.
1007
-
1008
- Returns
1009
- -------
1010
- None
1011
- """
1012
- context = get_context_from_project(project)
1013
- api = context.client.build_api(
1014
- ApiCategories.CONTEXT.value,
1015
- BackendOperations.STOP.value,
1016
- project=context.name,
1017
- entity_type=entity_type,
1018
- entity_id=entity_id,
1019
- )
1020
- context.client.create_object(api, **kwargs)
1021
-
1022
- def resume_entity(
1023
- self,
1024
- project: str,
1025
- entity_type: str,
1026
- entity_id: str,
1027
- **kwargs,
1028
- ) -> None:
1029
- """
1030
- Resume object in backend.
1031
-
1032
- Parameters
1033
- ----------
1034
- project : str
1035
- Project name.
1036
- entity_type : str
1037
- Entity type.
1038
- entity_id : str
1039
- Entity ID.
1040
- **kwargs : dict
1041
- Parameters to pass to the API call.
1042
-
1043
- Returns
1044
- -------
1045
- None
1046
- """
1047
- context = get_context_from_project(project)
1048
- api = context.client.build_api(
1049
- ApiCategories.CONTEXT.value,
1050
- BackendOperations.RESUME.value,
1051
- project=context.name,
1052
- entity_type=entity_type,
1053
- entity_id=entity_id,
1054
- )
1055
- context.client.create_object(api, **kwargs)
1056
-
1057
- def read_files_info(
1058
- self,
1059
- project: str,
1060
- entity_type: str,
1061
- entity_id: str,
1062
- **kwargs,
1063
- ) -> list[dict]:
1064
- """
1065
- Get files info from backend.
1066
-
1067
- Parameters
1068
- ----------
1069
- project : str
1070
- Project name.
1071
- entity_type : str
1072
- Entity type.
1073
- entity_id : str
1074
- Entity ID.
1075
- **kwargs : dict
1076
- Parameters to pass to the API call.
1077
-
1078
- Returns
1079
- -------
1080
- list[dict]
1081
- Response from backend.
1082
- """
1083
- context = get_context_from_project(project)
1084
- api = context.client.build_api(
1085
- ApiCategories.CONTEXT.value,
1086
- BackendOperations.FILES.value,
1087
- project=context.name,
1088
- entity_type=entity_type,
1089
- entity_id=entity_id,
1090
- )
1091
- return context.client.read_object(api, **kwargs)
1092
-
1093
- def update_files_info(
1094
- self,
1095
- project: str,
1096
- entity_type: str,
1097
- entity_id: str,
1098
- entity_list: list[dict],
1099
- **kwargs,
1100
- ) -> None:
1101
- """
1102
- Get files info from backend.
1103
-
1104
- Parameters
1105
- ----------
1106
- project : str
1107
- Project name.
1108
- entity_type : str
1109
- Entity type.
1110
- entity_id : str
1111
- Entity ID.
1112
- entity_list : list[dict]
1113
- Entity list.
1114
- **kwargs : dict
1115
- Parameters to pass to the API call.
1116
-
1117
- Returns
1118
- -------
1119
- None
1120
- """
1121
- context = get_context_from_project(project)
1122
- api = context.client.build_api(
1123
- ApiCategories.CONTEXT.value,
1124
- BackendOperations.FILES.value,
1125
- project=context.name,
1126
- entity_type=entity_type,
1127
- entity_id=entity_id,
1128
- )
1129
- return context.client.update_object(api, entity_list, **kwargs)
1130
-
1131
- def read_metrics(
1132
- self,
1133
- project: str,
1134
- entity_type: str,
1135
- entity_id: str,
1136
- metric_name: str | None = None,
1137
- **kwargs,
1138
- ) -> dict:
1139
- """
1140
- Get metrics from backend.
1141
-
1142
- Parameters
1143
- ----------
1144
- project : str
1145
- Project name.
1146
- entity_type : str
1147
- Entity type.
1148
- entity_id : str
1149
- Entity ID.
1150
- **kwargs : dict
1151
- Parameters to pass to the API call.
1152
-
1153
- Returns
1154
- -------
1155
- dict
1156
- Response from backend.
1157
- """
1158
- context = get_context_from_project(project)
1159
- api = context.client.build_api(
1160
- ApiCategories.CONTEXT.value,
1161
- BackendOperations.METRICS.value,
1162
- project=context.name,
1163
- entity_type=entity_type,
1164
- entity_id=entity_id,
1165
- metric_name=metric_name,
1166
- )
1167
- return context.client.read_object(api, **kwargs)
1168
-
1169
- def update_metric(
1170
- self,
1171
- project: str,
1172
- entity_type: str,
1173
- entity_id: str,
1174
- metric_name: str,
1175
- metric_value: Any,
1176
- **kwargs,
1177
- ) -> None:
1178
- """
1179
- Get single metric from backend.
1180
-
1181
- Parameters
1182
- ----------
1183
- project : str
1184
- Project name.
1185
- entity_type : str
1186
- Entity type.
1187
- entity_id : str
1188
- Entity ID.
1189
- **kwargs : dict
1190
- Parameters to pass to the API call.
1191
-
1192
- Returns
1193
- -------
1194
- None
1195
- """
1196
- context = get_context_from_project(project)
1197
- api = context.client.build_api(
1198
- ApiCategories.CONTEXT.value,
1199
- BackendOperations.METRICS.value,
1200
- project=context.name,
1201
- entity_type=entity_type,
1202
- entity_id=entity_id,
1203
- metric_name=metric_name,
1204
- )
1205
- context.client.update_object(api, metric_value, **kwargs)
1206
-
1207
- def _search(
1208
- self,
1209
- context: Context,
1210
- **kwargs,
1211
- ) -> dict:
1212
- """
1213
- Search in backend.
1214
-
1215
- Parameters
1216
- ----------
1217
- context : Context
1218
- Context instance.
1219
- **kwargs : dict
1220
- Parameters to pass to the API call.
1221
-
1222
- Returns
1223
- -------
1224
- dict
1225
- Response from backend.
1226
- """
1227
- kwargs = context.client.build_parameters(
1228
- ApiCategories.CONTEXT.value,
1229
- BackendOperations.SEARCH.value,
1230
- **kwargs,
1231
- )
1232
- api = context.client.build_api(
1233
- ApiCategories.CONTEXT.value,
1234
- BackendOperations.SEARCH.value,
1235
- project=context.name,
1236
- )
1237
- entities_dict = context.client.read_object(api, **kwargs)
1238
- return [self.read_context_entity(entity["key"]) for entity in entities_dict["content"]]
1239
-
1240
- def search_entity(
1241
- self,
1242
- project: str,
1243
- query: str | None = None,
1244
- entity_types: list[str] | None = None,
1245
- name: str | None = None,
1246
- kind: str | None = None,
1247
- created: str | None = None,
1248
- updated: str | None = None,
1249
- description: str | None = None,
1250
- labels: list[str] | None = None,
1251
- **kwargs,
1252
- ) -> list[ContextEntity]:
1253
- """
1254
- Search objects from backend.
1255
-
1256
- Parameters
1257
- ----------
1258
- project : str
1259
- Project name.
1260
- query : str
1261
- Search query.
1262
- entity_types : list[str]
1263
- Entity types.
1264
- name : str
1265
- Entity name.
1266
- kind : str
1267
- Entity kind.
1268
- created : str
1269
- Entity creation date.
1270
- updated : str
1271
- Entity update date.
1272
- description : str
1273
- Entity description.
1274
- labels : list[str]
1275
- Entity labels.
1276
- **kwargs : dict
1277
- Parameters to pass to the API call.
1278
-
1279
- Returns
1280
- -------
1281
- list[ContextEntity]
1282
- List of object instances.
1283
- """
1284
- context = get_context_from_project(project)
1285
- return self._search(
1286
- context,
1287
- query=query,
1288
- entity_types=entity_types,
1289
- name=name,
1290
- kind=kind,
1291
- created=created,
1292
- updated=updated,
1293
- description=description,
1294
- labels=labels,
1295
- **kwargs,
1296
- )
1297
-
1298
-
1299
- context_processor = ContextEntityOperationsProcessor()