digitalhub 0.13.0b3__py3-none-any.whl → 0.14.0b0__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 (67) hide show
  1. digitalhub/__init__.py +3 -8
  2. digitalhub/entities/_base/_base/entity.py +0 -11
  3. digitalhub/entities/_base/entity/builder.py +5 -5
  4. digitalhub/entities/_base/executable/entity.py +1 -1
  5. digitalhub/entities/_base/runtime_entity/builder.py +53 -18
  6. digitalhub/entities/_commons/metrics.py +64 -30
  7. digitalhub/entities/_commons/utils.py +100 -30
  8. digitalhub/entities/_processors/base.py +160 -81
  9. digitalhub/entities/_processors/context.py +424 -224
  10. digitalhub/entities/_processors/utils.py +77 -33
  11. digitalhub/entities/artifact/crud.py +20 -4
  12. digitalhub/entities/artifact/utils.py +29 -14
  13. digitalhub/entities/dataitem/crud.py +20 -4
  14. digitalhub/entities/dataitem/table/entity.py +0 -21
  15. digitalhub/entities/dataitem/utils.py +84 -34
  16. digitalhub/entities/function/_base/entity.py +1 -1
  17. digitalhub/entities/function/crud.py +15 -4
  18. digitalhub/entities/model/_base/entity.py +21 -1
  19. digitalhub/entities/model/crud.py +21 -5
  20. digitalhub/entities/model/utils.py +29 -14
  21. digitalhub/entities/project/_base/entity.py +65 -33
  22. digitalhub/entities/project/crud.py +8 -1
  23. digitalhub/entities/run/_base/entity.py +21 -1
  24. digitalhub/entities/run/crud.py +22 -5
  25. digitalhub/entities/secret/crud.py +22 -5
  26. digitalhub/entities/task/crud.py +22 -5
  27. digitalhub/entities/trigger/crud.py +20 -4
  28. digitalhub/entities/workflow/_base/entity.py +1 -1
  29. digitalhub/entities/workflow/crud.py +15 -4
  30. digitalhub/factory/enums.py +18 -0
  31. digitalhub/factory/factory.py +136 -57
  32. digitalhub/factory/utils.py +3 -54
  33. digitalhub/stores/client/api.py +6 -10
  34. digitalhub/stores/client/builder.py +3 -3
  35. digitalhub/stores/client/dhcore/client.py +104 -162
  36. digitalhub/stores/client/dhcore/configurator.py +92 -289
  37. digitalhub/stores/client/dhcore/enums.py +0 -16
  38. digitalhub/stores/client/dhcore/params_builder.py +41 -83
  39. digitalhub/stores/client/dhcore/utils.py +14 -22
  40. digitalhub/stores/client/local/client.py +77 -45
  41. digitalhub/stores/credentials/enums.py +1 -0
  42. digitalhub/stores/credentials/ini_module.py +0 -16
  43. digitalhub/stores/data/api.py +1 -1
  44. digitalhub/stores/data/builder.py +66 -4
  45. digitalhub/stores/data/local/store.py +0 -103
  46. digitalhub/stores/data/s3/configurator.py +60 -6
  47. digitalhub/stores/data/s3/store.py +44 -2
  48. digitalhub/stores/data/sql/configurator.py +57 -7
  49. digitalhub/stores/data/sql/store.py +184 -78
  50. digitalhub/utils/file_utils.py +0 -17
  51. digitalhub/utils/generic_utils.py +1 -2
  52. digitalhub/utils/store_utils.py +44 -0
  53. {digitalhub-0.13.0b3.dist-info → digitalhub-0.14.0b0.dist-info}/METADATA +3 -2
  54. {digitalhub-0.13.0b3.dist-info → digitalhub-0.14.0b0.dist-info}/RECORD +63 -65
  55. digitalhub/entities/_commons/types.py +0 -9
  56. digitalhub/entities/task/_base/utils.py +0 -22
  57. digitalhub/stores/client/dhcore/models.py +0 -40
  58. digitalhub/stores/data/s3/utils.py +0 -78
  59. /digitalhub/entities/{_base/entity/_constructors → _constructors}/__init__.py +0 -0
  60. /digitalhub/entities/{_base/entity/_constructors → _constructors}/metadata.py +0 -0
  61. /digitalhub/entities/{_base/entity/_constructors → _constructors}/name.py +0 -0
  62. /digitalhub/entities/{_base/entity/_constructors → _constructors}/spec.py +0 -0
  63. /digitalhub/entities/{_base/entity/_constructors → _constructors}/status.py +0 -0
  64. /digitalhub/entities/{_base/entity/_constructors → _constructors}/uuid.py +0 -0
  65. {digitalhub-0.13.0b3.dist-info → digitalhub-0.14.0b0.dist-info}/WHEEL +0 -0
  66. {digitalhub-0.13.0b3.dist-info → digitalhub-0.14.0b0.dist-info}/licenses/AUTHORS +0 -0
  67. {digitalhub-0.13.0b3.dist-info → digitalhub-0.14.0b0.dist-info}/licenses/LICENSE +0 -0
