digitalhub 0.13.3__py3-none-any.whl → 0.14.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of digitalhub might be problematic. Click here for more details.

Files changed (116) hide show
  1. digitalhub/__init__.py +3 -8
  2. digitalhub/context/api.py +1 -5
  3. digitalhub/context/builder.py +1 -5
  4. digitalhub/context/context.py +15 -9
  5. digitalhub/entities/_base/_base/entity.py +0 -15
  6. digitalhub/entities/_base/context/entity.py +1 -1
  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 +169 -79
  10. digitalhub/entities/_base/material/entity.py +6 -22
  11. digitalhub/entities/_base/material/utils.py +1 -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/utils.py +83 -21
  17. digitalhub/entities/_constructors/_resources.py +151 -0
  18. digitalhub/entities/{_base/entity/_constructors → _constructors}/name.py +18 -0
  19. digitalhub/entities/_processors/base/__init__.py +3 -0
  20. digitalhub/entities/_processors/{base.py → base/crud.py} +14 -226
  21. digitalhub/entities/_processors/base/import_export.py +123 -0
  22. digitalhub/entities/_processors/base/processor.py +302 -0
  23. digitalhub/entities/_processors/base/special_ops.py +108 -0
  24. digitalhub/entities/_processors/context/__init__.py +3 -0
  25. digitalhub/entities/_processors/context/crud.py +652 -0
  26. digitalhub/entities/_processors/context/import_export.py +242 -0
  27. digitalhub/entities/_processors/context/material.py +123 -0
  28. digitalhub/entities/_processors/context/processor.py +400 -0
  29. digitalhub/entities/_processors/context/special_ops.py +476 -0
  30. digitalhub/entities/_processors/processors.py +12 -0
  31. digitalhub/entities/_processors/utils.py +12 -11
  32. digitalhub/entities/artifact/crud.py +58 -22
  33. digitalhub/entities/artifact/utils.py +3 -3
  34. digitalhub/entities/dataitem/crud.py +63 -20
  35. digitalhub/entities/dataitem/table/entity.py +24 -22
  36. digitalhub/entities/dataitem/utils.py +15 -15
  37. digitalhub/entities/function/_base/entity.py +3 -3
  38. digitalhub/entities/function/crud.py +55 -24
  39. digitalhub/entities/model/_base/entity.py +62 -20
  40. digitalhub/entities/model/crud.py +58 -22
  41. digitalhub/entities/model/utils.py +3 -3
  42. digitalhub/entities/project/_base/entity.py +321 -152
  43. digitalhub/entities/project/crud.py +15 -23
  44. digitalhub/entities/run/_base/builder.py +0 -4
  45. digitalhub/entities/run/_base/entity.py +70 -63
  46. digitalhub/entities/run/crud.py +79 -26
  47. digitalhub/entities/secret/_base/entity.py +1 -5
  48. digitalhub/entities/secret/crud.py +29 -26
  49. digitalhub/entities/task/_base/builder.py +0 -4
  50. digitalhub/entities/task/_base/entity.py +5 -5
  51. digitalhub/entities/task/_base/models.py +13 -16
  52. digitalhub/entities/task/crud.py +61 -29
  53. digitalhub/entities/trigger/_base/entity.py +1 -5
  54. digitalhub/entities/trigger/crud.py +64 -24
  55. digitalhub/entities/workflow/_base/entity.py +3 -3
  56. digitalhub/entities/workflow/crud.py +55 -21
  57. digitalhub/factory/entity.py +283 -0
  58. digitalhub/factory/enums.py +18 -0
  59. digitalhub/factory/registry.py +197 -0
  60. digitalhub/factory/runtime.py +44 -0
  61. digitalhub/factory/utils.py +3 -54
  62. digitalhub/runtimes/_base.py +2 -2
  63. digitalhub/stores/client/_base/enums.py +39 -0
  64. digitalhub/stores/client/_base/key_builder.py +2 -2
  65. digitalhub/stores/client/_base/params_builder.py +48 -0
  66. digitalhub/stores/client/api.py +6 -10
  67. digitalhub/stores/client/builder.py +4 -4
  68. digitalhub/stores/client/dhcore/api_builder.py +2 -1
  69. digitalhub/stores/client/dhcore/client.py +85 -429
  70. digitalhub/stores/client/dhcore/configurator.py +109 -328
  71. digitalhub/stores/client/dhcore/enums.py +0 -16
  72. digitalhub/stores/client/dhcore/error_parser.py +0 -4
  73. digitalhub/stores/client/dhcore/header_manager.py +61 -0
  74. digitalhub/stores/client/dhcore/http_handler.py +133 -0
  75. digitalhub/stores/client/dhcore/params_builder.py +147 -134
  76. digitalhub/stores/client/dhcore/response_processor.py +102 -0
  77. digitalhub/stores/client/dhcore/utils.py +6 -72
  78. digitalhub/stores/client/local/api_builder.py +1 -1
  79. digitalhub/stores/client/local/client.py +79 -47
  80. digitalhub/stores/client/local/params_builder.py +18 -41
  81. digitalhub/stores/credentials/api.py +0 -4
  82. digitalhub/stores/credentials/configurator.py +2 -28
  83. digitalhub/stores/credentials/enums.py +3 -0
  84. digitalhub/stores/credentials/handler.py +0 -12
  85. digitalhub/stores/credentials/ini_module.py +0 -22
  86. digitalhub/stores/credentials/store.py +0 -4
  87. digitalhub/stores/data/_base/store.py +0 -16
  88. digitalhub/stores/data/builder.py +1 -5
  89. digitalhub/stores/data/local/store.py +0 -103
  90. digitalhub/stores/data/remote/store.py +0 -4
  91. digitalhub/stores/data/s3/configurator.py +60 -14
  92. digitalhub/stores/data/s3/store.py +49 -16
  93. digitalhub/stores/data/sql/configurator.py +0 -8
  94. digitalhub/stores/data/sql/store.py +21 -10
  95. digitalhub/stores/readers/data/factory.py +0 -8
  96. digitalhub/stores/readers/data/pandas/reader.py +0 -16
  97. digitalhub/utils/file_utils.py +0 -17
  98. digitalhub/utils/generic_utils.py +0 -12
  99. digitalhub/utils/git_utils.py +0 -8
  100. digitalhub/utils/io_utils.py +0 -12
  101. digitalhub/utils/store_utils.py +44 -0
  102. {digitalhub-0.13.3.dist-info → digitalhub-0.14.0.dist-info}/METADATA +3 -2
  103. {digitalhub-0.13.3.dist-info → digitalhub-0.14.0.dist-info}/RECORD +111 -95
  104. digitalhub/entities/_processors/context.py +0 -1450
  105. digitalhub/entities/task/_base/utils.py +0 -22
  106. digitalhub/factory/factory.py +0 -381
  107. digitalhub/stores/client/dhcore/models.py +0 -40
  108. digitalhub/stores/data/s3/utils.py +0 -78
  109. /digitalhub/entities/{_base/entity/_constructors → _constructors}/__init__.py +0 -0
  110. /digitalhub/entities/{_base/entity/_constructors → _constructors}/metadata.py +0 -0
  111. /digitalhub/entities/{_base/entity/_constructors → _constructors}/spec.py +0 -0
  112. /digitalhub/entities/{_base/entity/_constructors → _constructors}/status.py +0 -0
  113. /digitalhub/entities/{_base/entity/_constructors → _constructors}/uuid.py +0 -0
  114. {digitalhub-0.13.3.dist-info → digitalhub-0.14.0.dist-info}/WHEEL +0 -0
  115. {digitalhub-0.13.3.dist-info → digitalhub-0.14.0.dist-info}/licenses/AUTHORS +0 -0
  116. {digitalhub-0.13.3.dist-info → digitalhub-0.14.0.dist-info}/licenses/LICENSE +0 -0
