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,283 @@
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.factory.registry import registry
10
+ from digitalhub.utils.exceptions import BuilderError
11
+
12
+ if typing.TYPE_CHECKING:
13
+ from digitalhub.entities._base.entity.entity import Entity
14
+ from digitalhub.entities._base.entity.metadata import Metadata
15
+ from digitalhub.entities._base.entity.spec import Spec, SpecValidator
16
+ from digitalhub.entities._base.entity.status import Status
17
+
18
+
19
+ class EntityFactory:
20
+ """
21
+ Factory for creating and managing entity builders.
22
+
23
+ This class handles the creation of entities and their components
24
+ through their respective builders, using a centralized registry.
25
+ """
26
+
27
+ def _call_builder_method(self, kind: str, method_name: str, *args, **kwargs):
28
+ """
29
+ Helper method to get a builder and call a method on it.
30
+
31
+ Parameters
32
+ ----------
33
+ kind : str
34
+ The kind of builder to retrieve.
35
+ method_name : str
36
+ The name of the method to call on the builder.
37
+ *args
38
+ Positional arguments to pass to the method.
39
+ **kwargs
40
+ Keyword arguments to pass to the method.
41
+
42
+ Returns
43
+ -------
44
+ Any
45
+ The result of calling the method on the builder.
46
+ """
47
+ builder = registry.get_entity_builder(kind)
48
+ return getattr(builder, method_name)(*args, **kwargs)
49
+
50
+ def build_entity_from_params(self, **kwargs) -> Entity:
51
+ """
52
+ Build an entity from parameters.
53
+
54
+ Parameters
55
+ ----------
56
+ **kwargs
57
+ Entity parameters.
58
+
59
+ Returns
60
+ -------
61
+ Entity
62
+ Entity object.
63
+ """
64
+ kind = self._get_kind(**kwargs)
65
+ builder = registry.get_entity_builder(kind)
66
+ return builder.build(**kwargs)
67
+
68
+ def build_entity_from_dict(self, obj: dict) -> Entity:
69
+ """
70
+ Build an entity from a dictionary.
71
+
72
+ Parameters
73
+ ----------
74
+ obj : dict
75
+ Dictionary with entity data.
76
+
77
+ Returns
78
+ -------
79
+ Entity
80
+ Entity object.
81
+ """
82
+ kind = self._get_kind(**obj)
83
+ builder = registry.get_entity_builder(kind)
84
+ return builder.from_dict(obj)
85
+
86
+ def build_spec(self, kind_to_build_from: str, **kwargs) -> Spec:
87
+ """
88
+ Build an entity spec.
89
+
90
+ Parameters
91
+ ----------
92
+ kind_to_build_from : str
93
+ Entity type.
94
+ **kwargs
95
+ Additional spec parameters.
96
+
97
+ Returns
98
+ -------
99
+ Spec
100
+ Spec object.
101
+ """
102
+ return self._call_builder_method(kind_to_build_from, "build_spec", **kwargs)
103
+
104
+ def build_metadata(self, kind_to_build_from: str, **kwargs) -> Metadata:
105
+ """
106
+ Build an entity metadata.
107
+
108
+ Parameters
109
+ ----------
110
+ kind_to_build_from : str
111
+ Entity type.
112
+ **kwargs
113
+ Additional metadata parameters.
114
+
115
+ Returns
116
+ -------
117
+ Metadata
118
+ Metadata object.
119
+ """
120
+ return self._call_builder_method(kind_to_build_from, "build_metadata", **kwargs)
121
+
122
+ def build_status(self, kind_to_build_from: str, **kwargs) -> Status:
123
+ """
124
+ Build an entity status.
125
+
126
+ Parameters
127
+ ----------
128
+ kind_to_build_from : str
129
+ Entity type.
130
+ **kwargs
131
+ Additional status parameters.
132
+
133
+ Returns
134
+ -------
135
+ Status
136
+ Status object.
137
+ """
138
+ return self._call_builder_method(kind_to_build_from, "build_status", **kwargs)
139
+
140
+ def get_entity_type_from_kind(self, kind: str) -> str:
141
+ """
142
+ Get entity type from builder.
143
+
144
+ Parameters
145
+ ----------
146
+ kind : str
147
+ Entity type.
148
+
149
+ Returns
150
+ -------
151
+ str
152
+ Entity type.
153
+ """
154
+ return self._call_builder_method(kind, "get_entity_type")
155
+
156
+ def get_executable_kind(self, kind: str) -> str:
157
+ """
158
+ Get executable kind.
159
+
160
+ Parameters
161
+ ----------
162
+ kind : str
163
+ Kind.
164
+
165
+ Returns
166
+ -------
167
+ str
168
+ Executable kind.
169
+ """
170
+ return self._call_builder_method(kind, "get_executable_kind")
171
+
172
+ def get_action_from_task_kind(self, kind: str, task_kind: str) -> str:
173
+ """
174
+ Get action from task.
175
+
176
+ Parameters
177
+ ----------
178
+ kind : str
179
+ Kind.
180
+ task_kind : str
181
+ Task kind.
182
+
183
+ Returns
184
+ -------
185
+ str
186
+ Action.
187
+ """
188
+ return self._call_builder_method(kind, "get_action_from_task_kind", task_kind)
189
+
190
+ def get_task_kind_from_action(self, kind: str, action: str) -> list[str]:
191
+ """
192
+ Get task kinds from action.
193
+
194
+ Parameters
195
+ ----------
196
+ kind : str
197
+ Kind.
198
+ action : str
199
+ Action.
200
+
201
+ Returns
202
+ -------
203
+ list of str
204
+ Task kinds.
205
+ """
206
+ return self._call_builder_method(kind, "get_task_kind_from_action", action)
207
+
208
+ def get_run_kind_from_action(self, kind: str, action: str) -> str:
209
+ """
210
+ Get run kind.
211
+
212
+ Parameters
213
+ ----------
214
+ kind : str
215
+ Kind.
216
+
217
+ Returns
218
+ -------
219
+ str
220
+ Run kind.
221
+ """
222
+ return self._call_builder_method(kind, "get_run_kind_from_action", action)
223
+
224
+ def get_all_kinds(self, kind: str) -> list[str]:
225
+ """
226
+ Get all kinds.
227
+
228
+ Parameters
229
+ ----------
230
+ kind : str
231
+ Kind.
232
+
233
+ Returns
234
+ -------
235
+ list of str
236
+ All kinds.
237
+ """
238
+ return self._call_builder_method(kind, "get_all_kinds")
239
+
240
+ def get_spec_validator(self, kind: str) -> SpecValidator:
241
+ """
242
+ Get spec validators.
243
+
244
+ Parameters
245
+ ----------
246
+ kind : str
247
+ Kind.
248
+
249
+ Returns
250
+ -------
251
+ SpecValidator
252
+ Spec validator.
253
+ """
254
+ return self._call_builder_method(kind, "get_spec_validator")
255
+
256
+ @staticmethod
257
+ def _get_kind(**kwargs) -> str:
258
+ """
259
+ Extract the 'kind' from parameters.
260
+
261
+ Parameters
262
+ ----------
263
+ **kwargs
264
+ Entity parameters.
265
+
266
+ Returns
267
+ -------
268
+ str
269
+ The kind of the entity.
270
+
271
+ Raises
272
+ ------
273
+ BuilderError
274
+ If 'kind' is not found in parameters.
275
+ """
276
+ try:
277
+ return kwargs["kind"]
278
+ except KeyError:
279
+ raise BuilderError("Missing 'kind' parameter.")
280
+
281
+
282
+ # Global instance
283
+ entity_factory = EntityFactory()
@@ -0,0 +1,18 @@
1
+ # SPDX-FileCopyrightText: © 2025 DSLab - Fondazione Bruno Kessler
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from __future__ import annotations
6
+
7
+ from enum import Enum
8
+
9
+
10
+ class FactoryEnum(Enum):
11
+ """
12
+ Enumeration for factory.
13
+ """
14
+
15
+ RGX_RUNTIMES = r"digitalhub_runtime_.*"
16
+ REG_ENTITIES = "digitalhub.entities.builders"
17
+ REG_ENTITIES_VAR = "entity_builders"
18
+ REG_RUNTIME_VAR = "runtime_builders"
@@ -0,0 +1,197 @@
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.factory.enums import FactoryEnum
10
+ from digitalhub.factory.utils import import_module, list_runtimes
11
+ from digitalhub.utils.exceptions import BuilderError
12
+
13
+ if typing.TYPE_CHECKING:
14
+ from digitalhub.entities._base.entity.builder import EntityBuilder
15
+ from digitalhub.entities._base.runtime_entity.builder import RuntimeEntityBuilder
16
+ from digitalhub.runtimes.builder import RuntimeBuilder
17
+
18
+
19
+ class BuilderRegistry:
20
+ """
21
+ Singleton registry for managing imported modules and builders.
22
+
23
+ This class centralizes the registration and retrieval of entity and runtime builders,
24
+ ensuring lazy loading and a single source of truth for available builders.
25
+ """
26
+
27
+ def __init__(self) -> None:
28
+ self._instance: BuilderRegistry | None = None
29
+ self._initialized = False
30
+ self._entity_builders: dict[str, EntityBuilder | RuntimeEntityBuilder] = {}
31
+ self._runtime_builders: dict[str, RuntimeBuilder] = {}
32
+ self._entities_registered = False
33
+ self._runtimes_registered = False
34
+
35
+ def add_entity_builder(
36
+ self,
37
+ name: str,
38
+ builder: type[EntityBuilder | RuntimeEntityBuilder],
39
+ ) -> None:
40
+ """
41
+ Register an entity builder.
42
+
43
+ Parameters
44
+ ----------
45
+ name : str
46
+ The unique identifier for the builder.
47
+ builder : type[EntityBuilder] | type[RuntimeEntityBuilder]
48
+ The builder class to register. It will be instantiated immediately.
49
+
50
+ Raises
51
+ ------
52
+ BuilderError
53
+ If a builder with the same name already exists.
54
+ """
55
+ if name in self._entity_builders:
56
+ raise BuilderError(f"Builder {name} already exists.")
57
+ self._entity_builders[name] = builder()
58
+
59
+ def add_runtime_builder(self, name: str, builder: type[RuntimeBuilder]) -> None:
60
+ """
61
+ Register a runtime builder.
62
+
63
+ Parameters
64
+ ----------
65
+ name : str
66
+ The unique identifier for the builder.
67
+ builder : type[RuntimeBuilder]
68
+ The builder class to register. It will be instantiated immediately.
69
+
70
+ Raises
71
+ ------
72
+ BuilderError
73
+ If a builder with the same name already exists.
74
+ """
75
+ if name in self._runtime_builders:
76
+ raise BuilderError(f"Builder {name} already exists.")
77
+ self._runtime_builders[name] = builder()
78
+
79
+ def get_entity_builder(self, kind: str) -> EntityBuilder | RuntimeEntityBuilder:
80
+ """
81
+ Retrieve the entity builder for the given kind, ensuring lazy registration.
82
+
83
+ Parameters
84
+ ----------
85
+ kind : str
86
+ The kind of entity builder to retrieve.
87
+
88
+ Returns
89
+ -------
90
+ EntityBuilder | RuntimeEntityBuilder
91
+ The builder instance.
92
+
93
+ Raises
94
+ ------
95
+ BuilderError
96
+ If no builder exists for the specified kind.
97
+ """
98
+ if not self._entities_registered:
99
+ self._ensure_entities_registered()
100
+ if kind not in self._entity_builders:
101
+ if not self._runtimes_registered:
102
+ self._ensure_runtimes_registered()
103
+ if kind not in self._entity_builders:
104
+ raise BuilderError(f"Entity builder for kind '{kind}' not found.")
105
+ return self._entity_builders[kind]
106
+
107
+ def get_runtime_builder(self, kind: str) -> RuntimeBuilder:
108
+ """
109
+ Retrieve the runtime builder for the given kind, ensuring lazy registration.
110
+
111
+ Parameters
112
+ ----------
113
+ kind : str
114
+ The kind of runtime builder to retrieve.
115
+
116
+ Returns
117
+ -------
118
+ RuntimeBuilder
119
+ The builder instance.
120
+
121
+ Raises
122
+ ------
123
+ BuilderError
124
+ If no builder exists for the specified kind.
125
+ """
126
+ if kind not in self._runtime_builders:
127
+ if not self._runtimes_registered:
128
+ self._ensure_runtimes_registered()
129
+ if kind not in self._runtime_builders:
130
+ raise BuilderError(f"Runtime builder for kind '{kind}' not found.")
131
+ return self._runtime_builders[kind]
132
+
133
+ def _ensure_entities_registered(self) -> None:
134
+ """
135
+ Ensure core entities are registered on-demand.
136
+ """
137
+ if self._entities_registered:
138
+ return
139
+ try:
140
+ self._register_entities()
141
+ self._entities_registered = True
142
+ except Exception as e:
143
+ raise BuilderError(f"Failed to register core entities: {e}")
144
+
145
+ def _register_entities(self) -> None:
146
+ """
147
+ Register core entity builders into the registry.
148
+
149
+ Imports the core entities module and registers all entity
150
+ builders with the registry.
151
+ """
152
+ try:
153
+ module = import_module(FactoryEnum.REG_ENTITIES.value)
154
+
155
+ # Register core entities
156
+ for k, b in getattr(module, FactoryEnum.REG_ENTITIES_VAR.value, []):
157
+ self.add_entity_builder(k, b)
158
+
159
+ except Exception as e:
160
+ raise RuntimeError("Error registering core entities.") from e
161
+
162
+ def _ensure_runtimes_registered(self) -> None:
163
+ """
164
+ Ensure runtime entities are registered on-demand.
165
+ """
166
+ if self._runtimes_registered:
167
+ return
168
+ try:
169
+ self._register_runtimes_entities()
170
+ self._runtimes_registered = True
171
+ except Exception as e:
172
+ raise BuilderError(f"Failed to register runtime entities: {e}")
173
+
174
+ def _register_runtimes_entities(self) -> None:
175
+ """
176
+ Register all runtime builders and their entities into the registry.
177
+
178
+ Imports each runtime package and registers its entity and runtime
179
+ builders with the registry.
180
+ """
181
+ try:
182
+ for package in list_runtimes():
183
+ module = import_module(package)
184
+
185
+ # Register workflows, functions, tasks and runs entities builders
186
+ for k, b in getattr(module, FactoryEnum.REG_ENTITIES_VAR.value, []):
187
+ self.add_entity_builder(k, b)
188
+
189
+ # Register runtime builders
190
+ for k, b in getattr(module, FactoryEnum.REG_RUNTIME_VAR.value, []):
191
+ self.add_runtime_builder(k, b)
192
+ except Exception as e:
193
+ raise RuntimeError("Error registering runtime entities.") from e
194
+
195
+
196
+ # Global singleton instance
197
+ registry = BuilderRegistry()
@@ -0,0 +1,44 @@
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.factory.registry import registry
10
+
11
+ if typing.TYPE_CHECKING:
12
+ from digitalhub.runtimes._base import Runtime
13
+
14
+
15
+ class RuntimeFactory:
16
+ """
17
+ Factory for creating and managing runtime builders.
18
+
19
+ This class handles the creation of runtimes through their respective builders,
20
+ using a centralized registry.
21
+ """
22
+
23
+ def build_runtime(self, kind_to_build_from: str, project: str) -> Runtime:
24
+ """
25
+ Build a runtime.
26
+
27
+ Parameters
28
+ ----------
29
+ kind_to_build_from : str
30
+ Runtime type.
31
+ project : str
32
+ Project name.
33
+
34
+ Returns
35
+ -------
36
+ Runtime
37
+ Runtime object.
38
+ """
39
+ builder = registry.get_runtime_builder(kind_to_build_from)
40
+ return builder.build(project=project)
41
+
42
+
43
+ # Global instance
44
+ runtime_factory = RuntimeFactory()
@@ -9,7 +9,7 @@ import pkgutil
9
9
  import re