@@ -12,18 +12,12 @@ class ClientDHCoreParametersBuilder(ClientParametersBuilder):
12
12
  """
13
13
  Parameter builder for DHCore client API calls.
14
14
 
15
- This class constructs HTTP request parameters for different DHCore API
16
- operations, handling the specific parameter formats and query structures
17
- required by the DigitalHub Core backend. It supports both base-level
18
- operations (like project management) and context-level operations
19
- (entity operations within projects).
20
-
21
- The builder handles various parameter transformations including:
22
- - Query parameter formatting for different operations
23
- - Search filter construction for Solr-based searches
24
- - Cascade deletion options
25
- - Versioning parameters
26
- - Entity sharing parameters
15
+ Constructs HTTP request parameters for DHCore API operations, handling
16
+ parameter formats and query structures for both base-level operations
17
+ (project management) and context-level operations (entity operations
18
+ within projects). Supports query parameter formatting, search filter
19
+ construction for Solr-based searches, cascade deletion options,
20
+ versioning parameters, and entity sharing parameters.
27
21
 
28
22
  Methods
29
23
  -------
@@ -39,36 +33,27 @@ class ClientDHCoreParametersBuilder(ClientParametersBuilder):
39
33
  """
40
34
  Build HTTP request parameters for DHCore API calls.
41
35
 
42
- Routes parameter building to the appropriate method based on the
43
- API category (base or context operations) and applies operation-specific
44
- parameter transformations.
36
+ Routes parameter building to appropriate method based on API category
37
+ (base or context operations) and applies operation-specific transformations.
38
+ Acts as dispatcher, initializing parameter dictionaries with 'params' key
39
+ for query parameters.
45
40
 
46
41
  Parameters
47
42
  ----------
48
43
  category : str
49
- The API category, either 'base' for project-level operations
50
- or 'context' for entity operations within projects.
44
+ API category: 'base' for project-level operations or 'context'
45
+ for entity operations within projects.
51
46
  operation : str
52
- The specific API operation being performed (create, read, update,
53
- delete, list, search, etc.).
47
+ Specific API operation (create, read, update, delete, list, search, etc.).
54
48
  **kwargs : dict
55
- Raw parameters to be transformed into proper HTTP request format.
56
- May include entity identifiers, filter criteria, pagination
57
- options, etc.
49
+ Raw parameters to transform including entity identifiers, filter
50
+ criteria, pagination options, etc.
58
51
 
59
52
  Returns
60
53
  -------
61
54
  dict
62
- Formatted parameters dictionary ready for HTTP request, typically
63
- containing a 'params' key with query parameters and other
64
- request-specific parameters.
65
-
66
- Notes
67
- -----
68
- This method acts as a dispatcher, routing to either base or context
69
- parameter building based on the category. All parameter dictionaries
70
- are initialized with a 'params' key for query parameters if not
71
- already present.
55
+ Formatted parameters dictionary with 'params' key for query parameters
56
+ and other request-specific parameters.
72
57
  """
73
58
  if category == ApiCategories.BASE.value:
74
59
  return self.build_parameters_base(operation, **kwargs)
@@ -78,18 +63,18 @@ class ClientDHCoreParametersBuilder(ClientParametersBuilder):
78
63
  """