@@ -7,31 +7,23 @@ from __future__ import annotations
7
7
  import typing
8
8
 
9
9
  from digitalhub.context.api import delete_context
10
- from digitalhub.entities._commons.enums import ApiCategories, BackendOperations
11
- from digitalhub.factory.factory import factory
10
+ from digitalhub.factory.entity import entity_factory
11
+ from digitalhub.stores.client._base.enums import ApiCategories, BackendOperations
12
12
  from digitalhub.stores.client.api import get_client
13
- from digitalhub.utils.exceptions import EntityAlreadyExistsError, EntityError, EntityNotExistsError
14
- from digitalhub.utils.io_utils import read_yaml
15
13
 
16
14
  if typing.TYPE_CHECKING:
17
15
  from digitalhub.entities.project._base.entity import Project
18
16
  from digitalhub.stores.client._base.client import Client
19
17
 
20
18
 
21
- class BaseEntityOperationsProcessor:
19
+ class BaseEntityCRUDProcessor:
22
20
  """
23
- Processor for base entity operations.
21
+ Processor for core CRUD operations on base entities.
24
22
 
25
- This class handles CRUD operations and other entity management tasks
26
- for base-level entities (primarily projects). It interacts with the
27
- client layer to perform backend operations and manages entity lifecycle
28
- including creation, reading, updating, deletion, and sharing.
23
+ Handles creation, reading, updating, deletion, and listing of
24
+ base-level entities (primarily projects) within the backend.
29
25
  """