10
10
  from types import ModuleType
11
11
 
12
- from digitalhub.factory.factory import factory
12
+ from digitalhub.factory.enums import FactoryEnum
13
13
 
14
14
 
15
15
  def import_module(package: str) -> ModuleType:
@@ -58,62 +58,11 @@ def list_runtimes() -> list[str]:
58
58
  RuntimeError
59
59
  If an error occurs while scanning for runtime packages.
60
60
  """
61
- pattern = r"digitalhub_runtime_.*"
62
- runtimes: list[str] = []
63
61
  try:
62
+ runtimes: list[str] = []
64
63
  for _, name, _ in pkgutil.iter_modules():
65
- if re.match(pattern, name):
64
+ if re.match(FactoryEnum.RGX_RUNTIMES.value, name):
66
65
  runtimes.append(name)
67
66
  return runtimes
68
67
  except Exception as e:
69
68
  raise RuntimeError("Error listing installed runtimes.") from e
70
-
71
-
72
- def register_runtimes_entities() -> None:
73
- """
74
- Register all runtime builders and their entities into the factory.
75
-
76
- Imports each runtime package and registers its entity and runtime
77
- builders with the global factory instance.
78
-
79
- Returns
80
- -------
81
- None
82
- """
83
- for package in list_runtimes():
84
- module = import_module(package)
85
- entity_builders = getattr(module, "entity_builders")
86
- for entity_builder_tuple in entity_builders:
87
- kind, builder = entity_builder_tuple
88
- factory.add_entity_builder(kind, builder)
89
-
90
- runtime_builders = getattr(module, "runtime_builders")
91
- for runtime_builder_tuple in runtime_builders:
92
- kind, builder = runtime_builder_tuple
93
- factory.add_runtime_builder(kind, builder)
94
-
95
-
96
- def register_entities() -> None:
97
- """
98
- Register core entity builders into the factory.
99
-
100
- Imports the core entities module and registers all entity
101
- builders with the global factory instance.
102
-
103
- Returns
104
- -------
105
- None
106
-
107
- Raises
108
- ------
109
- RuntimeError
110
- If registration of core entities fails.
111
- """
112
- try:
113
- module = import_module("digitalhub.entities.builders")
114
- entities_builders_list = getattr(module, "entity_builders")
115
- for entity_builder_tuple in entities_builders_list:
116
- kind, builder = entity_builder_tuple
117
- factory.add_entity_builder(kind, builder)
118
- except Exception as e:
119
- raise RuntimeError("Error registering entities.") from e
@@ -7,7 +7,7 @@ from __future__ import annotations
7
7
  from abc import abstractmethod
8
8
  from typing import Any, Callable
9
9
 
10
- from digitalhub.factory.factory import factory
10
+ from digitalhub.factory.entity import entity_factory
11
11
  from digitalhub.utils.exceptions import EntityError
12
12
  from digitalhub.utils.logger import LOGGER
13
13
 
@@ -72,7 +72,7 @@ class Runtime:
72
72
  raise RuntimeError(msg)
73
73
 
74
74
  try:
75
- return factory.get_action_from_task_kind(task_kind, task_kind)
75
+ return entity_factory.get_action_from_task_kind(task_kind, task_kind)
76
76
  except EntityError:
77
77
  msg = f"Task {task_kind} not allowed."
78
78
  LOGGER.exception(msg)
@@ -4,15 +4,14 @@
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
- from digitalhub.entities._commons.enums import ApiCategories, BackendOperations
8
- from digitalhub.stores.client._base.api_builder import ClientApiBuilder
7
+ from digitalhub.stores.client.enums import ApiCategories, BackendOperations
9
8
  from digitalhub.utils.exceptions import BackendError
10
9
 
11
10
  API_BASE = "/api/v1"
12
11
  API_CONTEXT = f"{API_BASE}/-"
13
12
 
14
13
 
15
- class ClientDHCoreApiBuilder(ClientApiBuilder):
14
+ class ClientApiBuilder:
16
15
  """
17
16
  This class is used to build the API for the DHCore client.
18
17
  """
@@ -100,6 +99,7 @@ class ClientDHCoreApiBuilder(ClientApiBuilder):
100
99
  if operation in (
101
100
  BackendOperations.CREATE.value,
102
101
  BackendOperations.LIST.value,
102
+ BackendOperations.DELETE_ALL_VERSIONS.value,
103
103
  ):
104
104
  return f"{API_CONTEXT}/{project}/{entity_type}"
105
105
  elif operation in (