79
64
  Build parameters for base-level API operations.
80
65
 
81
- Constructs HTTP request parameters for operations that work at the
82
- base level of the API, typically project-level operations and
83
- entity sharing functionality.
66
+ Constructs HTTP request parameters for project-level operations and
67
+ entity sharing functionality. Handles CASCADE (boolean to lowercase string),
68
+ SHARE (user parameter to query params), and UNSHARE (requires unshare=True
69
+ and entity id).
84
70
 
85
71
  Parameters
86
72
  ----------
87
73
  operation : str
88
- The API operation being performed. Supported operations:
89
- - DELETE: Project deletion with optional cascade
90
- - SHARE: Entity sharing/unsharing with users
74
+ API operation: DELETE (project deletion with optional cascade)
75
+ or SHARE (entity sharing/unsharing with users).
91
76
  **kwargs : dict
92
- Operation-specific parameters including:
77
+ Operation-specific parameters:
93
78
  - cascade (bool): For DELETE, whether to cascade delete
94
79
  - user (str): For SHARE, target user for sharing
95
80
  - unshare (bool): For SHARE, whether to unshare instead
@@ -98,15 +83,7 @@ class ClientDHCoreParametersBuilder(ClientParametersBuilder):
98
83
  Returns
99
84
  -------
100
85
  dict
101
- Formatted parameters with 'params' containing query parameters
102
- and other request-specific parameters.
103
-
104
- Notes
105
- -----
106
- Parameter transformations:
107
- - CASCADE: Boolean values are converted to lowercase strings
108
- - SHARE: User parameter is moved to query params
109
- - UNSHARE: Requires both unshare=True and entity id
86
+ Formatted parameters with 'params' containing query parameters.
110
87
  """
111
88
  kwargs = self._set_params(**kwargs)
112
89
  if operation == BackendOperations.DELETE.value:
@@ -123,23 +100,22 @@ class ClientDHCoreParametersBuilder(ClientParametersBuilder):
123
100
  """
124
101
  Build parameters for context-level API operations.
125
102
 
126
- Constructs HTTP request parameters for operations that work within
127
- a specific context (project), including entity management and
128
- search functionality.
103
+ Constructs HTTP request parameters for entity management and search within
104
+ projects. Handles search filters via 'filter' parameter, pagination with
105
+ 'page' and 'size', result ordering with 'sort' parameter. READ supports
106
+ embedded entity inclusion, DELETE requires entity 'id' parameter.
129
107
 
130
108
  Parameters
131
109
  ----------
132
110
  operation : str
133
- The API operation being performed. Supported operations:
134
- - SEARCH: Search entities with filtering and pagination
135
- - READ_MANY: Retrieve multiple entities with pagination
136
- - DELETE: Delete specific entity by ID
137
- - READ: Read specific entity by ID (with optional embedded)
111
+ API operation: SEARCH (search entities with filtering), READ_MANY
112
+ (retrieve multiple with pagination), DELETE (delete by ID),
113
+ READ (read by ID with optional embedded).
138
114
  **kwargs : dict
139
- Operation-specific parameters including:
115
+ Operation-specific parameters:
140
116
  - params (dict): Search filters and conditions
141
117
  - page (int): Page number for pagination (default: 0)
142
- - size (int): Number of items per page (default: 20)
118
+ - size (int): Items per page (default: 20)
143
119
  - order_by (str): Field to order results by
144
120
  - order (str): Order direction ('asc' or 'desc')
145
121
  - embedded (bool): For READ, whether to include embedded entities
@@ -148,19 +124,8 @@ class ClientDHCoreParametersBuilder(ClientParametersBuilder):
148
124
  Returns
149
125
  -------
150
126
  dict