30
26
 
31
- ##############################
32
- # CRUD base entity
33
- ##############################
34
-
35
27
  def _create_base_entity(
36
28
  self,
37
29
  client: Client,
@@ -82,7 +74,7 @@ class BaseEntityOperationsProcessor:
82
74
 
83
75
  Parameters
84
76
  ----------
85
- _entity : Project, optional
77
+ _entity : Project
86
78
  An existing project entity object to create. If None,
87
79
  a new entity will be built from kwargs.
88
80
  **kwargs : dict
@@ -99,10 +91,10 @@ class BaseEntityOperationsProcessor:
99
91
  obj = _entity
100
92
  else:
101
93
  client = get_client(kwargs.get("local"))
102
- obj = factory.build_entity_from_params(**kwargs)
94
+ obj = entity_factory.build_entity_from_params(**kwargs)
103
95
  ent = self._create_base_entity(client, obj.ENTITY_TYPE, obj.to_dict())
104
96
  ent["local"] = client.is_local()
105
- return factory.build_entity_from_dict(ent)
97
+ return entity_factory.build_entity_from_dict(ent)
106
98
 
107
99
  def _read_base_entity(
108
100
  self,
@@ -171,91 +163,7 @@ class BaseEntityOperationsProcessor:
171
163
  client = get_client(kwargs.pop("local", False))
172
164
  obj = self._read_base_entity(client, entity_type, entity_name, **kwargs)
173
165
  obj["local"] = client.is_local()
174
- return factory.build_entity_from_dict(obj)
175
-
176
- def import_project_entity(
177
- self,
178
- file: str,
179
- **kwargs,
180
- ) -> Project:
181
- """
182
- Import a project entity from a YAML file and create it in the backend.
183
-
184
- Reads project configuration from a YAML file, creates a new project
185
- entity in the backend, and imports any related entities defined
186
- in the file. Raises an error if the project already exists.
187
-
188
- Parameters
189
- ----------
190
- file : str
191
- Path to the YAML file containing project configuration.
192
- **kwargs : dict
193
- Additional parameters including 'local' flag.
194
-
195
- Returns
196
- -------
197
- Project
198
- The imported and created project entity.
199
-
200
- Raises
201
- ------
202
- EntityError
203
- If the project already exists in the backend.
204
- """
205
- client = get_client(kwargs.pop("local", False))
206
- obj: dict = read_yaml(file)
207
- obj["status"] = {}
208
- obj["local"] = client.is_local()
209
- ent: Project = factory.build_entity_from_dict(obj)
210
-
211
- try:
212
- self._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
213
- except EntityAlreadyExistsError:
214
- raise EntityError(f"Entity {ent.name} already exists. If you want to update it, use load instead.")
215
-
216
- # Import related entities
217
- ent._import_entities(obj)
218
- ent.refresh()
219
- return ent
220
-
221
- def load_project_entity(
222
- self,
223
- file: str,
224
- **kwargs,
225
- ) -> Project:
226
- """
227
- Load a project entity from a YAML file and update it in the backend.
228
-
229
- Reads project configuration from a YAML file and updates an existing
230
- project in the backend. If the project doesn't exist, it creates a
231
- new one. Also loads any related entities defined in the file.
232
-
233
- Parameters
234
- ----------
235
- file : str
236
- Path to the YAML file containing project configuration.
237
- **kwargs : dict
238
- Additional parameters including 'local' flag.
239
-
240
- Returns
241
- -------
242
- Project
243
- The loaded and updated project entity.
244
- """
245
- client = get_client(kwargs.pop("local", False))
246
- obj: dict = read_yaml(file)
247
- obj["local"] = client.is_local()
248
- ent: Project = factory.build_entity_from_dict(obj)
249
-
250
- try:
251
- self._update_base_entity(ent._client, ent.ENTITY_TYPE, ent.name, ent.to_dict())
252
- except EntityNotExistsError:
253
- self._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
254
-
255
- # Load related entities
256
- ent._load_entities(obj)
257
- ent.refresh()
258
- return ent
166
+ return entity_factory.build_entity_from_dict(obj)
259
167
 
260
168
  def _list_base_entities(
261
169
  self,
@@ -320,7 +228,7 @@ class BaseEntityOperationsProcessor:
320
228
  entities = []
321
229
  for obj in objs:
322
230
  obj["local"] = client.is_local()
323
- ent = factory.build_entity_from_dict(obj)
231
+ ent = entity_factory.build_entity_from_dict(obj)
324
232
  entities.append(ent)
325
233
  return entities
326
234
 
@@ -397,7 +305,7 @@ class BaseEntityOperationsProcessor:
397
305
  client = get_client(kwargs.pop("local", False))
398
306
  obj = self._update_base_entity(client, entity_type, entity_name, entity_dict, **kwargs)
399
307
  obj["local"] = client.is_local()
400
- return factory.build_entity_from_dict(obj)
308
+ return entity_factory.build_entity_from_dict(obj)
401
309
 
402
310
  def _delete_base_entity(
403
311
  self,
@@ -456,6 +364,8 @@ class BaseEntityOperationsProcessor:
456
364
 
457
365
  Parameters
458
366
  ----------
367
+ crud_processor : BaseEntityCRUDProcessor
368
+ The CRUD processor instance for entity operations.
459
369
  entity_type : str
460
370
  The type of entity to delete (typically 'project').
461
371
  entity_name : str
@@ -478,125 +388,3 @@ class BaseEntityOperationsProcessor:
478
388
  entity_name,
479
389
  **kwargs,
480
390
  )
481
-
482
- ##############################
483
- # Base entity operations
484
- ##############################
485
-
486
- def _build_base_entity_key(
487
- self,
488
- client: Client,
489
- entity_id: str,
490
- ) -> str:
491
- """
492
- Build a storage key for a base entity.
493
-
494
- Creates a standardized key string that can be used to identify
495
- and store the entity in various contexts.
496
-
497
- Parameters
498
- ----------
499
- client : Client
500
- The client instance to use for key building.
501
- entity_id : str
502
- The unique identifier of the entity.
503
-
504
- Returns
505
- -------
506
- str
507
- The constructed entity key string.
508
- """
509
- return client.build_key(ApiCategories.BASE.value, entity_id)
510
-
511
- def build_project_key(
512
- self,
513
- entity_id: str,
514
- **kwargs,
515
- ) -> str:
516
- """
517
- Build a storage key for a project entity.
518
-
519
- Creates a standardized key string for project identification
520
- and storage, handling both local and remote client contexts.
521
-
522
- Parameters
523
- ----------
524
- entity_id : str
525
- The unique identifier of the project entity.
526
- **kwargs : dict
527
- Additional parameters including 'local' flag.
528
-
529
- Returns
530
- -------
531
- str
532
- The constructed project entity key string.
533
- """
534
- client = get_client(kwargs.pop("local", False))
535
- return self._build_base_entity_key(client, entity_id)
536
-
537
- def share_project_entity(
538
- self,
539
- entity_type: str,
540
- entity_name: str,
541
- **kwargs,
542
- ) -> None:
543
- """
544
- Share or unshare a project entity with a user.
545
-
546
- Manages project access permissions by sharing the project with
547
- a specified user or removing user access. Handles both sharing
548
- and unsharing operations based on the 'unshare' parameter.
549
-
550
- Parameters
551
- ----------
552
- entity_type : str
553
- The type of entity to share (typically 'project').
554
- entity_name : str
555
- The name identifier of the project to share.
556
- **kwargs : dict
557
- Additional parameters including:
558
- - 'user': username to share with/unshare from
559
- - 'unshare': boolean flag for unsharing (default False)
560
- - 'local': boolean flag for local backend
561
-
562
- Returns
563
- -------
564
- None
565
-
566
- Raises
567
- ------
568
- ValueError
569
- If trying to unshare from a user who doesn't have access.
570
- """
571
- client = get_client(kwargs.pop("local", False))
572
- api = client.build_api(
573
- ApiCategories.BASE.value,
574
- BackendOperations.SHARE.value,
575
- entity_type=entity_type,
576
- entity_name=entity_name,
577
- )
578
-
579
- user = kwargs.pop("user", None)
580
- if unshare := kwargs.pop("unshare", False):
581
- users = client.read_object(api, **kwargs)
582
- for u in users:
583
- if u["user"] == user:
584
- kwargs["id"] = u["id"]
585
- break
586
- else:
587
- raise ValueError(f"User '{user}' does not have access to project.")
588
-
589
- kwargs = client.build_parameters(
590
- ApiCategories.BASE.value,
591
- BackendOperations.SHARE.value,
592
- unshare=unshare,
593
- user=user,
594
- **kwargs,
595
- )
596
- if unshare:
597
- client.delete_object(api, **kwargs)
598
- return
599
- client.create_object(api, obj={}, **kwargs)
600
-
601
-
602
- base_processor = BaseEntityOperationsProcessor()
@@ -0,0 +1,123 @@
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.stores.client.api import get_client
12
+ from digitalhub.utils.exceptions import EntityAlreadyExistsError, EntityError, EntityNotExistsError
13
+ from digitalhub.utils.io_utils import read_yaml
14
+
15
+ if typing.TYPE_CHECKING:
16
+ from digitalhub.entities._processors.base.crud import BaseEntityCRUDProcessor
17
+ from digitalhub.entities.project._base.entity import Project
18
+
19
+
20
+ class BaseEntityImportExportProcessor:
21
+ """
22
+ Processor for import and export operations on base entities.
23
+
24
+ Handles loading entities from YAML files and importing/exporting
25
+ entity configurations between local files and the backend.
26
+ """
27
+
28
+ def import_project_entity(
29
+ self,
30
+ crud_processor: BaseEntityCRUDProcessor,
31
+ file: str,
32
+ **kwargs,
33
+ ) -> Project:
34
+ """
35
+ Import a project entity from a YAML file and create it in the backend.
36
+
37
+ Reads project configuration from a YAML file, creates a new project
38
+ entity in the backend, and imports any related entities defined
39
+ in the file. Raises an error if the project already exists.
40
+
41
+ Parameters
42
+ ----------
43
+ crud_processor : BaseEntityCRUDProcessor
44
+ The CRUD processor instance for entity operations.
45
+ file : str
46
+ Path to the YAML file containing project configuration.
47
+ **kwargs : dict
48
+ Additional parameters including 'local' and 'reset_id' flags.
49
+
50
+ Returns
51
+ -------
52
+ Project
53
+ The imported and created project entity.
54
+
55
+ Raises
56
+ ------
57
+ EntityError
58
+ If the project already exists in the backend.
59
+ """
60
+ client = get_client(kwargs.pop("local", False))
61
+ obj: dict = read_yaml(file)
62
+ obj["status"] = {}
63
+ obj["local"] = client.is_local()
64
+ ent: Project = entity_factory.build_entity_from_dict(obj)
65
+ reset_id = kwargs.pop("reset_id", False)
66
+
67
+ try:
68
+ crud_processor._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
69
+ except EntityAlreadyExistsError:
70
+ msg = f"Entity {ent.name} already exists."
71
+ if reset_id:
72
+ ent._import_entities(obj, reset_id=reset_id)
73
+ warn(f"{msg} Other entities ids have been imported.")
74
+ ent.refresh()
75
+ return ent
76
+ raise EntityError(f"{msg} If you want to update it, use load instead.")
77
+
78
+ # Import related entities
79
+ ent._import_entities(obj, reset_id=reset_id)
80
+ ent.refresh()
81
+ return ent
82
+
83
+ def load_project_entity(
84
+ self,
85
+ crud_processor: BaseEntityCRUDProcessor,
86
+ file: str,
87
+ **kwargs,
88
+ ) -> Project:
89
+ """
90
+ Load a project entity from a YAML file and update it in the backend.
91
+
92
+ Reads project configuration from a YAML file and updates an existing
93
+ project in the backend. If the project doesn't exist, it creates a
94
+ new one. Also loads any related entities defined in the file.
95
+
96
+ Parameters
97
+ ----------
98
+ crud_processor : BaseEntityCRUDProcessor
99
+ The CRUD processor instance for entity operations.
100
+ file : str
101
+ Path to the YAML file containing project configuration.
102
+ **kwargs : dict
103
+ Additional parameters including 'local' flag.
104
+
105
+ Returns
106
+ -------
107
+ Project
108
+ The loaded and updated project entity.
109
+ """
110
+ client = get_client(kwargs.pop("local", False))
111
+ obj: dict = read_yaml(file)
112
+ obj["local"] = client.is_local()
113
+ ent: Project = entity_factory.build_entity_from_dict(obj)
114
+
115
+ try:
116
+ crud_processor._update_base_entity(ent._client, ent.ENTITY_TYPE, ent.name, ent.to_dict())
117
+ except EntityNotExistsError:
118
+ crud_processor._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
119
+
120
+ # Load related entities
121
+ ent._load_entities(obj)
122
+ ent.refresh()
123
+ return ent