digitalhub 0.8.0b7__py3-none-any.whl → 0.8.0b10__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 (59) hide show
  1. digitalhub/__init__.py +1 -1
  2. digitalhub/client/api.py +63 -0
  3. digitalhub/client/builder.py +0 -55
  4. digitalhub/client/dhcore/utils.py +1 -1
  5. digitalhub/context/api.py +93 -0
  6. digitalhub/context/builder.py +0 -84
  7. digitalhub/datastores/_base/datastore.py +2 -2
  8. digitalhub/datastores/api.py +37 -0
  9. digitalhub/datastores/builder.py +7 -31
  10. digitalhub/datastores/local/datastore.py +9 -1
  11. digitalhub/datastores/remote/datastore.py +8 -0
  12. digitalhub/datastores/s3/datastore.py +9 -1
  13. digitalhub/datastores/sql/datastore.py +9 -1
  14. digitalhub/entities/_base/api_utils.py +620 -0
  15. digitalhub/entities/_base/context/entity.py +2 -2
  16. digitalhub/entities/_base/crud.py +204 -408
  17. digitalhub/entities/_base/entity/entity.py +1 -1
  18. digitalhub/entities/_base/executable/entity.py +7 -6
  19. digitalhub/entities/_base/material/entity.py +2 -2
  20. digitalhub/entities/artifact/crud.py +16 -42
  21. digitalhub/entities/dataitem/crud.py +19 -45
  22. digitalhub/entities/dataitem/table/entity.py +1 -1
  23. digitalhub/entities/function/crud.py +13 -39
  24. digitalhub/entities/model/crud.py +15 -42
  25. digitalhub/entities/project/_base/entity.py +65 -38
  26. digitalhub/entities/project/crud.py +8 -8
  27. digitalhub/entities/run/_base/entity.py +1 -1
  28. digitalhub/entities/run/crud.py +17 -30
  29. digitalhub/entities/secret/_base/entity.py +1 -1
  30. digitalhub/entities/secret/crud.py +15 -27
  31. digitalhub/entities/task/_base/entity.py +3 -2
  32. digitalhub/entities/task/crud.py +17 -30
  33. digitalhub/entities/workflow/crud.py +13 -39
  34. digitalhub/factory/api.py +31 -25
  35. digitalhub/factory/factory.py +7 -5
  36. digitalhub/readers/_base/builder.py +26 -0
  37. digitalhub/readers/api.py +80 -0
  38. digitalhub/readers/factory.py +133 -0
  39. digitalhub/readers/pandas/builder.py +29 -0
  40. digitalhub/readers/pandas/{readers.py → reader.py} +1 -1
  41. digitalhub/stores/api.py +54 -0
  42. digitalhub/stores/builder.py +0 -46
  43. {digitalhub-0.8.0b7.dist-info → digitalhub-0.8.0b10.dist-info}/METADATA +1 -1
  44. {digitalhub-0.8.0b7.dist-info → digitalhub-0.8.0b10.dist-info}/RECORD +48 -50
  45. digitalhub/entities/artifact/builder.py +0 -51
  46. digitalhub/entities/dataitem/builder.py +0 -51
  47. digitalhub/entities/function/builder.py +0 -51
  48. digitalhub/entities/model/builder.py +0 -51
  49. digitalhub/entities/project/builder.py +0 -51
  50. digitalhub/entities/run/builder.py +0 -51
  51. digitalhub/entities/secret/builder.py +0 -51
  52. digitalhub/entities/task/builder.py +0 -51
  53. digitalhub/entities/workflow/builder.py +0 -51
  54. digitalhub/readers/builder.py +0 -54
  55. digitalhub/readers/registry.py +0 -15
  56. /digitalhub/readers/_base/{readers.py → reader.py} +0 -0
  57. {digitalhub-0.8.0b7.dist-info → digitalhub-0.8.0b10.dist-info}/LICENSE.txt +0 -0
  58. {digitalhub-0.8.0b7.dist-info → digitalhub-0.8.0b10.dist-info}/WHEEL +0 -0
  59. {digitalhub-0.8.0b7.dist-info → digitalhub-0.8.0b10.dist-info}/top_level.txt +0 -0