151
- Formatted parameters with 'params' containing query parameters
152
- and other request-specific parameters like 'id' for entity operations.
153
-
154
- Notes
155
- -----
156
- Search and pagination:
157
- - Filters are applied via 'filter' parameter in query string
158
- - Pagination uses 'page' and 'size' parameters
159
- - Results can be ordered using 'sort' parameter format
160
-
161
- Entity operations:
162
- - READ: Supports embedded entity inclusion via 'embedded' param
163
- - DELETE: Requires entity 'id' parameter
127
+ Formatted parameters with 'params' for query parameters and
128
+ other request-specific parameters like 'id' for entity operations.
164
129
  """
165
130
  kwargs = self._set_params(**kwargs)
166
131
 
@@ -249,27 +214,20 @@ class ClientDHCoreParametersBuilder(ClientParametersBuilder):
249
214
  """
250
215
  Initialize parameter dictionary with query parameters structure.
251
216
 
252
- Ensures that the parameter dictionary has a 'params' key for
253
- HTTP query parameters. This is a utility method used by all
254
- parameter building methods to guarantee consistent structure.
217
+ Ensures parameter dictionary has 'params' key for HTTP query parameters,
218
+ guaranteeing consistent structure for all parameter building methods.
255
219
 
256
220
  Parameters
257
221
  ----------
258
222
  **kwargs : dict
259
- Keyword arguments to be formatted. May be empty or contain
260
- various parameters for API operations.
223
+ Keyword arguments to format. May be empty or contain various
224
+ parameters for API operations.
261
225
 
262
226
  Returns
263
227
  -------
264
228
  dict
265
229
  Parameters dictionary with guaranteed 'params' key containing
266
- an empty dict if not already present.
267
-
268
- Notes
269
- -----
270
- This method is called at the beginning of all parameter building
271
- methods to ensure consistent dictionary structure for query
272
- parameter handling.
230
+ empty dict if not already present.
273
231
  """
274
232
  if not kwargs:
275
233
  kwargs = {}
@@ -23,36 +23,30 @@ def set_dhcore_env(
23
23
  client_id: str | None = None,
24
24
  ) -> None:
25
25
  """
26
- Function to set environment variables for DHCore config.
26
+ Set DHCore environment variables and reload client configuration.
27
27
 
28
- Sets the environment variables for DHCore configuration and
29
- reloads the client configurator to use the new settings.
30
- Note that if the environment variable is already set, it
31
- will be overwritten.
28
+ Updates environment variables for DHCore configuration and automatically
29
+ reloads the client configurator to apply new settings. Overwrites existing
30
+ environment variables if already set.
32
31
 
33
32
  Parameters
34
33
  ----------
35
34
  endpoint : str, optional
36
- The endpoint URL of the DHCore backend.
35
+ DHCore backend endpoint URL.
37
36
  user : str, optional
38
- The username for basic authentication.
37
+ Username for basic authentication.
39
38
  password : str, optional
40
- The password for basic authentication.
39
+ Password for basic authentication.
41
40
  access_token : str, optional
42
- The OAuth2 access token.
41
+ OAuth2 access token.
43
42
  refresh_token : str, optional
44
- The OAuth2 refresh token.
43
+ OAuth2 refresh token.
45
44
  client_id : str, optional
46
- The OAuth2 client identifier.
45
+ OAuth2 client identifier.
47
46
 
48
47
  Returns
49
48
  -------
50
49
  None
51
-
52
- Notes
53
- -----
54
- After setting the environment variables, this function automatically
55
- reloads the client configurator to apply the new configuration.
56
50
  """
57
51
  if endpoint is not None:
58
52
  os.environ[CredsEnvVar.DHCORE_ENDPOINT.value] = endpoint
@@ -73,11 +67,10 @@ def set_dhcore_env(
73
67
 
74
68
  def refresh_token() -> None:
75
69
  """
76
- Function to refresh the OAuth2 access token.
70
+ Refresh the current OAuth2 access token.
77
71
 
78
- Attempts to refresh the current OAuth2 access token using the
79
- refresh token stored in the client configuration. This function
80
- requires that the client be configured with OAuth2 authentication.
72
+ Uses the refresh token stored in client configuration to obtain a new
73
+ access token. Requires OAuth2 authentication configuration.
81
74
 
82
75
  Returns
83
76
  -------
@@ -86,8 +79,7 @@ def refresh_token() -> None:
86
79
  Raises
