digitalhub 0.13.0b2__py3-none-any.whl → 0.13.0b4__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 (61) 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/_commons/metrics.py +64 -30
  7. digitalhub/entities/_commons/utils.py +36 -9
  8. digitalhub/entities/_processors/base.py +150 -79
  9. digitalhub/entities/_processors/context.py +363 -212
  10. digitalhub/entities/_processors/utils.py +74 -30
  11. digitalhub/entities/artifact/utils.py +28 -13
  12. digitalhub/entities/dataitem/crud.py +10 -2
  13. digitalhub/entities/dataitem/table/entity.py +3 -3
  14. digitalhub/entities/dataitem/utils.py +84 -35
  15. digitalhub/entities/model/utils.py +28 -13
  16. digitalhub/entities/task/_base/models.py +12 -3
  17. digitalhub/factory/factory.py +25 -3
  18. digitalhub/factory/utils.py +11 -3
  19. digitalhub/runtimes/_base.py +1 -1
  20. digitalhub/runtimes/builder.py +18 -1
  21. digitalhub/stores/client/__init__.py +12 -0
  22. digitalhub/stores/client/_base/api_builder.py +14 -0
  23. digitalhub/stores/client/_base/client.py +93 -0
  24. digitalhub/stores/client/_base/key_builder.py +28 -0
  25. digitalhub/stores/client/_base/params_builder.py +14 -0
  26. digitalhub/stores/client/api.py +10 -5
  27. digitalhub/stores/client/builder.py +3 -1
  28. digitalhub/stores/client/dhcore/api_builder.py +17 -0
  29. digitalhub/stores/client/dhcore/client.py +276 -58
  30. digitalhub/stores/client/dhcore/configurator.py +336 -141
  31. digitalhub/stores/client/dhcore/error_parser.py +35 -1
  32. digitalhub/stores/client/dhcore/params_builder.py +113 -17
  33. digitalhub/stores/client/dhcore/utils.py +32 -14
  34. digitalhub/stores/client/local/api_builder.py +17 -0
  35. digitalhub/stores/client/local/client.py +6 -8
  36. digitalhub/stores/credentials/api.py +8 -8
  37. digitalhub/stores/credentials/configurator.py +176 -3
  38. digitalhub/stores/credentials/enums.py +17 -3
  39. digitalhub/stores/credentials/handler.py +73 -45
  40. digitalhub/stores/credentials/ini_module.py +59 -27
  41. digitalhub/stores/credentials/store.py +33 -1
  42. digitalhub/stores/data/_base/store.py +8 -3
  43. digitalhub/stores/data/api.py +20 -16
  44. digitalhub/stores/data/builder.py +69 -13
  45. digitalhub/stores/data/s3/configurator.py +64 -23
  46. digitalhub/stores/data/s3/store.py +30 -27
  47. digitalhub/stores/data/s3/utils.py +9 -9
  48. digitalhub/stores/data/sql/configurator.py +76 -25
  49. digitalhub/stores/data/sql/store.py +180 -91
  50. digitalhub/utils/exceptions.py +6 -0
  51. digitalhub/utils/file_utils.py +53 -30
  52. digitalhub/utils/generic_utils.py +41 -33
  53. digitalhub/utils/git_utils.py +24 -14
  54. digitalhub/utils/io_utils.py +19 -18
  55. digitalhub/utils/uri_utils.py +31 -31
  56. {digitalhub-0.13.0b2.dist-info → digitalhub-0.13.0b4.dist-info}/METADATA +1 -1
  57. {digitalhub-0.13.0b2.dist-info → digitalhub-0.13.0b4.dist-info}/RECORD +60 -61
  58. digitalhub/entities/_commons/types.py +0 -9
  59. {digitalhub-0.13.0b2.dist-info → digitalhub-0.13.0b4.dist-info}/WHEEL +0 -0
  60. {digitalhub-0.13.0b2.dist-info → digitalhub-0.13.0b4.dist-info}/licenses/AUTHORS +0 -0
  61. {digitalhub-0.13.0b2.dist-info → digitalhub-0.13.0b4.dist-info}/licenses/LICENSE +0 -0
@@ -26,23 +26,36 @@ def parse_identifier(
26
26
  entity_id: str | None = None,
27
27
  ) -> tuple[str, str, str | None, str | None, str | None]:
