digitalhub 0.13.0b2__py3-none-any.whl → 0.13.0b3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. digitalhub/__init__.py +1 -1
  2. digitalhub/context/api.py +5 -5
  3. digitalhub/context/builder.py +3 -5
  4. digitalhub/context/context.py +9 -1
  5. digitalhub/entities/_base/material/entity.py +3 -3
  6. digitalhub/entities/dataitem/crud.py +10 -2
  7. digitalhub/entities/dataitem/table/entity.py +3 -3
  8. digitalhub/entities/dataitem/utils.py +1 -2
  9. digitalhub/entities/task/_base/models.py +12 -3
  10. digitalhub/factory/factory.py +25 -3
  11. digitalhub/factory/utils.py +11 -3
  12. digitalhub/runtimes/_base.py +1 -1
  13. digitalhub/runtimes/builder.py +18 -1
  14. digitalhub/stores/client/__init__.py +12 -0
  15. digitalhub/stores/client/_base/api_builder.py +14 -0
  16. digitalhub/stores/client/_base/client.py +93 -0
  17. digitalhub/stores/client/_base/key_builder.py +28 -0
  18. digitalhub/stores/client/_base/params_builder.py +14 -0
  19. digitalhub/stores/client/api.py +10 -5
  20. digitalhub/stores/client/builder.py +3 -1
  21. digitalhub/stores/client/dhcore/api_builder.py +17 -0
  22. digitalhub/stores/client/dhcore/client.py +276 -58
  23. digitalhub/stores/client/dhcore/configurator.py +336 -141
  24. digitalhub/stores/client/dhcore/error_parser.py +35 -1
  25. digitalhub/stores/client/dhcore/params_builder.py +113 -17
  26. digitalhub/stores/client/dhcore/utils.py +32 -14
  27. digitalhub/stores/client/local/api_builder.py +17 -0
  28. digitalhub/stores/client/local/client.py +6 -8
  29. digitalhub/stores/credentials/api.py +8 -8
  30. digitalhub/stores/credentials/configurator.py +176 -3
  31. digitalhub/stores/credentials/enums.py +16 -3
  32. digitalhub/stores/credentials/handler.py +73 -45
  33. digitalhub/stores/credentials/ini_module.py +59 -27
  34. digitalhub/stores/credentials/store.py +33 -1
  35. digitalhub/stores/data/_base/store.py +8 -3
  36. digitalhub/stores/data/api.py +20 -16
  37. digitalhub/stores/data/builder.py +3 -9
  38. digitalhub/stores/data/s3/configurator.py +64 -23
  39. digitalhub/stores/data/s3/store.py +30 -27
  40. digitalhub/stores/data/s3/utils.py +9 -9
  41. digitalhub/stores/data/sql/configurator.py +23 -22
  42. digitalhub/stores/data/sql/store.py +14 -16
  43. digitalhub/utils/exceptions.py +6 -0
  44. digitalhub/utils/file_utils.py +53 -30
  45. digitalhub/utils/generic_utils.py +41 -33
  46. digitalhub/utils/git_utils.py +24 -14
  47. digitalhub/utils/io_utils.py +19 -18
  48. digitalhub/utils/uri_utils.py +31 -31
  49. {digitalhub-0.13.0b2.dist-info → digitalhub-0.13.0b3.dist-info}/METADATA +1 -1
  50. {digitalhub-0.13.0b2.dist-info → digitalhub-0.13.0b3.dist-info}/RECORD +53 -53
  51. {digitalhub-0.13.0b2.dist-info → digitalhub-0.13.0b3.dist-info}/WHEEL +0 -0
  52. {digitalhub-0.13.0b2.dist-info → digitalhub-0.13.0b3.dist-info}/licenses/AUTHORS +0 -0
  53. {digitalhub-0.13.0b2.dist-info → digitalhub-0.13.0b3.dist-info}/licenses/LICENSE +0 -0
digitalhub/__init__.py CHANGED
@@ -104,7 +104,7 @@ except ImportError:
104
104
  # Register entities into registry
105
105
  from digitalhub.factory.utils import register_entities, register_runtimes_entities
106
106
  from digitalhub.stores.client.dhcore.utils import refresh_token, set_dhcore_env