87
80
  ------
88
81
  ClientError
89
- If the client is not properly configured or if the token
90
- refresh fails.
82
+ If client not properly configured or token refresh fails.
91
83
  """
92
84
  client: ClientDHCore = get_client(local=False)
93
85
  client._configurator.check_config()
@@ -207,7 +207,16 @@ class ClientLocal(Client):
207
207
 
208
208
  else:
209
209
  name = obj.get("name", entity_id)
210
- self._db[entity_type][name][entity_id] = obj
210
+ container = self._db[entity_type][name]
211
+ container[entity_id] = obj
212
+
213
+ # Keep the "latest" pointer consistent when updating the latest entity
214
+ try:
215
+ if container.get("latest", {}).get("id") == entity_id:
216
+ container["latest"] = obj
217
+ except AttributeError:
218
+ # In case "latest" is malformed, ignore and continue
219
+ pass
211
220
 
212
221
  except KeyError:
213
222
  msg = self._format_msg(3, entity_type=entity_type, entity_id=entity_id)
@@ -253,55 +262,51 @@ class ClientLocal(Client):
253
262
 
254
263
  # Name is optional and extracted from kwargs
255
264
  # "params": {"name": <name>}
256
- name = kwargs.get("params", {}).get("name")
265
+ name_param = kwargs.get("params", {}).get("name")
257
266
 
258
- # Delete by name
259
- if entity_id is None and name is not None:
260
- self._db[entity_type].pop(name, None)
267
+ # Delete by name (remove the whole named container)
268
+ if entity_id is None and name_param is not None:
269
+ self._db[entity_type].pop(name_param, None)
261
270
  return {"deleted": True}
262
271
 
263
272
  # Delete by id
264
- for _, v in self._db[entity_type].items():
273
+ found_name: str | None = None
274
+ container: dict | None = None
275
+ for n, v in self._db[entity_type].items():
265
276
  if entity_id in v:
266
- v.pop(entity_id)
267
-
268
- # Handle latest
269
- if v["latest"]["id"] == entity_id:
270
- name = v["latest"].get("name", entity_id)
271
- v.pop("latest")
272
- reset_latest = True
277
+ found_name = n
278
+ container = v
273
279
  break
274
280
  else:
275
281
  raise KeyError
276
282
 
277
- if name is not None:
278
- # Pop name if empty
279
- if not self._db[entity_type][name]:
280
- self._db[entity_type].pop(name)
281
-
282
- # Handle latest
283
- elif reset_latest:
284
- latest_uuid = None
285
- latest_date = None
286
- for k, v in self._db[entity_type][name].items():
287
- # Get created from metadata. If tzinfo is None, set it to UTC
288
- # If created is not in ISO format, use fallback
289
- fallback = datetime.fromtimestamp(0, timezone.utc)
290
- try:
291
- current_created = datetime.fromisoformat(v.get("metadata", {}).get("created"))
292
- if current_created.tzinfo is None:
293
- current_created = current_created.replace(tzinfo=timezone.utc)
294
- except ValueError:
295
- current_created = fallback
296
-
297
- # Update latest date and uuid
298
- if latest_date is None or current_created > latest_date:
299
- latest_uuid = k
300
- latest_date = current_created
301
-
302
- # Set new latest
303
- if latest_uuid is not None:
304
- self._db[entity_type][name]["latest"] = self._db[entity_type][name][latest_uuid]
283
+ # Remove the entity from the container
284
+ assert container is not None # for type checkers
285
+ container.pop(entity_id)
286
+
287
+ # Handle latest pointer if needed
288
+ if container.get("latest", {}).get("id") == entity_id:
289
+ # Remove stale latest
290
+ container.pop("latest", None)
291
+ reset_latest = True
292
+
293
+ # If container is now empty, drop it entirely
294
+ if not container:
295
+ assert found_name is not None
296
+ self._db[entity_type].pop(found_name, None)
297
+ # Otherwise, recompute latest if required
298
+ elif reset_latest:
299
+ latest_uuid = None
300
+ latest_date = None
301
+ for k, v in container.items():
302
+ # Parse creation time from metadata; tolerate various formats
303
+ current_created = self._safe_parse_created(v)
304
+ if latest_date is None or current_created > latest_date:
305
+ latest_uuid = k
306
+ latest_date = current_created
307
+
308
+ if latest_uuid is not None:
309
+ container["latest"] = container[latest_uuid]
305
310
 
306
311
  except KeyError:
307
312
  msg = self._format_msg(3, entity_type=entity_type, entity_id=entity_id)
@@ -330,7 +335,10 @@ class ClientLocal(Client):
330
335
  # "params": {"name": <name>}
331
336
  name = kwargs.get("params", {}).get("name")
332
337
  if name is not None:
333
- return [self._db[entity_type][name]["latest"]]
338
+ try:
339
+ return [self._db[entity_type][name]["latest"]]
340
+ except KeyError:
341
+ return []
334
342
 
335
343
  try:
336
344
  # If no name is provided, get latest objects
@@ -343,7 +351,7 @@ class ClientLocal(Client):
343
351
  if kind is not None:
344
352
  listed_objects = [obj for obj in listed_objects if obj["kind"] == kind]
345
353
 
346
- # If function is provided, return objects by function
354
+ # If function/task is provided, return objects by function/task
347
355
  spec_params = ["function", "task"]
348
356
  for i in spec_params:
349
357
  p = kwargs.get("params", {}).get(i)
@@ -489,14 +497,15 @@ class ClientLocal(Client):
489
497
  """
