digitalhub 0.14.0b1__py3-none-any.whl → 0.14.0b2__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.
- digitalhub/entities/_base/executable/entity.py +20 -12
- digitalhub/entities/_base/material/entity.py +8 -4
- digitalhub/entities/_processors/base.py +8 -8
- digitalhub/entities/_processors/context.py +15 -15
- digitalhub/entities/_processors/utils.py +2 -2
- digitalhub/entities/artifact/crud.py +23 -7
- digitalhub/entities/dataitem/crud.py +28 -9
- digitalhub/entities/dataitem/table/entity.py +28 -1
- digitalhub/entities/dataitem/utils.py +4 -0
- digitalhub/entities/function/_base/entity.py +3 -3
- digitalhub/entities/function/crud.py +23 -7
- digitalhub/entities/model/_base/entity.py +51 -9
- digitalhub/entities/model/crud.py +21 -7
- digitalhub/entities/project/_base/entity.py +121 -41
- digitalhub/entities/project/crud.py +20 -6
- digitalhub/entities/run/_base/entity.py +58 -15
- digitalhub/entities/run/crud.py +22 -7
- digitalhub/entities/secret/crud.py +21 -7
- digitalhub/entities/task/_base/entity.py +4 -4
- digitalhub/entities/task/crud.py +18 -6
- digitalhub/entities/trigger/crud.py +23 -7
- digitalhub/entities/workflow/_base/entity.py +3 -3
- digitalhub/entities/workflow/crud.py +23 -7
- digitalhub/factory/entity.py +283 -0
- digitalhub/factory/registry.py +221 -0
- digitalhub/factory/runtime.py +44 -0
- digitalhub/runtimes/_base.py +2 -2
- digitalhub/stores/client/dhcore/client.py +6 -2
- digitalhub/stores/credentials/configurator.py +4 -5
- digitalhub/stores/data/s3/configurator.py +2 -2
- digitalhub/stores/readers/data/pandas/reader.py +9 -3
- {digitalhub-0.14.0b1.dist-info → digitalhub-0.14.0b2.dist-info}/METADATA +1 -1
- {digitalhub-0.14.0b1.dist-info → digitalhub-0.14.0b2.dist-info}/RECORD +36 -34
- digitalhub/factory/factory.py +0 -460
- {digitalhub-0.14.0b1.dist-info → digitalhub-0.14.0b2.dist-info}/WHEEL +0 -0
- {digitalhub-0.14.0b1.dist-info → digitalhub-0.14.0b2.dist-info}/licenses/AUTHORS +0 -0
- {digitalhub-0.14.0b1.dist-info → digitalhub-0.14.0b2.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,221 @@
|
|
|
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
|
+
Returns
|
|
51
|
+
-------
|
|
52
|
+
None
|
|
53
|
+
|
|
54
|
+
Raises
|
|
55
|
+
------
|
|
56
|
+
BuilderError
|
|
57
|
+
If a builder with the same name already exists.
|
|
58
|
+
"""
|
|
59
|
+
if name in self._entity_builders:
|
|
60
|
+
raise BuilderError(f"Builder {name} already exists.")
|
|
61
|
+
self._entity_builders[name] = builder()
|
|
62
|
+
|
|
63
|
+
def add_runtime_builder(self, name: str, builder: type[RuntimeBuilder]) -> None:
|
|
64
|
+
"""
|
|
65
|
+
Register a runtime builder.
|
|
66
|
+
|
|
67
|
+
Parameters
|
|
68
|
+
----------
|
|
69
|
+
name : str
|
|
70
|
+
The unique identifier for the builder.
|
|
71
|
+
builder : type[RuntimeBuilder]
|
|
72
|
+
The builder class to register. It will be instantiated immediately.
|
|
73
|
+
|
|
74
|
+
Returns
|
|
75
|
+
-------
|
|
76
|
+
None
|
|
77
|
+
|
|
78
|
+
Raises
|
|
79
|
+
------
|
|
80
|
+
BuilderError
|
|
81
|
+
If a builder with the same name already exists.
|
|
82
|
+
"""
|
|
83
|
+
if name in self._runtime_builders:
|
|
84
|
+
raise BuilderError(f"Builder {name} already exists.")
|
|
85
|
+
self._runtime_builders[name] = builder()
|
|
86
|
+
|
|
87
|
+
def get_entity_builder(self, kind: str) -> EntityBuilder | RuntimeEntityBuilder:
|
|
88
|
+
"""
|
|
89
|
+
Retrieve the entity builder for the given kind, ensuring lazy registration.
|
|
90
|
+
|
|
91
|
+
Parameters
|
|
92
|
+
----------
|
|
93
|
+
kind : str
|
|
94
|
+
The kind of entity builder to retrieve.
|
|
95
|
+
|
|
96
|
+
Returns
|
|
97
|
+
-------
|
|
98
|
+
EntityBuilder | RuntimeEntityBuilder
|
|
99
|
+
The builder instance.
|
|
100
|
+
|
|
101
|
+
Raises
|
|
102
|
+
------
|
|
103
|
+
BuilderError
|
|
104
|
+
If no builder exists for the specified kind.
|
|
105
|
+
"""
|
|
106
|
+
if not self._entities_registered:
|
|
107
|
+
self._ensure_entities_registered()
|
|
108
|
+
if kind not in self._entity_builders:
|
|
109
|
+
if not self._runtimes_registered:
|
|
110
|
+
self._ensure_runtimes_registered()
|
|
111
|
+
if kind not in self._entity_builders:
|
|
112
|
+
raise BuilderError(f"Entity builder for kind '{kind}' not found.")
|
|
113
|
+
return self._entity_builders[kind]
|
|
114
|
+
|
|
115
|
+
def get_runtime_builder(self, kind: str) -> RuntimeBuilder:
|
|
116
|
+
"""
|
|
117
|
+
Retrieve the runtime builder for the given kind, ensuring lazy registration.
|
|
118
|
+
|
|
119
|
+
Parameters
|
|
120
|
+
----------
|
|
121
|
+
kind : str
|
|
122
|
+
The kind of runtime builder to retrieve.
|
|
123
|
+
|
|
124
|
+
Returns
|
|
125
|
+
-------
|
|
126
|
+
RuntimeBuilder
|
|
127
|
+
The builder instance.
|
|
128
|
+
|
|
129
|
+
Raises
|
|
130
|
+
------
|
|
131
|
+
BuilderError
|
|
132
|
+
If no builder exists for the specified kind.
|
|
133
|
+
"""
|
|
134
|
+
if kind not in self._runtime_builders:
|
|
135
|
+
if not self._runtimes_registered:
|
|
136
|
+
self._ensure_runtimes_registered()
|
|
137
|
+
if kind not in self._runtime_builders:
|
|
138
|
+
raise BuilderError(f"Runtime builder for kind '{kind}' not found.")
|
|
139
|
+
return self._runtime_builders[kind]
|
|
140
|
+
|
|
141
|
+
def _ensure_entities_registered(self) -> None:
|
|
142
|
+
"""
|
|
143
|
+
Ensure core entities are registered on-demand.
|
|
144
|
+
|
|
145
|
+
Returns
|
|
146
|
+
-------
|
|
147
|
+
None
|
|
148
|
+
"""
|
|
149
|
+
if self._entities_registered:
|
|
150
|
+
return
|
|
151
|
+
try:
|
|
152
|
+
self._register_entities()
|
|
153
|
+
self._entities_registered = True
|
|
154
|
+
except Exception as e:
|
|
155
|
+
raise BuilderError(f"Failed to register core entities: {e}")
|
|
156
|
+
|
|
157
|
+
def _register_entities(self) -> None:
|
|
158
|
+
"""
|
|
159
|
+
Register core entity builders into the registry.
|
|
160
|
+
|
|
161
|
+
Imports the core entities module and registers all entity
|
|
162
|
+
builders with the registry.
|
|
163
|
+
|
|
164
|
+
Returns
|
|
165
|
+
-------
|
|
166
|
+
None
|
|
167
|
+
"""
|
|
168
|
+
try:
|
|
169
|
+
module = import_module(FactoryEnum.REG_ENTITIES.value)
|
|
170
|
+
|
|
171
|
+
# Register core entities
|
|
172
|
+
for k, b in getattr(module, FactoryEnum.REG_ENTITIES_VAR.value, []):
|
|
173
|
+
self.add_entity_builder(k, b)
|
|
174
|
+
|
|
175
|
+
except Exception as e:
|
|
176
|
+
raise RuntimeError("Error registering core entities.") from e
|
|
177
|
+
|
|
178
|
+
def _ensure_runtimes_registered(self) -> None:
|
|
179
|
+
"""
|
|
180
|
+
Ensure runtime entities are registered on-demand.
|
|
181
|
+
|
|
182
|
+
Returns
|
|
183
|
+
-------
|
|
184
|
+
None
|
|
185
|
+
"""
|
|
186
|
+
if self._runtimes_registered:
|
|
187
|
+
return
|
|
188
|
+
try:
|
|
189
|
+
self._register_runtimes_entities()
|
|
190
|
+
self._runtimes_registered = True
|
|
191
|
+
except Exception as e:
|
|
192
|
+
raise BuilderError(f"Failed to register runtime entities: {e}")
|
|
193
|
+
|
|
194
|
+
def _register_runtimes_entities(self) -> None:
|
|
195
|
+
"""
|
|
196
|
+
Register all runtime builders and their entities into the registry.
|
|
197
|
+
|
|
198
|
+
Imports each runtime package and registers its entity and runtime
|
|
199
|
+
builders with the registry.
|
|
200
|
+
|
|
201
|
+
Returns
|
|
202
|
+
-------
|
|
203
|
+
None
|
|
204
|
+
"""
|
|
205
|
+
try:
|
|
206
|
+
for package in list_runtimes():
|
|
207
|
+
module = import_module(package)
|
|
208
|
+
|
|
209
|
+
# Register workflows, functions, tasks and runs entities builders
|
|
210
|
+
for k, b in getattr(module, FactoryEnum.REG_ENTITIES_VAR.value, []):
|
|
211
|
+
self.add_entity_builder(k, b)
|
|
212
|
+
|
|
213
|
+
# Register runtime builders
|
|
214
|
+
for k, b in getattr(module, FactoryEnum.REG_RUNTIME_VAR.value, []):
|
|
215
|
+
self.add_runtime_builder(k, b)
|
|
216
|
+
except Exception as e:
|
|
217
|
+
raise RuntimeError("Error registering runtime entities.") from e
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
# Global singleton instance
|
|
221
|
+
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()
|
digitalhub/runtimes/_base.py
CHANGED
|
@@ -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.
|
|
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
|
|
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)
|
|
@@ -61,8 +61,12 @@ class ClientDHCore(Client):
|
|
|
61
61
|
|
|
62
62
|
Examples
|
|
63
63
|
--------
|
|
64
|
-
>>> from digitalhub.stores.client.api import
|
|
65
|
-
|
|
64
|
+
>>> from digitalhub.stores.client.api import (
|
|
65
|
+
... get_client,
|
|
66
|
+
... )
|
|
67
|
+
>>> client = get_client(
|
|
68
|
+
... local=False
|
|
69
|
+
... )
|
|
66
70
|
>>> # Client is now ready for API operations
|
|
67
71
|
"""
|
|
68
72
|
|
|
@@ -62,12 +62,10 @@ class Configurator:
|
|
|
62
62
|
self.load_file_vars()
|
|
63
63
|
|
|
64
64
|
@abstractmethod
|
|
65
|
-
def load_env_vars(self) -> None:
|
|
66
|
-
...
|
|
65
|
+
def load_env_vars(self) -> None: ...
|
|
67
66
|
|
|
68
67
|
@abstractmethod
|
|
69
|
-
def load_file_vars(self) -> None:
|
|
70
|
-
...
|
|
68
|
+
def load_file_vars(self) -> None: ...
|
|
71
69
|
|
|
72
70
|
def check_config(self) -> None:
|
|
73
71
|
"""
|
|
@@ -143,7 +141,8 @@ class Configurator:
|
|
|
143
141
|
raise ConfigError("Origin has already been changed.")
|
|
144
142
|
if self._origin == self._env:
|
|
145
143
|
self.change_to_file()
|
|
146
|
-
|
|
144
|
+
else:
|
|
145
|
+
self.change_to_env()
|
|
147
146
|
|
|
148
147
|
def change_to_file(self) -> None:
|
|
149
148
|
"""
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
|
-
from datetime import datetime, timezone
|
|
7
|
+
from datetime import datetime, timedelta, timezone
|
|
8
8
|
|
|
9
9
|
from botocore.config import Config
|
|
10
10
|
|
|
@@ -165,5 +165,5 @@ class S3StoreConfigurator(Configurator):
|
|
|
165
165
|
return False
|
|
166
166
|
dt = datetime.strptime(timestamp, "%Y-%m-%dT%H:%M:%SZ")
|
|
167
167
|
dt = dt.replace(tzinfo=timezone.utc)
|
|
168
|
-
now = datetime.now(timezone.utc) +
|
|
168
|
+
now = datetime.now(timezone.utc) + timedelta(seconds=120)
|
|
169
169
|
return dt < now
|
|
@@ -133,7 +133,9 @@ class DataframeReaderPandas(DataframeReader):
|
|
|
133
133
|
-------
|
|
134
134
|
None
|
|
135
135
|
"""
|
|
136
|
-
|
|
136
|
+
if "index" not in kwargs:
|
|
137
|
+
kwargs["index"] = False
|
|
138
|
+
df.to_csv(dst, **kwargs)
|
|
137
139
|
|
|
138
140
|
@staticmethod
|
|
139
141
|
def write_parquet(df: pd.DataFrame, dst: str | BytesIO, **kwargs) -> None:
|
|
@@ -153,7 +155,9 @@ class DataframeReaderPandas(DataframeReader):
|
|
|
153
155
|
-------
|
|
154
156
|
None
|
|
155
157
|
"""
|
|
156
|
-
|
|
158
|
+
if "index" not in kwargs:
|
|
159
|
+
kwargs["index"] = False
|
|
160
|
+
df.to_parquet(dst, **kwargs)
|
|
157
161
|
|
|
158
162
|
@staticmethod
|
|
159
163
|
def write_table(df: pd.DataFrame, table: str, engine: Any, schema: str | None = None, **kwargs) -> None:
|
|
@@ -177,7 +181,9 @@ class DataframeReaderPandas(DataframeReader):
|
|
|
177
181
|
-------
|
|
178
182
|
None
|
|
179
183
|
"""
|
|
180
|
-
|
|
184
|
+
if "index" not in kwargs:
|
|
185
|
+
kwargs["index"] = False
|
|
186
|
+
df.to_sql(table, engine, schema=schema, **kwargs)
|
|
181
187
|
|
|
182
188
|
##############################
|
|
183
189
|
# Utils
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: digitalhub
|
|
3
|
-
Version: 0.14.
|
|
3
|
+
Version: 0.14.0b2
|
|
4
4
|
Summary: Python SDK for Digitalhub
|
|
5
5
|
Project-URL: Homepage, https://github.com/scc-digitalhub/digitalhub-sdk
|
|
6
6
|
Author-email: Fondazione Bruno Kessler <digitalhub@fbk.eu>, Matteo Martini <mmartini@fbk.eu>
|