digitalhub 0.14.0b1__py3-none-any.whl → 0.14.0b3__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 (71) hide show
  1. digitalhub/context/builder.py +0 -4
  2. digitalhub/context/context.py +12 -8
  3. digitalhub/entities/_base/_base/entity.py +0 -4
  4. digitalhub/entities/_base/context/entity.py +1 -1
  5. digitalhub/entities/_base/entity/entity.py +0 -8
  6. digitalhub/entities/_base/executable/entity.py +9 -21
  7. digitalhub/entities/_base/material/entity.py +5 -21
  8. digitalhub/entities/_base/unversioned/entity.py +1 -1
  9. digitalhub/entities/_base/versioned/entity.py +1 -1
  10. digitalhub/entities/_processors/base/__init__.py +3 -0
  11. digitalhub/entities/_processors/{base.py → base/crud.py} +12 -232
  12. digitalhub/entities/_processors/base/import_export.py +122 -0
  13. digitalhub/entities/_processors/base/processor.py +302 -0
  14. digitalhub/entities/_processors/base/special_ops.py +108 -0
  15. digitalhub/entities/_processors/context/__init__.py +3 -0
  16. digitalhub/entities/_processors/context/crud.py +654 -0
  17. digitalhub/entities/_processors/context/import_export.py +242 -0
  18. digitalhub/entities/_processors/context/material.py +123 -0
  19. digitalhub/entities/_processors/context/processor.py +400 -0
  20. digitalhub/entities/_processors/context/special_ops.py +476 -0
  21. digitalhub/entities/_processors/processors.py +12 -0
  22. digitalhub/entities/_processors/utils.py +2 -2
  23. digitalhub/entities/artifact/crud.py +1 -1
  24. digitalhub/entities/dataitem/crud.py +6 -3
  25. digitalhub/entities/dataitem/table/entity.py +24 -1
  26. digitalhub/entities/dataitem/utils.py +4 -0
  27. digitalhub/entities/function/_base/entity.py +3 -3
  28. digitalhub/entities/function/crud.py +1 -1
  29. digitalhub/entities/model/_base/entity.py +46 -24
  30. digitalhub/entities/model/crud.py +1 -1
  31. digitalhub/entities/project/_base/entity.py +3 -12
  32. digitalhub/entities/project/crud.py +1 -2
  33. digitalhub/entities/run/_base/builder.py +0 -4
  34. digitalhub/entities/run/_base/entity.py +53 -66
  35. digitalhub/entities/run/crud.py +5 -2
  36. digitalhub/entities/secret/_base/entity.py +1 -5
  37. digitalhub/entities/secret/crud.py +1 -1
  38. digitalhub/entities/task/_base/builder.py +0 -4
  39. digitalhub/entities/task/_base/entity.py +5 -5
  40. digitalhub/entities/task/crud.py +1 -1
  41. digitalhub/entities/trigger/_base/entity.py +1 -5
  42. digitalhub/entities/trigger/crud.py +1 -1
  43. digitalhub/entities/workflow/_base/entity.py +3 -3
  44. digitalhub/entities/workflow/crud.py +1 -1
  45. digitalhub/factory/entity.py +283 -0
  46. digitalhub/factory/registry.py +197 -0
  47. digitalhub/factory/runtime.py +44 -0
  48. digitalhub/runtimes/_base.py +2 -2
  49. digitalhub/stores/client/dhcore/client.py +0 -14
  50. digitalhub/stores/client/dhcore/configurator.py +5 -28
  51. digitalhub/stores/client/dhcore/error_parser.py +0 -4
  52. digitalhub/stores/credentials/configurator.py +4 -29
  53. digitalhub/stores/credentials/handler.py +0 -12
  54. digitalhub/stores/credentials/store.py +0 -4
  55. digitalhub/stores/data/_base/store.py +0 -16
  56. digitalhub/stores/data/builder.py +0 -4
  57. digitalhub/stores/data/remote/store.py +0 -4
  58. digitalhub/stores/data/s3/configurator.py +2 -10
  59. digitalhub/stores/data/s3/store.py +0 -12
  60. digitalhub/stores/data/sql/configurator.py +0 -8
  61. digitalhub/stores/data/sql/store.py +0 -4
  62. digitalhub/stores/readers/data/factory.py +0 -8
  63. digitalhub/stores/readers/data/pandas/reader.py +9 -19
  64. digitalhub/utils/io_utils.py +0 -4
  65. {digitalhub-0.14.0b1.dist-info → digitalhub-0.14.0b3.dist-info}/METADATA +1 -1
  66. {digitalhub-0.14.0b1.dist-info → digitalhub-0.14.0b3.dist-info}/RECORD +69 -57
  67. digitalhub/entities/_processors/context.py +0 -1499
  68. digitalhub/factory/factory.py +0 -460
  69. {digitalhub-0.14.0b1.dist-info → digitalhub-0.14.0b3.dist-info}/WHEEL +0 -0
  70. {digitalhub-0.14.0b1.dist-info → digitalhub-0.14.0b3.dist-info}/licenses/AUTHORS +0 -0
  71. {digitalhub-0.14.0b1.dist-info → digitalhub-0.14.0b3.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,122 @@
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.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,
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
+ client = get_client(kwargs.pop("local", False))
60
+ obj: dict = read_yaml(file)
61
+ obj["status"] = {}
62
+ obj["local"] = client.is_local()
63
+ ent: Project = entity_factory.build_entity_from_dict(obj)
64
+ reset_id = kwargs.pop("reset_id", False)
65
+
66
+ try:
67
+ crud_processor._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
68
+ except EntityAlreadyExistsError:
69
+ msg = f"Entity {ent.name} already exists."
70
+ if reset_id:
71
+ ent._import_entities(obj, reset_id=reset_id)
72
+ warn(f"{msg} Other entities ids have been imported.")
73
+ ent.refresh()
74
+ return ent
75
+ raise EntityError(f"{msg} If you want to update it, use load instead.")
76
+
77
+ # Import related entities
78
+ ent._import_entities(obj, reset_id=reset_id)
79
+ ent.refresh()
80
+ return ent
81
+
82
+ def load_project_entity(
83
+ self,
84
+ crud_processor,
85
+ file: str,
86
+ **kwargs,
87
+ ) -> Project:
88
+ """
89
+ Load a project entity from a YAML file and update it in the backend.
90
+
91
+ Reads project configuration from a YAML file and updates an existing
92
+ project in the backend. If the project doesn't exist, it creates a
93
+ new one. Also loads any related entities defined in the file.
94
+
95
+ Parameters
96
+ ----------
97
+ crud_processor : BaseEntityCRUDProcessor
98
+ The CRUD processor instance for entity operations.
99
+ file : str
100
+ Path to the YAML file containing project configuration.
101
+ **kwargs : dict
102
+ Additional parameters including 'local' flag.
103
+
104
+ Returns
105
+ -------
106
+ Project
107
+ The loaded and updated project entity.
108
+ """
109
+ client = get_client(kwargs.pop("local", False))
110
+ obj: dict = read_yaml(file)
111
+ obj["local"] = client.is_local()
112
+ ent: Project = entity_factory.build_entity_from_dict(obj)
113
+
114
+ try:
115
+ crud_processor._update_base_entity(ent._client, ent.ENTITY_TYPE, ent.name, ent.to_dict())
116
+ except EntityNotExistsError:
117
+ crud_processor._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
118
+
119
+ # Load related entities
120
+ ent._load_entities(obj)
121
+ ent.refresh()
122
+ return ent
@@ -0,0 +1,302 @@
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._processors.base.crud import BaseEntityCRUDProcessor
10
+ from digitalhub.entities._processors.base.import_export import BaseEntityImportExportProcessor
11
+ from digitalhub.entities._processors.base.special_ops import BaseEntitySpecialOpsProcessor
12
+
13
+ if typing.TYPE_CHECKING:
14
+ from digitalhub.entities.project._base.entity import Project
15
+
16
+
17
+ class BaseEntityOperationsProcessor:
18
+ """
19
+ Processor for base entity operations.
20
+
21
+ This class handles CRUD operations and other entity management tasks
22
+ for base-level entities (primarily projects). It interacts with the
23
+ client layer to perform backend operations and manages entity lifecycle
24
+ including creation, reading, updating, deletion, and sharing.
25
+
26
+ Uses composition with specialized processors for different operation types.
27
+ """
28
+
29
+ def __init__(self):
30
+ self.crud_processor = BaseEntityCRUDProcessor()
31
+ self.import_export_processor = BaseEntityImportExportProcessor()
32
+ self.special_ops_processor = BaseEntitySpecialOpsProcessor()
33
+
34
+ ##############################
35
+ # CRUD base entity
36
+ ##############################
37
+
38
+ def create_project_entity(
39
+ self,
40
+ _entity: Project | None = None,
41
+ **kwargs,
42
+ ) -> Project:
43
+ """
44
+ Create a project entity in the backend.
45
+
46
+ Creates a new project either from an existing entity object or
47
+ by building one from the provided parameters. Handles both
48
+ local and remote backend creation.
49
+
50
+ Parameters
51
+ ----------
52
+ _entity : Project, optional
53
+ An existing project entity object to create. If None,
54
+ a new entity will be built from kwargs.
55
+ **kwargs : dict
56
+ Parameters for entity creation, including 'local' flag
57
+ and entity-specific parameters.
58
+
59
+ Returns
60
+ -------
61
+ Project
62
+ The created project entity with backend data populated.
63
+ """
64
+ return self.crud_processor.create_project_entity(_entity, **kwargs)
65
+
66
+ def read_project_entity(
67
+ self,
68
+ entity_type: str,
69
+ entity_name: str,
70
+ **kwargs,
71
+ ) -> Project:
72
+ """
73
+ Read a project entity from the backend.
74
+
75
+ Retrieves project data from the backend and constructs a
76
+ Project entity object with the retrieved data.
77
+
78
+ Parameters
79
+ ----------
80
+ entity_type : str
81
+ The type of entity to read (typically 'project').
82
+ entity_name : str
83
+ The name identifier of the project to read.
84
+ **kwargs : dict
85
+ Additional parameters including 'local' flag and
86
+ API call parameters.
87
+
88
+ Returns
89
+ -------
90
+ Project
91
+ The project entity object populated with backend data.
92
+ """
93
+ return self.crud_processor.read_project_entity(entity_type, entity_name, **kwargs)
94
+
95
+ def update_project_entity(
96
+ self,
97
+ entity_type: str,
98
+ entity_name: str,
99
+ entity_dict: dict,
100
+ **kwargs,
101
+ ) -> Project:
102
+ """
103
+ Update a project entity in the backend.
104
+
105
+ Updates an existing project with new data and returns the
106
+ updated Project entity object.
107
+
108
+ Parameters
109
+ ----------
110
+ entity_type : str
111
+ The type of entity to update (typically 'project').
112
+ entity_name : str
113
+ The name identifier of the project to update.
114
+ entity_dict : dict
115
+ The updated project data dictionary.
116
+ **kwargs : dict
117
+ Additional parameters including 'local' flag and
118
+ API call parameters.
119
+
120
+ Returns
121
+ -------
122
+ Project
123
+ The updated project entity object.
124
+ """
125
+ return self.crud_processor.update_project_entity(entity_type, entity_name, entity_dict, **kwargs)
126
+
127
+ def delete_project_entity(
128
+ self,
129
+ entity_type: str,
130
+ entity_name: str,
131
+ **kwargs,
132
+ ) -> dict:
133
+ """
134
+ Delete a project entity from the backend.
135
+
136
+ Deletes a project from the backend and optionally cleans up
137
+ the associated context. Handles both local and remote backends.
138
+
139
+ Parameters
140
+ ----------
141
+ entity_type : str
142
+ The type of entity to delete (typically 'project').
143
+ entity_name : str
144
+ The name identifier of the project to delete.
145
+ **kwargs : dict
146
+ Additional parameters including 'local' flag, 'clean_context'
147
+ flag (default True), and API call parameters.
148
+
149
+ Returns
150
+ -------
151
+ dict
152
+ Response data from the backend delete operation.
153
+ """
154
+ return self.crud_processor.delete_project_entity(entity_type, entity_name, **kwargs)
155
+
156
+ def list_project_entities(
157
+ self,
158
+ entity_type: str,
159
+ **kwargs,
160
+ ) -> list[Project]:
161
+ """
162
+ List project entities from the backend.
163
+
164
+ Retrieves a list of projects from the backend and converts
165
+ them to Project entity objects.
166
+
167
+ Parameters
168
+ ----------
169
+ entity_type : str
170
+ The type of entities to list (typically 'project').
171
+ **kwargs : dict
172
+ Additional parameters including 'local' flag and
173
+ API call parameters for filtering or pagination.
174
+
175
+ Returns
176
+ -------
177
+ list[Project]
178
+ List of project entity objects.
179
+ """
180
+ return self.crud_processor.list_project_entities(entity_type, **kwargs)
181
+
182
+ ##############################
183
+ # Import/Export operations
184
+ ##############################
185
+
186
+ def import_project_entity(
187
+ self,
188
+ file: str,
189
+ **kwargs,
190
+ ) -> Project:
191
+ """
192
+ Import a project entity from a YAML file and create it in the backend.
193
+
194
+ Reads project configuration from a YAML file, creates a new project
195
+ entity in the backend, and imports any related entities defined
196
+ in the file. Raises an error if the project already exists.
197
+
198
+ Parameters
199
+ ----------
200
+ file : str
201
+ Path to the YAML file containing project configuration.
202
+ **kwargs : dict
203
+ Additional parameters including 'local' and 'reset_id' flags.
204
+
205
+ Returns
206
+ -------
207
+ Project
208
+ The imported and created project entity.
209
+
210
+ Raises
211
+ ------
212
+ EntityError
213
+ If the project already exists in the backend.
214
+ """
215
+ return self.import_export_processor.import_project_entity(file, **kwargs)
216
+
217
+ def load_project_entity(
218
+ self,
219
+ file: str,
220
+ **kwargs,
221
+ ) -> Project:
222
+ """
223
+ Load a project entity from a YAML file and update it in the backend.
224
+
225
+ Reads project configuration from a YAML file and updates an existing
226
+ project in the backend. If the project doesn't exist, it creates a
227
+ new one. Also loads any related entities defined in the file.
228
+
229
+ Parameters
230
+ ----------
231
+ file : str
232
+ Path to the YAML file containing project configuration.
233
+ **kwargs : dict
234
+ Additional parameters including 'local' flag.
235
+
236
+ Returns
237
+ -------
238
+ Project
239
+ The loaded and updated project entity.
240
+ """
241
+ return self.import_export_processor.load_project_entity(file, **kwargs)
242
+
243
+ ##############################
244
+ # Base entity operations
245
+ ##############################
246
+
247
+ def build_project_key(
248
+ self,
249
+ entity_id: str,
250
+ **kwargs,
251
+ ) -> str:
252
+ """
253
+ Build a storage key for a project entity.
254
+
255
+ Creates a standardized key string for project identification
256
+ and storage, handling both local and remote client contexts.
257
+
258
+ Parameters
259
+ ----------
260
+ entity_id : str
261
+ The unique identifier of the project entity.
262
+ **kwargs : dict
263
+ Additional parameters including 'local' flag.
264
+
265
+ Returns
266
+ -------
267
+ str
268
+ The constructed project entity key string.
269
+ """
270
+ return self.special_ops_processor.build_project_key(entity_id, **kwargs)
271
+
272
+ def share_project_entity(
273
+ self,
274
+ entity_type: str,
275
+ entity_name: str,
276
+ **kwargs,
277
+ ) -> None:
278
+ """
279
+ Share or unshare a project entity with a user.
280
+
281
+ Manages project access permissions by sharing the project with
282
+ a specified user or removing user access. Handles both sharing
283
+ and unsharing operations based on the 'unshare' parameter.
284
+
285
+ Parameters
286
+ ----------
287
+ entity_type : str
288
+ The type of entity to share (typically 'project').
289
+ entity_name : str
290
+ The name identifier of the project to share.
291
+ **kwargs : dict
292
+ Additional parameters including:
293
+ - 'user': username to share with/unshare from
294
+ - 'unshare': boolean flag for unsharing (default False)
295
+ - 'local': boolean flag for local backend
296
+
297
+ Raises
298
+ ------
299
+ ValueError
300
+ If trying to unshare from a user who doesn't have access.
301
+ """
302
+ return self.special_ops_processor.share_project_entity(entity_type, entity_name, **kwargs)
@@ -0,0 +1,108 @@
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.enums import ApiCategories, BackendOperations
10
+ from digitalhub.stores.client.api import get_client
11
+
12
+ if typing.TYPE_CHECKING:
13
+ pass
14
+
15
+
16
+ class BaseEntitySpecialOpsProcessor:
17
+ """
18
+ Processor for specialized base entity operations.
19
+
20
+ Handles backend operations like sharing, key building, and other
21
+ specialized functionality for base-level entities.
22
+ """
23
+
24
+ def build_project_key(
25
+ self,
26
+ entity_id: str,
27
+ **kwargs,
28
+ ) -> str:
29
+ """
30
+ Build a storage key for a project entity.
31
+
32
+ Creates a standardized key string for project identification
33
+ and storage, handling both local and remote client contexts.
34
+
35
+ Parameters
36
+ ----------
37
+ entity_id : str
38
+ The unique identifier of the project entity.
39
+ **kwargs : dict
40
+ Additional parameters including 'local' flag.
41
+
42
+ Returns
43
+ -------
44
+ str
45
+ The constructed project entity key string.
46
+ """
47
+ client = get_client(kwargs.pop("local", False))
48
+ return client.build_key(ApiCategories.BASE.value, entity_id)
49
+
50
+ def share_project_entity(
51
+ self,
52
+ entity_type: str,
53
+ entity_name: str,
54
+ **kwargs,
55
+ ) -> None:
56
+ """
57
+ Share or unshare a project entity with a user.
58
+
59
+ Manages project access permissions by sharing the project with
60
+ a specified user or removing user access. Handles both sharing
61
+ and unsharing operations based on the 'unshare' parameter.
62
+
63
+ Parameters
64
+ ----------
65
+ entity_type : str
66
+ The type of entity to share (typically 'project').
67
+ entity_name : str
68
+ The name identifier of the project to share.
69
+ **kwargs : dict
70
+ Additional parameters including:
71
+ - 'user': username to share with/unshare from
72
+ - 'unshare': boolean flag for unsharing (default False)
73
+ - 'local': boolean flag for local backend
74
+
75
+ Raises
76
+ ------
77
+ ValueError
78
+ If trying to unshare from a user who doesn't have access.
79
+ """
80
+ client = get_client(kwargs.pop("local", False))
81
+ api = client.build_api(
82
+ ApiCategories.BASE.value,
83
+ BackendOperations.SHARE.value,
84
+ entity_type=entity_type,
85
+ entity_name=entity_name,
86
+ )
87
+
88
+ user = kwargs.pop("user", None)
89
+ if unshare := kwargs.pop("unshare", False):
90
+ users = client.read_object(api, **kwargs)
91
+ for u in users:
92
+ if u["user"] == user:
93
+ kwargs["id"] = u["id"]
94
+ break
95
+ else:
96
+ raise ValueError(f"User '{user}' does not have access to project.")
97
+
98
+ kwargs = client.build_parameters(
99
+ ApiCategories.BASE.value,
100
+ BackendOperations.SHARE.value,
101
+ unshare=unshare,
102
+ user=user,
103
+ **kwargs,
104
+ )
105
+ if unshare:
106
+ client.delete_object(api, **kwargs)
107
+ return
108
+ client.create_object(api, obj={}, **kwargs)
@@ -0,0 +1,3 @@
1
+ # SPDX-FileCopyrightText: © 2025 DSLab - Fondazione Bruno Kessler
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0