@@ -2,17 +2,15 @@ from __future__ import annotations
2
2
 
3
3
  import typing
4
4
 
5
- from digitalhub.context.builder import check_context
6
5
  from digitalhub.entities._base.crud import (
7
- delete_entity_api_ctx,
8
- list_entity_api_ctx,
9
- read_entity_api_ctx,
10
- read_entity_api_ctx_versions,
6
+ delete_entity,
7
+ get_context_entity_versions,
8
+ get_versioned_entity,
9
+ import_executable_entity,
10
+ list_context_entities,
11
+ new_context_entity,
11
12
  )
12
13
  from digitalhub.entities.utils.entity_types import EntityTypes
13
- from digitalhub.entities.workflow.builder import workflow_from_dict, workflow_from_parameters
14
- from digitalhub.utils.exceptions import EntityAlreadyExistsError
15
- from digitalhub.utils.io_utils import read_yaml
16
14
 
17
15
  if typing.TYPE_CHECKING:
18
16
  from digitalhub.entities.workflow._base.entity import Workflow
@@ -64,8 +62,7 @@ def new_workflow(
64
62
  >>> code_src="pipeline.py",
65
63
  >>> handler="pipeline-handler")
66
64
  """
67
- check_context(project)
68
- obj = workflow_from_parameters(
65
+ return new_context_entity(
69
66
  project=project,
70
67
  name=name,
71
68
  kind=kind,
@@ -75,8 +72,6 @@ def new_workflow(
75
72
  embedded=embedded,
76
73
  **kwargs,
77
74
  )
78
- obj.save()
79
- return obj
80
75
 
81
76
 
82
77
  def get_workflow(
@@ -114,14 +109,13 @@ def get_workflow(
114
109
  >>> project="my-project",
115
110
  >>> entity_id="my-workflow-id")
116
111
  """
