digitalhub 0.13.4__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.
- digitalhub/__init__.py +3 -8
- digitalhub/context/api.py +1 -5
- digitalhub/context/builder.py +1 -5
- digitalhub/context/context.py +2 -9
- digitalhub/entities/_base/_base/entity.py +0 -15
- digitalhub/entities/_base/context/entity.py +1 -1
- digitalhub/entities/_base/entity/builder.py +5 -5
- digitalhub/entities/_base/entity/entity.py +0 -8
- digitalhub/entities/_base/executable/entity.py +169 -79
- digitalhub/entities/_base/material/entity.py +6 -22
- digitalhub/entities/_base/material/utils.py +1 -4
- digitalhub/entities/_base/runtime_entity/builder.py +53 -18
- digitalhub/entities/_base/unversioned/entity.py +1 -1
- digitalhub/entities/_base/versioned/entity.py +1 -1
- digitalhub/entities/_commons/enums.py +1 -31
- digitalhub/entities/_commons/utils.py +83 -21
- digitalhub/entities/_constructors/_resources.py +151 -0
- digitalhub/entities/{_base/entity/_constructors → _constructors}/name.py +18 -0
- digitalhub/entities/_processors/base/__init__.py +3 -0
- digitalhub/entities/_processors/{base.py → base/crud.py} +14 -226
- digitalhub/entities/_processors/base/import_export.py +123 -0
- digitalhub/entities/_processors/base/processor.py +302 -0
- digitalhub/entities/_processors/base/special_ops.py +108 -0
- digitalhub/entities/_processors/context/__init__.py +3 -0
- digitalhub/entities/_processors/context/crud.py +652 -0
- digitalhub/entities/_processors/context/import_export.py +242 -0
- digitalhub/entities/_processors/context/material.py +123 -0
- digitalhub/entities/_processors/context/processor.py +400 -0
- digitalhub/entities/_processors/context/special_ops.py +476 -0
- digitalhub/entities/_processors/processors.py +12 -0
- digitalhub/entities/_processors/utils.py +12 -11
- digitalhub/entities/artifact/crud.py +58 -22
- digitalhub/entities/artifact/utils.py +3 -3
- digitalhub/entities/dataitem/crud.py +63 -20
- digitalhub/entities/dataitem/table/entity.py +24 -22
- digitalhub/entities/dataitem/utils.py +15 -15
- digitalhub/entities/function/_base/entity.py +3 -3
- digitalhub/entities/function/crud.py +55 -24
- digitalhub/entities/model/_base/entity.py +62 -20
- digitalhub/entities/model/crud.py +58 -22
- digitalhub/entities/model/utils.py +3 -3
- digitalhub/entities/project/_base/entity.py +321 -152
- digitalhub/entities/project/crud.py +15 -23
- digitalhub/entities/run/_base/builder.py +0 -4
- digitalhub/entities/run/_base/entity.py +70 -63
- digitalhub/entities/run/crud.py +79 -26
- digitalhub/entities/secret/_base/entity.py +1 -5
- digitalhub/entities/secret/crud.py +29 -26
- digitalhub/entities/task/_base/builder.py +0 -4
- digitalhub/entities/task/_base/entity.py +5 -5
- digitalhub/entities/task/_base/models.py +13 -16
- digitalhub/entities/task/crud.py +61 -29
- digitalhub/entities/trigger/_base/entity.py +1 -5
- digitalhub/entities/trigger/crud.py +64 -24
- digitalhub/entities/workflow/_base/entity.py +3 -3
- digitalhub/entities/workflow/crud.py +55 -21
- digitalhub/factory/entity.py +283 -0
- digitalhub/factory/enums.py +18 -0
- digitalhub/factory/registry.py +197 -0
- digitalhub/factory/runtime.py +44 -0
- digitalhub/factory/utils.py +3 -54
- digitalhub/runtimes/_base.py +2 -2
- digitalhub/stores/client/_base/enums.py +39 -0
- digitalhub/stores/client/_base/key_builder.py +2 -2
- digitalhub/stores/client/_base/params_builder.py +48 -0
- digitalhub/stores/client/api.py +6 -10
- digitalhub/stores/client/builder.py +4 -4
- digitalhub/stores/client/dhcore/api_builder.py +2 -1
- digitalhub/stores/client/dhcore/client.py +85 -429
- digitalhub/stores/client/dhcore/configurator.py +109 -328
- digitalhub/stores/client/dhcore/enums.py +0 -16
- digitalhub/stores/client/dhcore/error_parser.py +0 -4
- digitalhub/stores/client/dhcore/header_manager.py +61 -0
- digitalhub/stores/client/dhcore/http_handler.py +133 -0
- digitalhub/stores/client/dhcore/params_builder.py +147 -134
- digitalhub/stores/client/dhcore/response_processor.py +102 -0
- digitalhub/stores/client/dhcore/utils.py +6 -72
- digitalhub/stores/client/local/api_builder.py +1 -1
- digitalhub/stores/client/local/client.py +79 -47
- digitalhub/stores/client/local/params_builder.py +18 -41
- digitalhub/stores/credentials/api.py +0 -4
- digitalhub/stores/credentials/configurator.py +2 -28
- digitalhub/stores/credentials/enums.py +3 -0
- digitalhub/stores/credentials/handler.py +0 -12
- digitalhub/stores/credentials/ini_module.py +0 -22
- digitalhub/stores/credentials/store.py +0 -4
- digitalhub/stores/data/_base/store.py +0 -16
- digitalhub/stores/data/builder.py +1 -5
- digitalhub/stores/data/local/store.py +0 -103
- digitalhub/stores/data/remote/store.py +0 -4
- digitalhub/stores/data/s3/configurator.py +60 -14
- digitalhub/stores/data/s3/store.py +49 -16
- digitalhub/stores/data/sql/configurator.py +0 -8
- digitalhub/stores/data/sql/store.py +21 -10
- digitalhub/stores/readers/data/factory.py +0 -8
- digitalhub/stores/readers/data/pandas/reader.py +0 -16
- digitalhub/utils/file_utils.py +0 -17
- digitalhub/utils/generic_utils.py +0 -12
- digitalhub/utils/git_utils.py +0 -8
- digitalhub/utils/io_utils.py +0 -12
- digitalhub/utils/store_utils.py +44 -0
- {digitalhub-0.13.4.dist-info → digitalhub-0.14.0.dist-info}/METADATA +3 -2
- {digitalhub-0.13.4.dist-info → digitalhub-0.14.0.dist-info}/RECORD +111 -95
- digitalhub/entities/_processors/context.py +0 -1450
- digitalhub/entities/task/_base/utils.py +0 -22
- digitalhub/factory/factory.py +0 -381
- digitalhub/stores/client/dhcore/models.py +0 -40
- digitalhub/stores/data/s3/utils.py +0 -78
- /digitalhub/entities/{_base/entity/_constructors → _constructors}/__init__.py +0 -0
- /digitalhub/entities/{_base/entity/_constructors → _constructors}/metadata.py +0 -0
- /digitalhub/entities/{_base/entity/_constructors → _constructors}/spec.py +0 -0
- /digitalhub/entities/{_base/entity/_constructors → _constructors}/status.py +0 -0
- /digitalhub/entities/{_base/entity/_constructors → _constructors}/uuid.py +0 -0
- {digitalhub-0.13.4.dist-info → digitalhub-0.14.0.dist-info}/WHEEL +0 -0
- {digitalhub-0.13.4.dist-info → digitalhub-0.14.0.dist-info}/licenses/AUTHORS +0 -0
- {digitalhub-0.13.4.dist-info → digitalhub-0.14.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -7,7 +7,7 @@ from __future__ import annotations
|
|
|
7
7
|
import typing
|
|
8
8
|
|
|
9
9
|
from digitalhub.entities._commons.enums import EntityTypes
|
|
10
|
-
from digitalhub.entities._processors.
|
|
10
|
+
from digitalhub.entities._processors.processors import context_processor
|
|
11
11
|
|
|
12
12
|
if typing.TYPE_CHECKING:
|
|
13
13
|
from digitalhub.entities.workflow._base.entity import Workflow
|
|
@@ -75,7 +75,6 @@ def get_workflow(
|
|
|
75
75
|
identifier: str,
|
|
76
76
|
project: str | None = None,
|
|
77
77
|
entity_id: str | None = None,
|
|
78
|
-
**kwargs,
|
|
79
78
|
) -> Workflow:
|
|
80
79
|
"""
|
|
81
80
|
Get object from backend.
|
|
@@ -88,8 +87,6 @@ def get_workflow(
|
|
|
88
87
|
Project name.
|
|
89
88
|
entity_id : str
|
|
90
89
|
Entity ID.
|
|
91
|
-
**kwargs : dict
|
|
92
|
-
Parameters to pass to the API call.
|
|
93
90
|
|
|
94
91
|
Returns
|
|
95
92
|
-------
|
|
@@ -107,18 +104,16 @@ def get_workflow(
|
|
|
107
104
|
>>> entity_id="my-workflow-id")
|
|
108
105
|
"""
|
|
109
106
|
return context_processor.read_context_entity(
|
|
110
|
-
identifier,
|
|
107
|
+
identifier=identifier,
|
|
111
108
|
entity_type=ENTITY_TYPE,
|
|
112
109
|
project=project,
|
|
113
110
|
entity_id=entity_id,
|
|
114
|
-
**kwargs,
|
|
115
111
|
)
|
|
116
112
|
|
|
117
113
|
|
|
118
114
|
def get_workflow_versions(
|
|
119
115
|
identifier: str,
|
|
120
116
|
project: str | None = None,
|
|
121
|
-
**kwargs,
|
|
122
117
|
) -> list[Workflow]:
|
|
123
118
|
"""
|
|
124
119
|
Get object versions from backend.
|
|
@@ -129,8 +124,6 @@ def get_workflow_versions(
|
|
|
129
124
|
Entity key (store://...) or entity name.
|
|
130
125
|
project : str
|
|
131
126
|
Project name.
|
|
132
|
-
**kwargs : dict
|
|
133
|
-
Parameters to pass to the API call.
|
|
134
127
|
|
|
135
128
|
Returns
|
|
136
129
|
-------
|
|
@@ -147,14 +140,23 @@ def get_workflow_versions(
|
|
|
147
140
|
>>> project="my-project")
|
|
148
141
|
"""
|
|
149
142
|
return context_processor.read_context_entity_versions(
|
|
150
|
-
identifier,
|
|
143
|
+
identifier=identifier,
|
|
151
144
|
entity_type=ENTITY_TYPE,
|
|
152
145
|
project=project,
|
|
153
|
-
**kwargs,
|
|
154
146
|
)
|
|
155
147
|
|
|
156
148
|
|
|
157
|
-
def list_workflows(
|
|
149
|
+
def list_workflows(
|
|
150
|
+
project: str,
|
|
151
|
+
q: str | None = None,
|
|
152
|
+
name: str | None = None,
|
|
153
|
+
kind: str | None = None,
|
|
154
|
+
user: str | None = None,
|
|
155
|
+
state: str | None = None,
|
|
156
|
+
created: str | None = None,
|
|
157
|
+
updated: str | None = None,
|
|
158
|
+
version: str | None = None,
|
|
159
|
+
) -> list[Workflow]:
|
|
158
160
|
"""
|
|
159
161
|
List all latest version objects from backend.
|
|
160
162
|
|
|
@@ -162,8 +164,22 @@ def list_workflows(project: str, **kwargs) -> list[Workflow]:
|
|
|
162
164
|
----------
|
|
163
165
|
project : str
|
|
164
166
|
Project name.
|
|
165
|
-
|
|
166
|
-
|
|
167
|
+
q : str
|
|
168
|
+
Query string to filter objects.
|
|
169
|
+
name : str
|
|
170
|
+
Object name.
|
|
171
|
+
kind : str
|
|
172
|
+
Kind of the object.
|
|
173
|
+
user : str
|
|
174
|
+
User that created the object.
|
|
175
|
+
state : str
|
|
176
|
+
Object state.
|
|
177
|
+
created : str
|
|
178
|
+
Creation date filter.
|
|
179
|
+
updated : str
|
|
180
|
+
Update date filter.
|
|
181
|
+
version : str
|
|
182
|
+
Object version, default is latest.
|
|
167
183
|
|
|
168
184
|
Returns
|
|
169
185
|
-------
|
|
@@ -177,18 +193,36 @@ def list_workflows(project: str, **kwargs) -> list[Workflow]:
|
|
|
177
193
|
return context_processor.list_context_entities(
|
|
178
194
|
project=project,
|
|
179
195
|
entity_type=ENTITY_TYPE,
|
|
180
|
-
|
|
196
|
+
q=q,
|
|
197
|
+
name=name,
|
|
198
|
+
kind=kind,
|
|
199
|
+
user=user,
|
|
200
|
+
state=state,
|
|
201
|
+
created=created,
|
|
202
|
+
updated=updated,
|
|
203
|
+
version=version,
|
|
181
204
|
)
|
|
182
205
|
|
|
183
206
|
|
|
184
|
-
def import_workflow(
|
|
207
|
+
def import_workflow(
|
|
208
|
+
file: str | None = None,
|
|
209
|
+
key: str | None = None,
|
|
210
|
+
reset_id: bool = False,
|
|
211
|
+
context: str | None = None,
|
|
212
|
+
) -> Workflow:
|
|
185
213
|
"""
|
|
186
|
-
Import object from a YAML file
|
|
214
|
+
Import an object from a YAML file or from a storage key.
|
|
187
215
|
|
|
188
216
|
Parameters
|
|
189
217
|
----------
|
|
190
218
|
file : str
|
|
191
|
-
Path to YAML file.
|
|
219
|
+
Path to the YAML file.
|
|
220
|
+
key : str
|
|
221
|
+
Entity key (store://...).
|
|
222
|
+
reset_id : bool
|
|
223
|
+
Flag to determine if the ID of executable entities should be reset.
|
|
224
|
+
context : str
|
|
225
|
+
Project name to use for context resolution.
|
|
192
226
|
|
|
193
227
|
Returns
|
|
194
228
|
-------
|
|
@@ -199,7 +233,7 @@ def import_workflow(file: str) -> Workflow:
|
|
|
199
233
|
--------
|
|
200
234
|
>>> obj = import_workflow("my-workflow.yaml")
|
|
201
235
|
"""
|
|
202
|
-
return context_processor.import_executable_entity(file)
|
|
236
|
+
return context_processor.import_executable_entity(file, key, reset_id, context)
|
|
203
237
|
|
|
204
238
|
|
|
205
239
|
def load_workflow(file: str) -> Workflow:
|
|
@@ -269,7 +303,8 @@ def delete_workflow(
|
|
|
269
303
|
entity_id : str
|
|
270
304
|
Entity ID.
|
|
271
305
|
delete_all_versions : bool
|
|
272
|
-
Delete all versions of the named entity.
|
|
306
|
+
Delete all versions of the named entity.
|
|
307
|
+
If True, use entity name instead of entity key as identifier.
|
|
273
308
|
cascade : bool
|
|
274
309
|
Cascade delete.
|
|
275
310
|
**kwargs : dict
|
|
@@ -297,5 +332,4 @@ def delete_workflow(
|
|
|
297
332
|
entity_id=entity_id,
|
|
298
333
|
delete_all_versions=delete_all_versions,
|
|
299
334
|
cascade=cascade,
|
|
300
|
-
**kwargs,
|
|
301
335
|
)
|
|
@@ -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()
|