28
28
  """
29
- Parse entity identifier.
29
+ Parse and validate entity identifier into its components.
30
+
31
+ Processes an entity identifier that can be either a full entity key
32
+ (store://) or a simple entity name. When using a simple name,
33
+ additional parameters must be provided for proper identification.
30
34
 
31
35
  Parameters
32
36
  ----------
33
37
  identifier : str
34
- Entity key (store://...) or entity name.
35
- project : str
36
- Project name.
37
- entity_type : str
38
- Entity type.
39
- entity_id : str
40
- Entity ID.
38
+ The entity identifier to parse. Can be either a full entity key
39
+ (store://project/entity_type/kind/name:id) or a simple entity name.
40
+ project : str, optional
41
+ The project name. Required when identifier is not a full key.
42
+ entity_type : str, optional
43
+ The entity type. Required when identifier is not a full key.
44
+ entity_kind : str, optional
45
+ The entity kind specification.
46
+ entity_id : str, optional
47
+ The entity version identifier.
41
48
 
42
49
  Returns
43
50
  -------
44
51
  tuple[str, str, str | None, str | None, str | None]
45
- Project name, entity type, entity kind, entity name, entity ID.
52
+ A tuple containing (project_name, entity_type, entity_kind,
53
+ entity_name, entity_id) parsed from the identifier.
54
+
55
+ Raises
56
+ ------
57
+ ValueError
58
+ If identifier is not a full key and project or entity_type is None.
46
59
  """
47
60
  if not identifier.startswith("store://"):
48
61
  if project is None or entity_type is None:
@@ -56,19 +69,29 @@ def get_context_from_identifier(
56
69
  project: str | None = None,
57
70
  ) -> Context:
58
71
  """
59
- Get context from project.
72
+ Retrieve context instance from entity identifier or project name.
73
+
74
+ Extracts project information from the identifier and returns the
75
+ corresponding context. If the identifier is not a full key, the
76
+ project parameter must be provided explicitly.
60
77
 
61
78
  Parameters
62
79
  ----------
63
80
  identifier : str
64
- Entity key (store://...) or entity name.
65
- project : str
66
- Project name.
81
+ The entity identifier to extract context from. Can be either
82
+ a full entity key (store://...) or a simple entity name.
83
+ project : str, optional
84
+ The project name. Required when identifier is not a full key.
67
85
 
68
86
  Returns
69
87
  -------
70
88
  Context
71
- Context.
89
+ The context instance associated with the identified project.
90
+
91
+ Raises
92
+ ------
93
+ EntityError
94
+ If identifier is not a full key and project parameter is None.
72
95
  """
73
96
  if not identifier.startswith("store://"):
74
97
  if project is None:
@@ -83,19 +106,26 @@ def get_context_from_project(
83
106
  project: str,
84
107
  ) -> Context:
85
108
  """
86
- Check if the given project is in the context.
87
- Otherwise try to get the project from remote.
88
- Finally return the client.
109
+ Retrieve context for a project, fetching from remote if necessary.
110
+
111
+ Attempts to get the project context from the local cache first.
112
+ If the project is not found locally, tries to fetch it from the
113
+ remote backend and create the context.
89
114
 
90
115
  Parameters
91
116
  ----------
92
117
  project : str
93
- Project name.
118
+ The name of the project to get context for.
94
119
 
95
120
  Returns
96
121
  -------
97
122
  Context
98
- Context.
123
+ The context instance for the specified project.
124
+
125
+ Raises
126
+ ------
127
+ ContextError
128
+ If the project cannot be found locally or remotely.
99
129
  """
100
130
  try:
101
131
  return get_context(project)
@@ -105,19 +135,28 @@ def get_context_from_project(
105
135
 
106
136
  def get_context_from_remote(
107
137
  project: str,
108
- ) -> Client:
138
+ ) -> Context:
109
139
  """
110
- Get context from remote.
140
+ Fetch project context from remote backend and create local context.
141
+
142
+ Retrieves project information from the remote backend, builds the
143
+ project entity locally, and returns the corresponding context.
144
+ Used when a project is not available in the local context cache.
111
145
 
112
146
  Parameters
113
147
  ----------
114
148
  project : str
115
- Project name.
149
+ The name of the project to fetch from remote.
116
150
 
117
151
  Returns
118
152
  -------
119
- Client
120
- Client.
153
+ Context
154
+ The context instance created from the remote project data.
155
+
156
+ Raises
157
+ ------
158
+ ContextError
159
+ If the project is not found on the remote backend.
121
160
  """