490
498
  # Deepcopy to avoid modifying the original object
491
499
  project = deepcopy(obj)
492
- spec = project.get("spec", {})
500
+ # Ensure spec exists on the returned project
501
+ spec = project.setdefault("spec", {})
493
502
 
494
503
  # Get all entities associated with the project specs
495
504
  projects_entities = [k for k, _ in self._db.items() if k not in ["projects", "runs", "tasks"]]
496
505
 
497
506
  for entity_type in projects_entities:
498
507
  # Get all objects of the entity type for the project
499
- objs = self._db[entity_type]
508
+ objs = self._db.get(entity_type, {})
500
509
 
501
510
  # Set empty list
502
511
  spec[entity_type] = []
@@ -521,6 +530,29 @@ class ClientLocal(Client):
521
530
 
522
531
  return project
523
532
 
533
+ @staticmethod
534
+ def _safe_parse_created(obj: dict) -> datetime:
535
+ """
536
+ Safely parse the creation datetime of an object.
537
+
538
+ - Accepts ISO format with optional 'Z'.
539
+ - If tzinfo is missing, assume UTC.
540
+ - Falls back to epoch if missing/invalid.
541
+ """
542
+ created_raw = obj.get("metadata", {}).get("created")
543
+ fallback = datetime.fromtimestamp(0, timezone.utc)
544
+ if not created_raw or not isinstance(created_raw, str):
545
+ return fallback
546
+ try:
547
+ # Support trailing 'Z'
548
+ ts = created_raw.replace("Z", "+00:00")
549
+ dt = datetime.fromisoformat(ts)
550
+ if dt.tzinfo is None:
551
+ dt = dt.replace(tzinfo=timezone.utc)
552
+ return dt
553
+ except Exception:
554
+ return fallback
555
+
524
556
  ##############################
525
557
  # Utils
526
558
  ##############################
@@ -36,6 +36,7 @@ class CredsEnvVar(Enum):
36
36
  """
37
37
  Supported credential environment variables.
38
38
  """
39
+
39
40
  # S3
40
41
  S3_ENDPOINT_URL = "AWS_ENDPOINT_URL"
41
42
  S3_ACCESS_KEY_ID = "AWS_ACCESS_KEY_ID"
@@ -146,19 +146,3 @@ def set_current_profile(environment: str) -> None:
146
146
 
147
147
  except Exception as e:
148
148
  raise ClientError(f"Failed to write env file: {e}")