117
- obj = read_entity_api_ctx(
112
+ return get_versioned_entity(
118
113
  identifier,
119
- ENTITY_TYPE,
114
+ entity_type=ENTITY_TYPE,
120
115
  project=project,
121
116
  entity_id=entity_id,
122
117
  **kwargs,
123
118
  )
124
- return workflow_from_dict(obj)
125
119
 
126
120
 
127
121
  def get_workflow_versions(
@@ -155,13 +149,12 @@ def get_workflow_versions(
155
149
  >>> obj = get_workflow_versions("my-workflow-name"
156
150
  >>> project="my-project")
157
151
  """
158
- obj = read_entity_api_ctx_versions(
152
+ return get_context_entity_versions(
159
153
  identifier,
160
154
  entity_type=ENTITY_TYPE,
161
155
  project=project,
162
156
  **kwargs,
163
157
  )
164
- return [workflow_from_dict(o) for o in obj]
165
158
 
166
159
 
167
160
  def list_workflows(project: str, **kwargs) -> list[Workflow]:
@@ -184,12 +177,11 @@ def list_workflows(project: str, **kwargs) -> list[Workflow]:
184
177
  --------
185
178
  >>> objs = list_workflows(project="my-project")
186
179
  """
187
- objs = list_entity_api_ctx(
180
+ return list_context_entities(
188
181
  project=project,
189
182
  entity_type=ENTITY_TYPE,
190
183
  **kwargs,
191
184
  )
192
- return [workflow_from_dict(obj) for obj in objs]
193
185
 
194
186
 
195
187
  def import_workflow(file: str) -> Workflow:
@@ -210,25 +202,7 @@ def import_workflow(file: str) -> Workflow:
210
202
  --------
211
203
  >>> obj = import_workflow("my-workflow.yaml")
212
204
  """
213
- dict_obj: dict | list[dict] = read_yaml(file)
214
- if isinstance(dict_obj, list):
215
- wkf_dict = dict_obj[0]
216
- tsk_dicts = dict_obj[1:]
217
- else:
218
- wkf_dict = dict_obj
219
- tsk_dicts = []
220
-
221
- check_context(wkf_dict.get("project"))
222
- obj = workflow_from_dict(wkf_dict)
223
-
224
- obj.import_tasks(tsk_dicts)
225
-
226
- try:
227
- obj.save()
228
- except EntityAlreadyExistsError:
229
- pass
230
- finally:
231
- return obj
205
+ return import_executable_entity(file)
232
206
 
233
207
 
234
208
  def update_workflow(entity: Workflow) -> Workflow:
@@ -293,7 +267,7 @@ def delete_workflow(
293
267
  >>> project="my-project",
294
268
  >>> delete_all_versions=True)
295
269
  """
296
- return delete_entity_api_ctx(
270
+ return delete_entity(
297
271
  identifier=identifier,
298
272
  entity_type=ENTITY_TYPE,
299
273
  project=project,
digitalhub/factory/api.py CHANGED
@@ -13,22 +13,48 @@ if typing.TYPE_CHECKING:
13
13
  from digitalhub.runtimes._base import Runtime
14
14
 
15
15
 
16
- def build_entity(kind_to_build_from: str, *args, **kwargs) -> Entity:
16
+ def build_entity_from_params(**kwargs) -> Entity:
17
17
  """
18
18
  Build an entity.
19
19
 
20
20
  Parameters
21
21
  ----------
22
- kind_to_build_from : str
23
- Entity type.
22
+ **kwargs
23
+ Entity parameters.
24
24
 
25
25
  Returns
26
26
  -------
27
27
  Entity
28
28
  Entity object.
29
29
  """
30
- _raise_if_entity_builder_not_found(kind_to_build_from)
31
- return factory.build_entity_from_params(kind_to_build_from, *args, **kwargs)
30
+ try:
31
+ kind = kwargs["kind"]
32
+ except KeyError:
33
+ raise BuilderError("Missing 'kind' parameter.")
34
+ _raise_if_entity_builder_not_found(kind)
35
+ return factory.build_entity_from_params(kind, **kwargs)
36
+
37
+
38
+ def build_entity_from_dict(obj: dict) -> Entity:
39
+ """
40
+ Build an entity from a dictionary.
41
+
42
+ Parameters
43
+ ----------
44
+ obj : dict
45
+ Dictionary with entity data.
46
+
47
+ Returns
48
+ -------
49
+ Entity
50
+ Entity object.
51
+ """
52
+ try:
53
+ kind = obj["kind"]
54
+ except KeyError:
55
+ raise BuilderError("Missing 'kind' parameter.")
56
+ _raise_if_entity_builder_not_found(kind)
57
+ return factory.build_entity_from_dict(kind, obj)
32
58
 
33
59
 
34
60
  def build_spec(kind_to_build_from: str, **kwargs) -> Spec:
@@ -105,26 +131,6 @@ def build_runtime(kind_to_build_from: str, project: str) -> Runtime:
105
131
  return factory.build_runtime(kind_to_build_from, project)
106
132
 
107
133
 
108
- def build_entity_from_dict(kind_to_build_from: str, dict_data: dict) -> Entity:
109
- """
110
- Build an entity from a dictionary.
111
-
112
- Parameters
113
- ----------
114
- kind_to_build_from : str
115
- Entity type.
116
- dict_data : dict
117
- Dictionary with entity data.
118
-
119
- Returns
120
- -------
121
- Entity
122
- Entity object.
123
- """
124
- _raise_if_entity_builder_not_found(kind_to_build_from)
125
- return factory.build_entity_from_dict(kind_to_build_from, dict_data)
126
-
127
-
128
134
  def get_entity_type_from_kind(kind: str) -> str:
129
135
  """
130
136
  Get entity type from builder.
@@ -62,23 +62,25 @@ class Factory:
62
62
  raise BuilderError(f"Builder {name} already exists.")
63
63
  self._runtime_builders[name] = builder()
64
64
 
65
- def build_entity_from_params(self, kind_to_build_from: str, *args, **kwargs) -> Entity:
65
+ def build_entity_from_params(self, kind_to_build_from: str, **kwargs) -> Entity:
66
66
  """
67
- Build an entity.
67
+ Build an entity from parameters.
68
68
 
69
69
  Parameters
70
70
  ----------
71
71
  kind_to_build_from : str
72
72
  Entity type.
73
+ **kwargs
74
+ Entity parameters.
73
75
 
74
76
  Returns
75
77
  -------
76
78
  Entity
77
79
  Entity object.
78
80
  """
79
- return self._entity_builders[kind_to_build_from].build(*args, **kwargs)
81
+ return self._entity_builders[kind_to_build_from].build(**kwargs)
80
82
 
81
- def build_entity_from_dict(self, kind_to_build_from: str, dict_data: dict) -> Entity:
83
+ def build_entity_from_dict(self, kind_to_build_from: str, obj: dict) -> Entity:
82
84
  """
83
85
  Build an entity from a dictionary.
84
86
 
@@ -94,7 +96,7 @@ class Factory:
94
96
  Entity
95
97
  Entity object.
96
98
  """
97
- return self._entity_builders[kind_to_build_from].from_dict(dict_data)
99
+ return self._entity_builders[kind_to_build_from].from_dict(obj)
98
100
 
99
101
  def build_spec(self, kind_to_build_from: str, **kwargs) -> Spec:
100
102
  """
@@ -0,0 +1,26 @@
1
+ from __future__ import annotations
2
+
3
+ import typing
4
+ from abc import abstractmethod
5
+
6
+ from digitalhub.utils.exceptions import BuilderError
7
+
8
+ if typing.TYPE_CHECKING:
9
+ from digitalhub.readers._base.reader import DataframeReader
10
+
11
+
12
+ class ReaderBuilder:
13
+ ENGINE = None
14
+ DATAFRAME_CLASS = None
15
+
16
+ def __init__(self):
17
+ if self.ENGINE is None:
18
+ raise BuilderError("ENGINE must be set.")
19
+ if self.DATAFRAME_CLASS is None:
20
+ raise BuilderError("DATAFRAME_CLASS must be set.")
21
+
22
+ @abstractmethod
23
+ def build(self, **kwargs) -> DataframeReader:
24
+ """
25
+ Build reader object.
26
+ """
@@ -0,0 +1,80 @@
1
+ from __future__ import annotations
2
+
3
+ import typing
4
+ from typing import Any
5
+
6
+ from digitalhub.readers.factory import factory
7
+
8
+ if typing.TYPE_CHECKING:
9
+ from digitalhub.readers._base.reader import DataframeReader
10
+
11
+
12
+ def get_reader_by_engine(engine: str | None = None) -> DataframeReader:
13
+ """
14
+ Get Dataframe reader.
15
+
16
+ Parameters
17
+ ----------
18
+ engine : str
19
+ Dataframe engine (pandas, polars, etc.).
20
+
21
+ Returns
22
+ -------
23
+ DataframeReader
24
+ Reader object.
25
+ """
26
+ if engine is None:
27
+ engine = factory.get_default()
28
+ try:
29
+ return factory.build(engine=engine)
30
+ except KeyError:
31
+ engines = factory.list_supported_engines()
32
+ msg = f"Unsupported dataframe engine: '{engine}'. Supported engines: {engines}"
33
+ raise ValueError(msg)
34
+
35
+
36
+ def get_reader_by_object(obj: Any) -> DataframeReader:
37
+ """
38
+ Get Dataframe reader by object.
39
+
40
+ Parameters
41
+ ----------
42
+ obj : Any
43
+ Object to get reader from.
44
+
45
+ Returns
46
+ -------
47
+ DataframeReader
48
+ Reader object.
49
+ """
50
+ try:
51
+ obj_name = f"{obj.__class__.__module__}.{obj.__class__.__name__}"
52
+ return factory.build(dataframe=obj_name)
53
+ except KeyError:
54
+ types = factory.list_supported_dataframes()
55
+ msg = f"Unsupported dataframe type: '{obj}'. Supported types: {types}"
56
+ raise ValueError(msg)
57
+
58
+
59
+ def get_supported_engines() -> list[str]:
60
+ """
61
+ Get supported engines.
62
+
63
+ Returns
64
+ -------
65
+ list
66
+ List of supported engines.
67
+ """
68
+ return factory.list_supported_engines()
69
+
70
+
71
+ def get_supported_dataframes() -> list[str]:
72
+ """
73
+ Get supported dataframes.
74
+
75
+ Returns
76
+ -------
77
+ list
78
+ List of supported dataframes.
79
+ """
80
+ return factory.list_supported_dataframes()
@@ -0,0 +1,133 @@
1
+ from __future__ import annotations
2
+
3
+ import typing
4
+
5
+ if typing.TYPE_CHECKING:
6
+ from digitalhub.readers._base.builder import ReaderBuilder
7
+ from digitalhub.readers._base.reader import DataframeReader
8
+
9
+
10
+ class ReaderFactory:
11
+ """
12
+ Reader factory class.
13
+ """
14
+
15
+ def __init__(self) -> None:
16
+ self._engine_builders: dict[str, ReaderBuilder] = None
17
+ self._dataframe_builders: dict[str, ReaderBuilder] = None
18
+ self._default: str = None
19
+
20
+ def add_builder(self, engine: str, dataframe: str, builder: ReaderBuilder) -> None:
21
+ """
22
+ Add a builder to the factory.
23
+
24
+ Parameters
25
+ ----------
26
+ name : str
27
+ Reader name.
28
+ builder : DataframeReader
29
+ Builder object.
30
+
31
+ Returns
32
+ -------
33
+ None
34
+ """
35
+ if self._engine_builders is None:
36
+ self._engine_builders = {}
37
+ if engine in self._engine_builders:
38
+ raise ValueError(f"Engine {engine} already exists.")
39
+ self._engine_builders[engine] = builder
40
+
41
+ if self._dataframe_builders is None:
42
+ self._dataframe_builders = {}
43
+ if dataframe in self._dataframe_builders:
44
+ raise ValueError(f"Dataframe {dataframe} already exists.")
45
+ self._dataframe_builders[dataframe] = builder
46
+
47
+ def build(self, engine: str | None = None, dataframe: str | None = None, **kwargs) -> DataframeReader:
48
+ """
49
+ Build reader object.
50
+
51
+ Parameters
52
+ ----------
53
+ engine : str | None
54
+ Engine name.
55
+ dataframe : str | None
56
+ Dataframe name.
57
+ **kwargs : dict
58
+ Keyword arguments.
59
+
60
+ Returns
61
+ -------
62
+ DataframeReader
63
+ Reader object.
64
+ """
65
+ if (engine is None) == (dataframe is None):
66
+ raise ValueError("Either engine or dataframe must be provided.")
67
+ if engine is not None:
68
+ return self._engine_builders[engine].build(**kwargs)
69
+ return self._dataframe_builders[dataframe].build(**kwargs)
70
+
71
+ def list_supported_engines(self) -> list[str]:
72
+ """
73
+ List supported engines.
74
+
75
+ Returns
76
+ -------
77
+ list[str]
78
+ List of supported engines.
79
+ """
80
+ return list(self._engine_builders.keys())
81
+
82
+ def list_supported_dataframes(self) -> list[str]:
83
+ """
84
+ List supported dataframes.
85
+
86
+ Returns
87
+ -------
88
+ list[str]
89
+ List of supported dataframes.
90
+ """
91
+ return list(self._dataframe_builders.keys())
92
+
93
+ def set_default(self, engine: str) -> None:
94
+ """
95
+ Set default engine.
96
+
97
+ Parameters
98
+ ----------
99
+ engine : str
100
+ Engine name.
101
+
102
+ Returns
103
+ -------
104
+ None
105
+ """
106
+ if engine not in self._engine_builders:
107
+ raise ValueError(f"Engine {engine} not found.")
108
+ self._default = engine
109
+
110
+ def get_default(self) -> str:
111
+ """
112
+ Get default engine.
113
+
114
+ Returns
115
+ -------
116
+ str
117
+ Default engine.
118
+ """
119
+ if self._default is None:
120
+ raise ValueError("No default engine set.")
121
+ return self._default
122
+
123
+
124
+ factory = ReaderFactory()
125
+
126
+ try:
127
+ from digitalhub.readers.pandas.builder import ReaderBuilderPandas
128
+
129
+ factory.add_builder(ReaderBuilderPandas.ENGINE, ReaderBuilderPandas.DATAFRAME_CLASS, ReaderBuilderPandas())
130
+ factory.set_default(ReaderBuilderPandas.ENGINE)
131
+
132
+ except ImportError:
133
+ pass
@@ -0,0 +1,29 @@
1
+ from __future__ import annotations
2
+
3
+ from digitalhub.readers._base.builder import ReaderBuilder
4
+ from digitalhub.readers.pandas.reader import DataframeReaderPandas
5
+
6
+
7
+ class ReaderBuilderPandas(ReaderBuilder):
8
+ """
9
+ Pandas reader builder.
10
+ """
11
+
12
+ ENGINE = "pandas"
13
+ DATAFRAME_CLASS = "pandas.core.frame.DataFrame"
14
+
15
+ def build(self, **kwargs) -> DataframeReaderPandas:
16
+ """
17
+ Build reader object.
18
+
19
+ Parameters
20
+ ----------
21
+ **kwargs : dict
22
+ Keyword arguments.
23
+
24
+ Returns
25
+ -------
26
+ DataframeReaderPandas
27
+ Pandas reader object.
28
+ """
29
+ return DataframeReaderPandas(**kwargs)
@@ -7,7 +7,7 @@ import numpy as np
7
7
  import pandas as pd
8
8
  from pandas.errors import ParserError
9
9
 
10
- from digitalhub.readers._base.readers import DataframeReader
10
+ from digitalhub.readers._base.reader import DataframeReader
11
11
  from digitalhub.utils.data_utils import build_data_preview, get_data_preview
12
12
 
13
13
 
@@ -0,0 +1,54 @@
1
+ from __future__ import annotations
2
+
3
+ import typing
4
+
5
+ from digitalhub.stores.builder import store_builder
6
+
7
+ if typing.TYPE_CHECKING:
8
+ from digitalhub.stores._base.store import Store, StoreParameters
9
+
10
+
11
+ def set_store(store_cfg: StoreParameters) -> None:
12
+ """
13
+ Set a new store instance with the given configuration.
14
+
15
+ Parameters
16
+ ----------
17
+ store_cfg : StoreParameters
18
+ Store configuration.
19
+
20
+ Returns
21
+ -------
22
+ None
23
+ """
24
+ store_builder.build(store_cfg)
25
+
26
+
27
+ def get_store(uri: str) -> Store:
28
+ """
29
+ Get store instance by uri.
30
+
31
+ Parameters
32
+ ---------
33
+ uri : str
34
+ URI to parse.
35
+
36
+ Returns
37
+ -------
38
+ Store
39
+ Store instance.
40
+ """
41
+ return store_builder.get(uri)
42
+
43
+
44
+ def get_default_store() -> Store:
45
+ """
46
+ Get the default store instance. The default store is the one that
47
+ can persist artifacts and dataitems.
48
+
49
+ Returns
50
+ -------
51
+ Store
52
+ Default store instance.
53
+ """
54
+ return store_builder.default()
@@ -208,50 +208,4 @@ def get_env_store_config(scheme: str) -> StoreParameters:
208
208
  raise ValueError(f"Unsupported scheme {scheme}")
209
209
 
210
210
 
211
- def set_store(store_cfg: StoreParameters) -> None:
212
- """
213
- Set a new store instance with the given configuration.
214
-
215
- Parameters
216
- ----------
217
- store_cfg : StoreParameters
218
- Store configuration.
219
-
220
- Returns
221
- -------
222
- None
223
- """
224
- store_builder.build(store_cfg)
225
-
226
-
227
- def get_store(uri: str) -> Store:
228
- """
229
- Get store instance by uri.
230
-
231
- Parameters
232
- ---------
233
- uri : str
234
- URI to parse.
235
-
236
- Returns
237
- -------
238
- Store
239
- Store instance.
240
- """
241
- return store_builder.get(uri)
242
-
243
-
244
- def get_default_store() -> Store:
245
- """
246
- Get the default store instance. The default store is the one that
247
- can persist artifacts and dataitems.
248
-
249
- Returns
250
- -------
251
- Store
252
- Default store instance.
253
- """
254
- return store_builder.default()
255
-
256
-
257
211
  store_builder = StoreBuilder()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: digitalhub
3
- Version: 0.8.0b7
3
+ Version: 0.8.0b10
4
4
  Summary: Python SDK for Digitalhub
5
5
  Author-email: Fondazione Bruno Kessler <dslab@fbk.eu>, Matteo Martini <mmartini@fbk.eu>
6
6
  License: Apache License