107
- from digitalhub.stores.credentials.api import get_current_env, set_current_env
107
+ from digitalhub.stores.credentials.api import get_current_profile, set_current_profile
108
108
 
109
109
  register_entities()
110
110
  register_runtimes_entities()
digitalhub/context/api.py CHANGED
@@ -17,15 +17,15 @@ def build_context(project: Project, overwrite: bool = False) -> Context:
17
17
  """
18
18
  Build a new context for a project.
19
19
 
20
- Creates or updates a context instance for the given project in the global
21
- context registry.
20
+ Creates or updates a context instance for the given project
21
+ in the global context registry.
22
22
 
23
23
  Parameters
24
24
  ----------
25
25
  project : Project
26
26
  The project object used to build the context.
27
27
  overwrite : bool, optional
28
- If True, overwrites existing context if it exists, by default False.
28
+ If True, overwrites existing context if it exists. Default is False.
29
29
 
30
30
  Returns
31
31
  -------
@@ -37,7 +37,7 @@ def build_context(project: Project, overwrite: bool = False) -> Context:
37
37
 
38
38
  def get_context(project: str) -> Context:
39
39
  """
40
- Wrapper for ContextBuilder.get().
40
+ Get the context for a given project name.
41
41
 
42
42
  Parameters
43
43
  ----------
@@ -54,7 +54,7 @@ def get_context(project: str) -> Context:
54
54
 
55
55
  def delete_context(project: str) -> None:
56
56
  """
57
- Wrapper for ContextBuilder.remove().
57
+ Delete the context for a given project name.
58
58
 
59
59
  Parameters
60
60
  ----------
@@ -39,8 +39,7 @@ class ContextBuilder:
39
39
  project : Project
40
40
  The project instance to create a context for.
41
41
  overwrite : bool, optional
42
- If True, overwrites existing context if project name already exists,
43
- by default False.
42
+ If True, overwrites existing context if project name already exists. Default is False.
44
43
 
45
44
  Returns
46
45
  -------
@@ -87,12 +86,11 @@ class ContextBuilder:
87
86
  Returns
88
87
  -------
89
88
  None
90
- This method doesn't return anything.
89
+ This method does not return anything.
91
90
 
92
91
  Notes
93
92
  -----
94
- If the project doesn't exist in the registry, this method
95
- silently does nothing.
93
+ If the project does not exist in the registry, this method silently does nothing.
96
94
  """
97
95
  self._instances.pop(project, None)
98
96
 
@@ -56,6 +56,10 @@ class Context:
56
56
  ----------
57
57
  run_ctx : str
58
58
  The run key to set.
59
+
60
+ Returns
61
+ -------
62
+ None
59
63
  """
60
64
  self.is_running = True
61
65
  self._run_ctx = run_ctx
@@ -63,6 +67,10 @@ class Context:
63
67
  def unset_run(self) -> None:
64
68
  """
65
69
  Clear the current run key and reset running state.
70
+
71
+ Returns
72
+ -------
73
+ None
66
74
  """
67
75
  self.is_running = False
68
76
  self._run_ctx = None
@@ -73,7 +81,7 @@ class Context:
73
81
 
74
82
  Returns
75
83
  -------
76
- str | None
84
+ str or None
77
85
  The current run key if set, None otherwise.
78
86
  """
79
87
  return self._run_ctx
@@ -82,7 +82,7 @@ class MaterialEntity(VersionedEntity):
82
82
  list[str]
83
83
  List of file paths.
84
84
  """
85
- store = get_store(self.project, self.spec.path)
85
+ store = get_store(self.spec.path)
86
86
  dst = store._build_temp()
87
87
  return store.download(self.spec.path, dst=dst)
88
88
 
@@ -121,7 +121,7 @@ class MaterialEntity(VersionedEntity):
121
121
  >>> print(path)
122
122
  dataitem/data.csv
123
123
  """
124
- store = get_store(self.project, self.spec.path)
124
+ store = get_store(self.spec.path)
125
125
 
126
126
  if destination is None:
127
127
  dst = self._context().root / self.ENTITY_TYPE
@@ -158,7 +158,7 @@ class MaterialEntity(VersionedEntity):
158
158
  >>> entity.upload('./data')