122
161
  try:
123
162
  client = get_client()
@@ -135,23 +174,28 @@ def _read_base_entity(
135
174
  **kwargs,
136
175
  ) -> dict:
137
176
  """
138
- Read object from backend.
177
+ Read entity data from the backend API.
178
+
179
+ Internal utility function that performs a base-level entity read
180
+ operation through the client API. Builds the appropriate API
181
+ endpoint and retrieves the entity data as a dictionary.
139
182
 
140
183
  Parameters
141
184
  ----------
142
185
  client : Client
143
- Client instance.
186
+ The client instance to use for the API request.
144
187
  entity_type : str
145
- Entity type.
188
+ The type of entity to read (e.g., 'project', 'function').
146
189
  entity_name : str
147
- Entity name.
190
+ The name identifier of the entity to retrieve.
148
191
  **kwargs : dict
149
- Parameters to pass to the API call.
192
+ Additional parameters to pass to the API call, such as
193
+ version specifications or query filters.
150
194
 
151
195
  Returns
152
196
  -------
153
197
  dict
154
- Object instance.
198
+ Dictionary containing the entity data retrieved from the backend.
155
199
  """
156
200
  api = client.build_api(
157
201
  ApiCategories.BASE.value,
@@ -15,16 +15,23 @@ def eval_source(
15
15
  source: str | list[str] | None = None,
16
16
  ) -> Any:
17
17
  """
18
- Evaluate if source is local.
18
+ Evaluate whether the source is local or remote.
19
+
20
+ Determines if the provided source(s) reference local files or
21
+ remote resources. This evaluation affects how the artifact
22
+ will be processed and stored.
19
23
 
20
24
  Parameters
21
25
  ----------
22
- source : str | list[str]
23
- Source(s).
26
+ source : str, list[str], or None, optional
27
+ The source specification(s) to evaluate. Can be a single
28
+ source string, a list of source strings, or None.
24
29
 
25
30
  Returns
26
31
  -------
27
- None
32
+ Any
33
+ The result of the local source evaluation, indicating
34
+ whether the source is local or remote.
28
35
  """
29
36
  return eval_local_source(source)
30
37
 
@@ -37,25 +44,33 @@ def process_kwargs(
37
44
  **kwargs,
38
45
  ) -> dict:
39
46
  """
40
- Process spec kwargs.
47
+ Process and enhance specification parameters for artifact creation.
48
+
49
+ Processes the keyword arguments for artifact specification, handling
50
+ path generation and UUID assignment. If no path is provided, generates
51
+ a unique path based on project, entity type, name, and source.
41
52
 
42
53
  Parameters
43
54
  ----------
44
55
  project : str
45
- Project name.
56
+ The name of the project.
46
57
  name : str
47
- Object name.
48
- source : str
49
- Source(s).
50
- path : str
51
- Destination path of the entity. If not provided, it's generated.
58
+ The name of the artifact entity.
59
+ source : str or list[str]
60
+ The source specification(s) for the artifact content.
61
+ Can be a single source or multiple sources.
62
+ path : str, optional
63
+ The destination path for the artifact entity.
64
+ If None, a path will be automatically generated.
52
65
  **kwargs : dict
53
- Spec parameters.
66
+ Additional specification parameters to be processed
67
+ and passed to the artifact creation.
54
68
 
55
69
  Returns
56
70
  -------
57
71
  dict
58
- Kwargs updated.
72
+ The updated kwargs dictionary with processed path
73
+ and UUID information included.
59
74
  """
60
75
  if path is None:
61
76
  uuid = build_uuid()
@@ -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,
@@ -33,16 +33,39 @@ def eval_source(
33
33
  project: str | None = None,
34
34
  ) -> Any:
35
35
  """
36
- Evaluate if source is local.
36
+ Evaluate and process data source for dataitem creation.
37
+
38
+ Determines the appropriate source handling based on whether a source
39
+ path or data object is provided. For table dataitems with data objects,
40
+ writes the data to a Parquet file and returns the file path.
37
41
 
38
42
  Parameters
39
43
  ----------
40
- source : SourcesOrListOfSources
41
- Source(s).
44
+ source : SourcesOrListOfSources, optional
45
+ The source specification(s) for the dataitem. Can be file paths,
46
+ URLs, or other source identifiers.
47
+ data : Any, optional
48
+ The data object to process (e.g., DataFrame). Alternative to source.
49
+ Exactly one of source or data must be provided.
50
+ kind : str, optional
51
+ The kind of dataitem being created (e.g., 'table').
52
+ name : str, optional
53
+ The name of the dataitem, used for generating file paths.
54
+ project : str, optional
55
+ The project name, used for context and path generation.
42
56
 
43
57
  Returns
44
58
  -------
45
- None
59
+ Any
60
+ The processed source. Returns the original source if provided,
61
+ or the path to a generated file if data was processed.
62
+
63
+ Raises
64
+ ------
65
+ ValueError
66
+ If both source and data are provided or both are None.
67
+ NotImplementedError
68
+ If the specified kind is not supported for data processing.
46
69
  """
47
70
  if (source is None) == (data is None):
48
71
  raise ValueError("You must provide source or data.")
@@ -62,7 +85,6 @@ def eval_source(
62
85
 
63
86
 
64
87
  def eval_data(
65
- project: str,
66
88
  kind: str,
67
89
  source: SourcesOrListOfSources,
68
90
  data: Any | None = None,
@@ -70,28 +92,36 @@ def eval_data(
70
92
  engine: str | None = None,
71
93
  ) -> Any:
72
94
  """
73
- Evaluate data is loaded.
95
+ Evaluate and load data from source or return provided data.
96
+
97
+ For table dataitems, loads data from the source using the appropriate
98
+ store and reader. For other kinds, returns the data as-is.
74
99
 
75
100
  Parameters
76
101
  ----------
77
- project : str
78
- Project name.
79
- source : str
80
- Source(s).
81
- data : Any
82
- Dataframe to log. Alternative to source.
83
- file_format : str
84
- Extension of the file.
85
- engine : str
86
- Engine to use.
102
+ kind : str
103
+ The kind of dataitem (e.g., 'table') that determines
104
+ how data should be processed.
105
+ source : SourcesOrListOfSources
106
+ The source specification(s) to load data from.
107
+ data : Any, optional
108
+ Pre-loaded data object. If provided, may be returned directly
109
+ depending on the dataitem kind.
110
+ file_format : str, optional
111
+ The file format specification for reading the source
112
+ (e.g., 'parquet', 'csv').
113
+ engine : str, optional
114
+ The engine to use for reading the data (e.g., 'pandas', 'polars').
87
115
 
88
116
  Returns
89
117
  -------
90
- None
118
+ Any
119
+ The loaded data object for table dataitems, or the original
120
+ data parameter for other kinds.
91
121
  """
92
122
  if kind == EntityKinds.DATAITEM_TABLE.value:
93
123
  if data is None:
94
- return get_store(project, source).read_df(
124
+ return get_store(source).read_df(
95
125
  source,
96
126
  file_format=file_format,
97
127
  engine=engine,
@@ -109,29 +139,37 @@ def process_kwargs(
109
139
  **kwargs,
110
140
  ) -> dict:
111
141
  """
112
- Process spec kwargs.
142
+ Process and enhance specification parameters for dataitem creation.
143
+
144
+ Processes the keyword arguments for dataitem specification, handling
145
+ schema extraction for table dataitems and path generation. Extracts
146
+ schema information from data objects when available.
113
147
 
114
148
  Parameters
115
149
  ----------
116
150
  project : str
117
- Project name.
151
+ The name of the project.
118
152
  name : str
119
- Object name.
153
+ The name of the dataitem entity.
120
154
  kind : str
121
- Kind the object.
155
+ The kind of dataitem being created (e.g., 'table').
122
156
  source : SourcesOrListOfSources
123
- Source(s).
124
- data : Any
125
- Dataframe to log. Alternative to source.
126
- path : str
127
- Destination path of the entity. If not provided, it's generated.
157
+ The source specification(s) for the dataitem content.
158
+ data : Any, optional
159
+ The data object for schema extraction and processing.
160
+ Used as an alternative to source for table dataitems.
161
+ path : str, optional
162
+ The destination path for the dataitem entity.
163
+ If None, a path will be automatically generated.
128
164
  **kwargs : dict
129
- Spec parameters.
165
+ Additional specification parameters to be processed
166
+ and passed to the dataitem creation.
130
167
 
131
168
  Returns
132
169
  -------
133
170
  dict
134
- Kwargs updated.
171
+ The updated kwargs dictionary with processed path,
172
+ UUID, and schema information included.
135
173
  """
136
174
  if data is not None:
137
175
  if kind == EntityKinds.DATAITEM_TABLE.value:
@@ -148,12 +186,17 @@ def process_kwargs(
148
186
 
149
187
  def clean_tmp_path(pth: SourcesOrListOfSources) -> None:
150
188
  """
151
- Clean temporary path.
189
+ Clean up temporary files and directories.
190
+
191
+ Removes temporary files or directories created during dataitem
192
+ processing. Handles both single paths and lists of paths,
193
+ ignoring any errors that occur during cleanup.
152
194
 
153
195
  Parameters
154
196
  ----------
155
197
  pth : SourcesOrListOfSources
156
- Path to clean.
198
+ The path or list of paths to clean up. Can be file paths
199
+ or directory paths that need to be removed.
157
200
 
158
201
  Returns
159
202
  -------
@@ -168,19 +211,25 @@ def clean_tmp_path(pth: SourcesOrListOfSources) -> None:
168
211
 
169
212
  def post_process(obj: Dataitem, data: Any) -> Dataitem:
170
213
  """
171
- Post process object.
214
+ Post-process dataitem object with additional metadata and previews.
215
+
216
+ Enhances the dataitem object with additional information extracted
217
+ from the data. For table dataitems, generates and stores a data
218
+ preview in the object's status.
172
219
 
173
220
  Parameters
174
221
  ----------
175
222
  obj : Dataitem
176
- The object.
223
+ The dataitem object to post-process and enhance.
177
224
  data : Any
178
- The data.
225
+ The data object used to generate previews and extract
226
+ additional metadata information.
179
227
 
180
228
  Returns
181
229
  -------
182
230
  Dataitem
183
- The object.
231
+ The enhanced dataitem object with updated status information
232
+ and saved changes.
184
233
  """
185
234
  if obj.kind == EntityKinds.DATAITEM_TABLE.value:
186
235
  reader = get_reader_by_object(data)
@@ -15,16 +15,23 @@ def eval_source(
15
15
  source: str | list[str] | None = None,
16
16
  ) -> Any:
17
17
  """
18
- Evaluate if source is local.
18
+ Evaluate whether the source is local or remote.
19
+
20
+ Determines if the provided source(s) reference local files or
21
+ remote resources. This evaluation affects how the model
22
+ will be processed and stored.
19
23
 
20
24
  Parameters
21
25
  ----------
22
- source : str | list[str]
23
- Source(s).
26
+ source : str, list[str], or None, optional
27
+ The source specification(s) to evaluate. Can be a single
28
+ source string, a list of source strings, or None.
24
29
 
25
30
  Returns
26
31
  -------
27
- None
32
+ Any
33
+ The result of the local source evaluation, indicating
34
+ whether the source is local or remote.
28
35
  """
29
36
  return eval_local_source(source)
30
37
 
@@ -37,25 +44,33 @@ def process_kwargs(
37
44
  **kwargs,
38
45
  ) -> dict:
39
46
  """
40
- Process spec kwargs.
47
+ Process and enhance specification parameters for model creation.
48
+
49
+ Processes the keyword arguments for model specification, handling
50
+ path generation and UUID assignment. If no path is provided, generates
51
+ a unique path based on project, entity type, name, and source.
41
52
 
42
53
  Parameters
43
54
  ----------
44
55
  project : str
45
- Project name.
56
+ The name of the project containing the model.
46
57
  name : str
47
- Object name.
48
- source : str
49
- Source(s).
50
- path : str
51
- Destination path of the entity. If not provided, it's generated.
58
+ The name of the model entity.
59
+ source : str or list[str]
60
+ The source specification(s) for the model content.
61
+ Can be a single source or multiple sources.
62
+ path : str, optional
63
+ The destination path for the model entity.
64
+ If None, a path will be automatically generated.
52
65
  **kwargs : dict
53
- Spec parameters.
66
+ Additional specification parameters to be processed
67
+ and passed to the model creation.
54
68
 
55
69
  Returns
56
70
  -------
57
71
  dict
58
- Kwargs updated.
72
+ The updated kwargs dictionary with processed path
73
+ and UUID information included.
59
74
  """
60
75
  if path is None:
61
76
  uuid = build_uuid()
@@ -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