149
-
150
-
151
- def read_env_from_file() -> str | None:
152
- """
153
- Read the current credentials profile name from the .dhcore.ini file.
154
-
155
- Returns
156
- -------
157
- str or None
158
- Name of the current credentials profile, or None if not found.
159
- """
160
- try:
161
- cfg = load_file()
162
- return cfg["DEFAULT"]["current_environment"]
163
- except Exception:
164
- return None
@@ -37,7 +37,7 @@ def get_default_store(project: str) -> str:
37
37
  var = StoreEnv.DEFAULT_FILES_STORE.value
38
38
 
39
39
  context = get_context(project)
40
- store = context.config.get(var.lower())
40
+ store = context.config.get(var.lower().replace("dhcore_", ""))
41
41
  if store is not None:
42
42
  return store
43
43
 
@@ -21,6 +21,20 @@ if typing.TYPE_CHECKING:
21
21
 
22
22
 
23
23
  class StoreInfo:
24
+ """
25
+ Container for store class and configurator information.
26
+
27
+ Holds store class references and their associated configurators
28
+ for registration and instantiation in the store builder system.
29
+
30
+ Attributes
31
+ ----------
32
+ _store : Store
33
+ The store class to be instantiated.
34
+ _configurator : Configurator or None
35
+ The configurator class for store configuration, if required.
36
+ """
37
+
24
38
  def __init__(self, store: Store, configurator: Configurator | None = None) -> None:
25
39
  self._store = store
26
40
  self._configurator = configurator
@@ -28,7 +42,19 @@ class StoreInfo:
28
42
 
29
43
  class StoreBuilder:
30
44
  """
31
- Store builder class.
45
+ Store factory and registry for managing data store instances.
46
+
47
+ Provides registration, instantiation, and caching of data store
48
+ instances based on URI schemes. Supports various store types
49
+ including S3, SQL, local, and remote stores with their respective
50
+ configurators.
51
+
52
+ Attributes
53
+ ----------
54
+ _builders : dict[str, StoreInfo]
55
+ Registry of store types mapped to their StoreInfo instances.
56
+ _instances : dict[str, Store]
57
+ Cache of instantiated store instances by store type.
32
58
  """
33
59
 
34
60
  def __init__(self) -> None:
@@ -41,6 +67,31 @@ class StoreBuilder:
41
67
  store: Store,
42
68
  configurator: Configurator | None = None,
43
69
  ) -> None:
70
+ """
71
+ Register a store type with its class and optional configurator.
72
+
73
+ Adds a new store type to the builder registry, associating it
74
+ with a store class and optional configurator for later instantiation.
75
+
76
+ Parameters
77
+ ----------
78
+ store_type : str
79
+ The unique identifier for the store type (e.g., 's3', 'sql').
80
+ store : Store
81
+ The store class to register for this type.
82
+ configurator : Configurator, optional
83
+ The configurator class for store configuration.
84
+ If None, the store will be instantiated without configuration.
85
+
86
+ Returns
87
+ -------
88
+ None
89
+
90
+ Raises
91
+ ------
92
+ StoreError
93
+ If the store type is already registered in the builder.
94
+ """
44
95
  if store_type not in self._builders:
45
96
  self._builders[store_type] = StoreInfo(store, configurator)
46
97
  else:
@@ -48,17 +99,28 @@ class StoreBuilder:
48
99
 
49
100
  def get(self, uri: str) -> Store:
50
101
  """
51
- Get a store instance by URI, building it if necessary.
102
+ Get or create a store instance based on URI scheme.
103
+
104
+ Determines the appropriate store type from the URI scheme,
105
+ instantiates the store if not already cached, and returns
106
+ the store instance. Store instances are cached for reuse.
52
107
 
53
108
  Parameters
54
109
  ----------
55
110
  uri : str
56
- URI to parse.
111
+ The URI to parse for determining the store type.
112
+ The scheme (e.g., 's3://', 'sql://') determines which
113
+ store type to instantiate.
57
114
 
58
115
  Returns
59
116
  -------
60
117
  Store
61
- The store instance.
118
+ The store instance appropriate for handling the given URI.
119
+
120
+ Raises
121
+ ------
122
+ KeyError
123
+ If no store is registered for the URI scheme.
62
124
  """
63
125
  store_type = map_uri_scheme(uri)
64
126