159
159
  """
160
160
  # Get store and upload object
161
- store = get_store(self.project, self.spec.path)
161
+ store = get_store(self.spec.path)
162
162
  paths = store.upload(source, self.spec.path)
163
163
 
164
164
  # Update files info
@@ -131,8 +131,16 @@ def log_dataitem(
131
131
  cleanup = True
132
132
 
133
133
  source = eval_source(source, data, kind, name, project)
134
- data = eval_data(project, kind, source, data, file_format, engine)
135
- kwargs = process_kwargs(project, name, kind, source=source, data=data, path=path, **kwargs)
134
+ data = eval_data(kind, source, data, file_format, engine)
135
+ kwargs = process_kwargs(
136
+ project,
137
+ name,
138
+ kind,
139
+ source=source,
140
+ data=data,
141
+ path=path,
142
+ **kwargs,
143
+ )
136
144
  obj = context_processor.log_material_entity(
137
145
  source=source,
138
146
  project=project,
@@ -93,14 +93,14 @@ class DataitemTable(Dataitem):
93
93
  DataFrame.
94
94
  """
95
95
  if self._query is not None:
96
- df = get_store(self.project, self.spec.path).query(
96
+ df = get_store(self.spec.path).query(
97
97
  self._query,
98
98
  self.spec.path,
99
99
  engine,
100
100
  )
101
101
  self._query = None
102
102
  return df
103
- return get_store(self.project, self.spec.path).read_df(
103
+ return get_store(self.spec.path).read_df(
104
104
  self.spec.path,
105
105
  file_format,
106
106
  engine,
@@ -132,7 +132,7 @@ class DataitemTable(Dataitem):
132
132
  str
133
133
  Path to the written dataframe.
134
134
  """
135
- return get_store(self.project, self.spec.path).write_df(
135
+ return get_store(self.spec.path).write_df(
136
136
  df,
137
137
  self.spec.path,
138
138
  extension=extension,
@@ -62,7 +62,6 @@ def eval_source(
62
62
 
63
63
 
64
64
  def eval_data(
65
- project: str,
66
65
  kind: str,
67
66
  source: SourcesOrListOfSources,
68
67
  data: Any | None = None,
@@ -91,7 +90,7 @@ def eval_data(
91
90
  """
92
91
  if kind == EntityKinds.DATAITEM_TABLE.value:
93
92
  if data is None:
94
- return get_store(project, source).read_df(
93
+ return get_store(source).read_df(
95
94
  source,
96
95
  file_format=file_format,
97
96
  engine=engine,
@@ -17,6 +17,7 @@ class VolumeType(Enum):
17
17
 
18
18
  PERSISTENT_VOLUME_CLAIM = "persistent_volume_claim"
19
19
  EMPTY_DIR = "empty_dir"
20
+ EPHEMERAL = "ephemeral"
20
21
 
21
22
 
22
23
  class SpecEmptyDir(BaseModel):
@@ -24,7 +25,7 @@ class SpecEmptyDir(BaseModel):
24
25
  Spec empty dir model.
25
26
  """
26
27
 
27
- size_limit: str
28
+ size_limit: Optional[str] = None
28
29
 
29
30
  medium: Optional[str] = None
30
31
 
@@ -34,7 +35,15 @@ class SpecPVC(BaseModel):
34
35
  Spec PVC model.
35
36
  """
36
37
 
37
- size: str
38
+ size: Optional[str] = None
39
+
40
+
41
+ class SpecEphemeral(BaseModel):
42
+ """
43
+ Ephemeral volume model.
44
+ """
45
+
46
+ size: Optional[str] = None
38
47
 
39
48
 
40
49
  class Volume(BaseModel):
@@ -53,7 +62,7 @@ class Volume(BaseModel):
53
62
  mount_path: str
54
63
  """Volume mount path inside the container."""
55
64
 
56
- spec: Optional[Union[SpecEmptyDir, SpecPVC]] = None
65
+ spec: Optional[Union[SpecEmptyDir, SpecPVC, SpecEphemeral]] = None
57
66
  """Volume spec."""
58
67
 
59
68
 
@@ -55,9 +55,13 @@ class Factory:
55
55
  ----------
56
56
  name : str
57
57
  The unique identifier for the builder.
58
- builder : EntityBuilder | RuntimeEntityBuilder
58
+ builder : EntityBuilder or RuntimeEntityBuilder
59
59
  The builder instance to register.
60
60
 
61
+ Returns
62
+ -------
63
+ None
64
+
61
65
  Raises
62
66
  ------
63
67
  BuilderError
@@ -78,6 +82,10 @@ class Factory:
78
82
  builder : RuntimeBuilder
79
83
  The builder instance to register.
80
84
 
85
+ Returns
86
+ -------
87
+ None
88
+
81
89
  Raises
82
90
  ------
83
91
  BuilderError
@@ -137,6 +145,8 @@ class Factory:
137
145
  ----------
138
146
  kind_to_build_from : str
139
147
  Entity type.
148
+ **kwargs
149
+ Additional spec parameters.
140
150
 
141
151
  Returns
142
152
  -------
@@ -154,6 +164,8 @@ class Factory:
154
164
  ----------
155
165
  kind_to_build_from : str
156
166
  Entity type.
167
+ **kwargs
168
+ Additional metadata parameters.
157
169
 
158
170
  Returns
159
171
  -------
@@ -171,6 +183,8 @@ class Factory:
171
183
  ----------
172
184
  kind_to_build_from : str
173
185
  Entity type.
186
+ **kwargs
187
+ Additional status parameters.
174
188
 
175
189
  Returns
176
190
  -------
@@ -265,7 +279,7 @@ class Factory:
265
279
 
266
280
  Returns
267
281
  -------
268
- list[str]
282
+ list of str
269
283
  Task kinds.
270
284
  """
271
285
  self._raise_if_entity_builder_not_found(kind)
@@ -299,7 +313,7 @@ class Factory:
299
313
 
300
314
  Returns
301
315
  -------
302
- list[str]
316
+ list of str
303
317
  All kinds.
304
318
  """
305
319
  return self._entity_builders[kind].get_all_kinds()
@@ -330,6 +344,10 @@ class Factory:
330
344
  kind : str
331
345
  The entity kind to verify.
332
346
 
347
+ Returns
348
+ -------
349
+ None
350
+
333
351
  Raises
334
352
  ------
335
353
  BuilderError
@@ -347,6 +365,10 @@ class Factory:
347
365
  kind : str
348
366
  The runtime kind to verify.
349
367
 
368
+ Returns
369
+ -------
370
+ None
371
+
350
372
  Raises
351
373
  ------
352
374
  BuilderError
@@ -50,7 +50,7 @@ def list_runtimes() -> list[str]:
50
50
 
51
51
  Returns
52
52
  -------
53
- list[str]
53
+ list of str
54
54
  List of runtime package names.
55
55
 
56
56
  Raises
@@ -75,6 +75,10 @@ def register_runtimes_entities() -> None:
75
75
 
76
76
  Imports each runtime package and registers its entity and runtime
77
77
  builders with the global factory instance.
78
+
79
+ Returns
80
+ -------
81
+ None
78
82
  """
79
83
  for package in list_runtimes():
80
84
  module = import_module(package)
@@ -93,8 +97,12 @@ def register_entities() -> None:
93
97
  """
94
98
  Register core entity builders into the factory.
95
99
 
96
- Imports the core entities module and registers all entity builders
97
- with the global factory instance.
100
+ Imports the core entities module and registers all entity
101
+ builders with the global factory instance.
102
+
103
+ Returns
104
+ -------
105
+ None
98
106
 
99
107
  Raises
100
108
  ------
@@ -89,7 +89,7 @@ class Runtime:
89
89
  Function to execute.
90
90
  *args
91
91
  Function arguments.
92
- **kwargs : dict
92
+ **kwargs
93
93
  Function keyword arguments.
94
94
 
95
95
  Returns
@@ -34,12 +34,29 @@ class RuntimeBuilder:
34
34
  RUNTIME_CLASS: Runtime = None
35
35
 
36
36
  def __init__(self) -> None:
37
+ """
38
+ Initialize a RuntimeBuilder instance.
39
+
40
+ Raises
41
+ ------
42
+ BuilderError
43
+ If RUNTIME_CLASS is not set in the implementing class.
44
+ """
37
45
  if self.RUNTIME_CLASS is None:
38
46
  raise BuilderError("RUNTIME_CLASS must be set")
39
47
 
40
48
  def build(self, project: str, *args, **kwargs) -> Runtime:
41
49
  """
42
- Build runtime object.
50
+ Build a runtime object.
51
+
52
+ Parameters
53
+ ----------
54
+ project : str
55
+ The project identifier for the runtime instance.
56
+ *args
57
+ Additional positional arguments to pass to the Runtime constructor.
58
+ **kwargs
59
+ Additional keyword arguments to pass to the Runtime constructor.
43
60
 
44
61
  Returns
45
62
  -------
@@ -1,3 +1,15 @@
1
1
  # SPDX-FileCopyrightText: © 2025 DSLab - Fondazione Bruno Kessler
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Client module for DigitalHub SDK.
7
+
8
+ This module provides client implementations for interacting with different
9
+ backends:
10
+ - Local client for in-memory operations
11
+ - DHCore client for remote backend communication
12
+
13
+ The main entry point is through the get_client function which returns
14
+ the appropriate client instance based on the configuration.
15
+ """
@@ -17,4 +17,18 @@ class ClientApiBuilder:
17
17
  def build_api(self, category: str, operation: str, **kwargs) -> str:
18
18
  """
19
19
  Build the API for the client.
20
+
21
+ Parameters
22
+ ----------
23
+ category : str
24
+ The API category.
25
+ operation : str
26
+ The API operation.
27
+ **kwargs : dict
28
+ Additional keyword arguments.
29
+
30
+ Returns
31
+ -------
32
+ str
33
+ The formatted API endpoint.
20
34
  """
@@ -36,42 +36,130 @@ class Client:
36
36
  def create_object(self, api: str, obj: Any, **kwargs) -> dict:
37
37
  """
38
38
  Create object method.
39
+
40
+ Parameters
41
+ ----------
42
+ api : str
43
+ The API endpoint to create the object.
44
+ obj : Any
45
+ The object to create.
46
+ **kwargs : dict
47
+ Additional keyword arguments.
48
+
49
+ Returns
50
+ -------
51
+ dict
52
+ The created object.
39
53
  """
40
54
 
41
55
  @abstractmethod
42
56
  def read_object(self, api: str, **kwargs) -> dict:
43
57
  """
44
58
  Read object method.
59
+
60
+ Parameters
61
+ ----------
62
+ api : str
63
+ The API endpoint to read the object.
64
+ **kwargs : dict
65
+ Additional keyword arguments.
66
+
67
+ Returns
68
+ -------
69
+ dict
70
+ The retrieved object.
45
71
  """
46
72
 
47
73
  @abstractmethod
48
74
  def update_object(self, api: str, obj: Any, **kwargs) -> dict:
49
75
  """
50
76
  Update object method.
77
+
78
+ Parameters
79
+ ----------
80
+ api : str
81
+ The API endpoint to update the object.
82
+ obj : Any
83
+ The object to update.
84
+ **kwargs : dict
85
+ Additional keyword arguments.
86
+
87
+ Returns
88
+ -------
89
+ dict
90
+ The updated object.
51
91
  """
52
92
 
53
93
  @abstractmethod
54
94
  def delete_object(self, api: str, **kwargs) -> dict:
55
95
  """
56
96
  Delete object method.
97
+
98
+ Parameters
99
+ ----------
100
+ api : str
101
+ The API endpoint to delete the object.
102
+ **kwargs : dict
103
+ Additional keyword arguments.
104
+
105
+ Returns
106
+ -------
107
+ dict
108
+ The deletion result.
57
109
  """
58
110
 
59
111
  @abstractmethod
60
112
  def list_objects(self, api: str, **kwargs) -> dict:
61
113
  """
62
114
  List objects method.
115
+
116
+ Parameters
117
+ ----------
118
+ api : str
119
+ The API endpoint to list objects.
120
+ **kwargs : dict
121
+ Additional keyword arguments.
122
+
123
+ Returns
124
+ -------
125
+ dict
126
+ The list of objects.
63
127
  """
64
128
 
65
129
  @abstractmethod
66
130
  def list_first_object(self, api: str, **kwargs) -> dict:
67
131
  """
68
132
  Read first object method.
133
+
134
+ Parameters
135
+ ----------
136
+ api : str
137
+ The API endpoint to read the first object.
138
+ **kwargs : dict
139
+ Additional keyword arguments.
140
+
141
+ Returns
142
+ -------
143
+ dict
144
+ The first object in the list.
69
145
  """
70
146
 
71
147
  @abstractmethod
72
148
  def search_objects(self, api: str, **kwargs) -> dict:
73
149
  """
74
150
  Search objects method.
151
+
152
+ Parameters
153
+ ----------
154
+ api : str
155
+ The API endpoint to search objects.
156
+ **kwargs : dict
157
+ Additional keyword arguments containing search parameters.
158
+
159
+ Returns
160
+ -------
161
+ dict
162
+ The search results.
75
163
  """
76
164
 
77
165
  ##############################
@@ -147,4 +235,9 @@ class Client:
147
235
  def is_local() -> bool:
148
236
  """
149
237
  Flag to check if client is local.
238
+
239
+ Returns
240
+ -------
241
+ bool
242
+ True if the client operates locally, False otherwise.
150
243
  """
@@ -40,6 +40,16 @@ class ClientKeyBuilder:
40
40
  def base_entity_key(self, entity_id: str) -> str:
41
41
  """
42
42
  Build for base entity key.
43
+
44
+ Parameters
45
+ ----------
46
+ entity_id : str
47
+ The entity identifier.
48
+
49
+ Returns
50
+ -------
51
+ str
52
+ The formatted base entity key.
43
53
  """
44
54
 
45
55
  @abstractmethod
@@ -53,4 +63,22 @@ class ClientKeyBuilder:
53
63
  ) -> str:
54
64
  """
55
65
  Build for context entity key.
66
+
67
+ Parameters
68
+ ----------
69
+ project : str
70
+ The project name.
71
+ entity_type : str
72
+ The entity type.
73
+ entity_kind : str
74
+ The entity kind.
75
+ entity_name : str
76
+ The entity name.
77
+ entity_id : str, optional
78
+ The entity identifier. If None, key will not include version.
79
+
80
+ Returns
81
+ -------
82
+ str
83
+ The formatted context entity key.
56
84
  """
@@ -17,4 +17,18 @@ class ClientParametersBuilder:
17
17
  def build_parameters(self, category: str, operation: str, **kwargs) -> dict:
18
18
  """
19
19
  Build the parameters for the client call.
20
+
21
+ Parameters
22
+ ----------
23
+ category : str
24
+ The API category.
25
+ operation : str
26
+ The API operation.
27
+ **kwargs : dict
28
+ Additional keyword arguments to build parameters from.
29
+
30
+ Returns
31
+ -------
32
+ dict
33
+ The formatted parameters for the client call.
20
34
  """
@@ -18,14 +18,19 @@ def get_client(local: bool = False, config: dict | None = None) -> Client:
18
18
 
19
19
  Parameters
20
20
  ----------
21
- local : bool
22
- Whether to create a local client or not.
23
- config : dict
24
- DHCore environment configuration.
21
+ local : bool, default False
22
+ Whether to create a local client or not. If True, creates a
23
+ ClientLocal instance that operates in-memory. If False, creates
24
+ a ClientDHCore instance that communicates with a remote backend.
25
+ config : dict, optional
26
+ DHCore environment configuration. Only used when local=False.
27
+ If None, configuration will be loaded from environment variables
28
+ and configuration files.
25
29
 
26
30
  Returns
27
31
  -------
28
32
  Client
29
- The client instance.
33
+ The client instance. Either ClientLocal or ClientDHCore depending
34
+ on the local parameter.
30
35
  """
31
36
  return client_builder.build(local, config)
@@ -33,8 +33,10 @@ class ClientBuilder:
33
33
 
34
34
  Parameters
35
35
  ----------
36
- local : bool
36
+ local : bool, default False
37
37
  Whether to create a local client or not.
38
+ config : dict, optional
39
+ DHCore environment configuration.
38
40
 
39
41
  Returns
40
42
  -------