digitalhub 0.14.0b7__py3-none-any.whl → 0.14.1b0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of digitalhub might be problematic. Click here for more details.
- digitalhub/__init__.py +2 -2
- digitalhub/context/api.py +42 -1
- digitalhub/context/context.py +3 -6
- digitalhub/entities/_base/context/entity.py +0 -3
- digitalhub/entities/_base/material/entity.py +2 -2
- digitalhub/entities/_processors/base/crud.py +14 -23
- digitalhub/entities/_processors/base/import_export.py +0 -5
- digitalhub/entities/_processors/base/processor.py +1 -4
- digitalhub/entities/_processors/base/special_ops.py +4 -8
- digitalhub/entities/_processors/context/crud.py +5 -5
- digitalhub/entities/_processors/context/import_export.py +5 -5
- digitalhub/entities/_processors/context/material.py +2 -2
- digitalhub/entities/_processors/context/special_ops.py +13 -13
- digitalhub/entities/_processors/utils.py +2 -111
- digitalhub/entities/function/_base/entity.py +0 -3
- digitalhub/entities/project/_base/builder.py +0 -6
- digitalhub/entities/project/_base/entity.py +4 -12
- digitalhub/entities/project/_base/spec.py +4 -4
- digitalhub/entities/project/crud.py +9 -44
- digitalhub/entities/project/utils.py +7 -3
- digitalhub/entities/workflow/_base/entity.py +0 -5
- digitalhub/stores/client/{dhcore/api_builder.py → api_builder.py} +2 -3
- digitalhub/stores/client/builder.py +20 -32
- digitalhub/stores/client/{dhcore/client.py → client.py} +64 -23
- digitalhub/stores/client/{dhcore/configurator.py → configurator.py} +122 -176
- digitalhub/stores/client/{_base/enums.py → enums.py} +11 -0
- digitalhub/stores/client/{dhcore/http_handler.py → http_handler.py} +4 -5
- digitalhub/stores/client/{_base/key_builder.py → key_builder.py} +13 -13
- digitalhub/stores/client/{dhcore/params_builder.py → params_builder.py} +51 -12
- digitalhub/stores/client/{dhcore/response_processor.py → response_processor.py} +1 -1
- digitalhub/stores/client/{dhcore/utils.py → utils.py} +2 -7
- digitalhub/stores/{credentials → configurator}/api.py +5 -5
- digitalhub/stores/configurator/configurator.py +123 -0
- digitalhub/stores/{credentials → configurator}/enums.py +25 -10
- digitalhub/stores/configurator/handler.py +213 -0
- digitalhub/stores/{credentials → configurator}/ini_module.py +31 -0
- digitalhub/stores/data/_base/store.py +0 -4
- digitalhub/stores/data/api.py +2 -4
- digitalhub/stores/data/builder.py +5 -37
- digitalhub/stores/data/s3/configurator.py +30 -114
- digitalhub/stores/data/s3/store.py +9 -22
- digitalhub/stores/data/sql/configurator.py +49 -71
- digitalhub/stores/data/sql/store.py +20 -55
- {digitalhub-0.14.0b7.dist-info → digitalhub-0.14.1b0.dist-info}/METADATA +1 -1
- {digitalhub-0.14.0b7.dist-info → digitalhub-0.14.1b0.dist-info}/RECORD +51 -66
- digitalhub/stores/client/_base/api_builder.py +0 -34
- digitalhub/stores/client/_base/client.py +0 -243
- digitalhub/stores/client/_base/params_builder.py +0 -82
- digitalhub/stores/client/api.py +0 -32
- digitalhub/stores/client/dhcore/__init__.py +0 -3
- digitalhub/stores/client/dhcore/enums.py +0 -18
- digitalhub/stores/client/dhcore/key_builder.py +0 -62
- digitalhub/stores/client/local/__init__.py +0 -3
- digitalhub/stores/client/local/api_builder.py +0 -116
- digitalhub/stores/client/local/client.py +0 -605
- digitalhub/stores/client/local/enums.py +0 -15
- digitalhub/stores/client/local/key_builder.py +0 -62
- digitalhub/stores/client/local/params_builder.py +0 -97
- digitalhub/stores/credentials/__init__.py +0 -3
- digitalhub/stores/credentials/configurator.py +0 -185
- digitalhub/stores/credentials/handler.py +0 -164
- digitalhub/stores/credentials/store.py +0 -77
- /digitalhub/stores/client/{dhcore/error_parser.py → error_parser.py} +0 -0
- /digitalhub/stores/client/{dhcore/header_manager.py → header_manager.py} +0 -0
- /digitalhub/stores/{client/_base → configurator}/__init__.py +0 -0
- {digitalhub-0.14.0b7.dist-info → digitalhub-0.14.1b0.dist-info}/WHEEL +0 -0
- {digitalhub-0.14.0b7.dist-info → digitalhub-0.14.1b0.dist-info}/licenses/AUTHORS +0 -0
- {digitalhub-0.14.0b7.dist-info → digitalhub-0.14.1b0.dist-info}/licenses/LICENSE +0 -0
|
@@ -4,15 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
|
-
from
|
|
8
|
-
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from digitalhub.stores.client.enums import ApiCategories, BackendOperations
|
|
9
10
|
|
|
10
11
|
DEFAULT_START_PAGE = 0
|
|
11
12
|
DEFAULT_SIZE = 25
|
|
12
13
|
DEFAULT_SORT = "metadata.updated,DESC"
|
|
13
14
|
|
|
14
15
|
|
|
15
|
-
class
|
|
16
|
+
class ClientParametersBuilder:
|
|
16
17
|
"""
|
|
17
18
|
Parameter builder for DHCore client API calls.
|
|
18
19
|
|
|
@@ -22,15 +23,6 @@ class ClientDHCoreParametersBuilder(ClientParametersBuilder):
|
|
|
22
23
|
within projects). Supports query parameter formatting, search filter
|
|
23
24
|
construction for Solr-based searches, cascade deletion options,
|
|
24
25
|
versioning parameters, and entity sharing parameters.
|
|
25
|
-
|
|
26
|
-
Methods
|
|
27
|
-
-------
|
|
28
|
-
build_parameters(category, operation, **kwargs)
|
|
29
|
-
Main entry point for parameter building based on API category.
|
|
30
|
-
build_parameters_base(operation, **kwargs)
|
|
31
|
-
Builds parameters for base-level API operations.
|
|
32
|
-
build_parameters_context(operation, **kwargs)
|
|
33
|
-
Builds parameters for context-level API operations.
|
|
34
26
|
"""
|
|
35
27
|
|
|
36
28
|
def build_parameters(self, category: str, operation: str, **kwargs) -> dict:
|
|
@@ -236,6 +228,53 @@ class ClientDHCoreParametersBuilder(ClientParametersBuilder):
|
|
|
236
228
|
|
|
237
229
|
return kwargs
|
|
238
230
|
|
|
231
|
+
@staticmethod
|
|
232
|
+
def _ensure_params(**kwargs) -> dict:
|
|
233
|
+
"""
|
|
234
|
+
Initialize parameter dictionary with query parameters structure.
|
|
235
|
+
|
|
236
|
+
Ensures parameter dictionary has 'params' key for HTTP query parameters,
|
|
237
|
+
guaranteeing consistent structure for all parameter building methods.
|
|
238
|
+
|
|
239
|
+
Parameters
|
|
240
|
+
----------
|
|
241
|
+
**kwargs : dict
|
|
242
|
+
Keyword arguments to format. May be empty or contain various
|
|
243
|
+
parameters for API operations.
|
|
244
|
+
|
|
245
|
+
Returns
|
|
246
|
+
-------
|
|
247
|
+
dict
|
|
248
|
+
Parameters dictionary with guaranteed 'params' key containing
|
|
249
|
+
empty dict if not already present.
|
|
250
|
+
"""
|
|
251
|
+
if "params" not in kwargs:
|
|
252
|
+
kwargs["params"] = {}
|
|
253
|
+
return kwargs
|
|
254
|
+
|
|
255
|
+
@staticmethod
|
|
256
|
+
def _add_param(key: str, value: Any | None, **kwargs) -> dict:
|
|
257
|
+
"""
|
|
258
|
+
Add a single query parameter to kwargs.
|
|
259
|
+
|
|
260
|
+
Parameters
|
|
261
|
+
----------
|
|
262
|
+
key : str
|
|
263
|
+
Parameter key.
|
|
264
|
+
value : Any
|
|
265
|
+
Parameter value.
|
|
266
|
+
**kwargs : dict
|
|
267
|
+
Keyword arguments to format. May be empty or contain various
|
|
268
|
+
parameters for API operations.
|
|
269
|
+
|
|
270
|
+
Returns
|
|
271
|
+
-------
|
|
272
|
+
dict
|
|
273
|
+
Parameters dictionary with added key-value pair in 'params'.
|
|
274
|
+
"""
|
|
275
|
+
kwargs["params"][key] = value
|
|
276
|
+
return kwargs
|
|
277
|
+
|
|
239
278
|
@staticmethod
|
|
240
279
|
def read_page_number(**kwargs) -> int:
|
|
241
280
|
"""
|
|
@@ -9,7 +9,7 @@ from warnings import warn
|
|
|
9
9
|
|
|
10
10
|
from requests.exceptions import JSONDecodeError
|
|
11
11
|
|
|
12
|
-
from digitalhub.stores.client.
|
|
12
|
+
from digitalhub.stores.client.error_parser import ErrorParser
|
|
13
13
|
from digitalhub.utils.exceptions import BackendError, ClientError
|
|
14
14
|
|
|
15
15
|
if typing.TYPE_CHECKING:
|
|
@@ -4,12 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
from digitalhub.stores.client.api import get_client
|
|
10
|
-
|
|
11
|
-
if typing.TYPE_CHECKING:
|
|
12
|
-
pass
|
|
7
|
+
from digitalhub.stores.client.builder import get_client
|
|
13
8
|
|
|
14
9
|
|
|
15
10
|
def refresh_token() -> None:
|
|
@@ -25,4 +20,4 @@ def refresh_token() -> None:
|
|
|
25
20
|
ClientError
|
|
26
21
|
If client not properly configured or token refresh fails.
|
|
27
22
|
"""
|
|
28
|
-
get_client(
|
|
23
|
+
get_client().refresh_token()
|
|
@@ -4,19 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
|
-
from digitalhub.stores.
|
|
7
|
+
from digitalhub.stores.configurator.configurator import configurator
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
def set_current_profile(
|
|
10
|
+
def set_current_profile(profile: str) -> None:
|
|
11
11
|
"""
|
|
12
12
|
Set the current credentials profile.
|
|
13
13
|
|
|
14
14
|
Parameters
|
|
15
15
|
----------
|
|
16
|
-
|
|
16
|
+
profile : str
|
|
17
17
|
Name of the credentials profile to set.
|
|
18
18
|
"""
|
|
19
|
-
|
|
19
|
+
configurator.set_current_profile(profile)
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
def get_current_profile() -> str:
|
|
@@ -28,4 +28,4 @@ def get_current_profile() -> str:
|
|
|
28
28
|
str
|
|
29
29
|
Name of the current credentials profile.
|
|
30
30
|
"""
|
|
31
|
-
return
|
|
31
|
+
return configurator.get_current_profile()
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: © 2025 DSLab - Fondazione Bruno Kessler
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from digitalhub.stores.configurator.handler import ConfigurationHandler
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Configurator:
|
|
11
|
+
"""
|
|
12
|
+
Configurator class for configuration and credentials management.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(self):
|
|
16
|
+
self._handler = ConfigurationHandler()
|
|
17
|
+
self._reload_from_env = False
|
|
18
|
+
|
|
19
|
+
##############################
|
|
20
|
+
# Configuration
|
|
21
|
+
##############################
|
|
22
|
+
|
|
23
|
+
def get_configuration(self) -> dict:
|
|
24
|
+
"""
|
|
25
|
+
Retrieve the current configuration.
|
|
26
|
+
|
|
27
|
+
Returns
|
|
28
|
+
-------
|
|
29
|
+
dict
|
|
30
|
+
Dictionary of configuration variables.
|
|
31
|
+
"""
|
|
32
|
+
return self._handler.get_configuration()
|
|
33
|
+
|
|
34
|
+
##############################
|
|
35
|
+
# Credentials
|
|
36
|
+
##############################
|
|
37
|
+
|
|
38
|
+
def get_credentials(self) -> dict:
|
|
39
|
+
"""
|
|
40
|
+
Retrieve the current credentials.
|
|
41
|
+
|
|
42
|
+
Returns
|
|
43
|
+
-------
|
|
44
|
+
dict
|
|
45
|
+
Dictionary of credentials.
|
|
46
|
+
"""
|
|
47
|
+
return self._handler.get_credentials()
|
|
48
|
+
|
|
49
|
+
def eval_retry(self) -> bool:
|
|
50
|
+
"""
|
|
51
|
+
Evaluate credentials reload based on retry logic.
|
|
52
|
+
|
|
53
|
+
Returns
|
|
54
|
+
-------
|
|
55
|
+
bool
|
|
56
|
+
True if a retry action was performed, otherwise False.
|
|
57
|
+
"""
|
|
58
|
+
current_creds = self.get_credentials()
|
|
59
|
+
reread_creds = self._handler.load_credentials()
|
|
60
|
+
|
|
61
|
+
# Compare cached and file credentials.
|
|
62
|
+
# If different, reload in cache.
|
|
63
|
+
if current_creds != reread_creds:
|
|
64
|
+
self.reload_credentials()
|
|
65
|
+
return True
|
|
66
|
+
|
|
67
|
+
# Check if we need to reload from env only
|
|
68
|
+
if not self._reload_from_env:
|
|
69
|
+
self._handler.reload_credentials_from_env()
|
|
70
|
+
self._reload_from_env = True
|
|
71
|
+
return True
|
|
72
|
+
|
|
73
|
+
return False
|
|
74
|
+
|
|
75
|
+
def reload_credentials(self) -> None:
|
|
76
|
+
"""
|
|
77
|
+
Reload credentials from environment and file.
|
|
78
|
+
"""
|
|
79
|
+
self._handler.reload_credentials()
|
|
80
|
+
|
|
81
|
+
###############################
|
|
82
|
+
# Profile methods
|
|
83
|
+
###############################
|
|
84
|
+
|
|
85
|
+
def set_current_profile(self, profile: str) -> None:
|
|
86
|
+
"""
|
|
87
|
+
Set the current profile.
|
|
88
|
+
|
|
89
|
+
Parameters
|
|
90
|
+
----------
|
|
91
|
+
profile : str
|
|
92
|
+
Name of the profile to set.
|
|
93
|
+
"""
|
|
94
|
+
self._handler.set_current_profile(profile)
|
|
95
|
+
|
|
96
|
+
################################
|
|
97
|
+
# Other methods
|
|
98
|
+
################################
|
|
99
|
+
|
|
100
|
+
def write_file(self, variables: dict) -> None:
|
|
101
|
+
"""
|
|
102
|
+
Write the current configuration and credentials to file.
|
|
103
|
+
|
|
104
|
+
Parameters
|
|
105
|
+
----------
|
|
106
|
+
variables : dict
|
|
107
|
+
Dictionary of variables to write.
|
|
108
|
+
"""
|
|
109
|
+
self._handler.write_file(variables)
|
|
110
|
+
|
|
111
|
+
def get_config_creds(self) -> dict:
|
|
112
|
+
"""
|
|
113
|
+
Get merged configuration and credentials.
|
|
114
|
+
|
|
115
|
+
Returns
|
|
116
|
+
-------
|
|
117
|
+
dict
|
|
118
|
+
Merged configuration and credentials dictionary.
|
|
119
|
+
"""
|
|
120
|
+
return {**self.get_configuration(), **self.get_credentials()}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
configurator = Configurator()
|
|
@@ -32,26 +32,20 @@ class SetCreds(Enum):
|
|
|
32
32
|
DH_PROFILE = "DH_NAME"
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
class
|
|
35
|
+
class ConfigurationVars(Enum):
|
|
36
36
|
"""
|
|
37
|
-
|
|
37
|
+
List of supported configuration variables.
|
|
38
38
|
"""
|
|
39
39
|
|
|
40
40
|
# S3
|
|
41
41
|
S3_ENDPOINT_URL = "AWS_ENDPOINT_URL"
|
|
42
|
-
S3_ACCESS_KEY_ID = "AWS_ACCESS_KEY_ID"
|
|
43
|
-
S3_SECRET_ACCESS_KEY = "AWS_SECRET_ACCESS_KEY"
|
|
44
|
-
S3_SESSION_TOKEN = "AWS_SESSION_TOKEN"
|
|
45
42
|
S3_REGION = "AWS_REGION"
|
|
46
43
|
S3_SIGNATURE_VERSION = "S3_SIGNATURE_VERSION"
|
|
47
|
-
S3_CREDENTIALS_EXPIRATION = "AWS_CREDENTIALS_EXPIRATION"
|
|
48
44
|
S3_PATH_STYLE = "S3_PATH_STYLE"
|
|
49
45
|
|
|
50
46
|
# SQL
|
|
51
47
|
DB_HOST = "DB_HOST"
|
|
52
48
|
DB_PORT = "DB_PORT"
|
|
53
|
-
DB_USERNAME = "DB_USERNAME"
|
|
54
|
-
DB_PASSWORD = "DB_PASSWORD"
|
|
55
49
|
DB_DATABASE = "DB_DATABASE"
|
|
56
50
|
DB_PLATFORM = "DB_PLATFORM"
|
|
57
51
|
DB_PG_SCHEMA = "DB_SCHEMA"
|
|
@@ -59,10 +53,31 @@ class CredsEnvVar(Enum):
|
|
|
59
53
|
# DHCORE
|
|
60
54
|
DHCORE_ENDPOINT = "DHCORE_ENDPOINT"
|
|
61
55
|
DHCORE_ISSUER = "DHCORE_ISSUER"
|
|
56
|
+
DHCORE_WORKFLOW_IMAGE = "DHCORE_WORKFLOW_IMAGE"
|
|
57
|
+
DHCORE_CLIENT_ID = "DHCORE_CLIENT_ID"
|
|
58
|
+
|
|
59
|
+
# OAUTH2
|
|
60
|
+
OAUTH2_TOKEN_ENDPOINT = "OAUTH2_TOKEN_ENDPOINT"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class CredentialsVars(Enum):
|
|
64
|
+
"""
|
|
65
|
+
List of supported credential variables.
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
# S3
|
|
69
|
+
S3_ACCESS_KEY_ID = "AWS_ACCESS_KEY_ID"
|
|
70
|
+
S3_SECRET_ACCESS_KEY = "AWS_SECRET_ACCESS_KEY"
|
|
71
|
+
S3_SESSION_TOKEN = "AWS_SESSION_TOKEN"
|
|
72
|
+
S3_CREDENTIALS_EXPIRATION = "AWS_CREDENTIALS_EXPIRATION"
|
|
73
|
+
|
|
74
|
+
# SQL
|
|
75
|
+
DB_USERNAME = "DB_USERNAME"
|
|
76
|
+
DB_PASSWORD = "DB_PASSWORD"
|
|
77
|
+
|
|
78
|
+
# DHCORE
|
|
62
79
|
DHCORE_USER = "DHCORE_USER"
|
|
63
80
|
DHCORE_PASSWORD = "DHCORE_PASSWORD"
|
|
64
|
-
DHCORE_CLIENT_ID = "DHCORE_CLIENT_ID"
|
|
65
81
|
DHCORE_ACCESS_TOKEN = "DHCORE_ACCESS_TOKEN"
|
|
66
82
|
DHCORE_REFRESH_TOKEN = "DHCORE_REFRESH_TOKEN"
|
|
67
83
|
DHCORE_PERSONAL_ACCESS_TOKEN = "DHCORE_PERSONAL_ACCESS_TOKEN"
|
|
68
|
-
DHCORE_WORKFLOW_IMAGE = "DHCORE_WORKFLOW_IMAGE"
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: © 2025 DSLab - Fondazione Bruno Kessler
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from digitalhub.stores.configurator.enums import ConfigurationVars, CredentialsVars, SetCreds
|
|
11
|
+
from digitalhub.stores.configurator.ini_module import (
|
|
12
|
+
load_file,
|
|
13
|
+
load_key,
|
|
14
|
+
load_profile,
|
|
15
|
+
set_current_profile,
|
|
16
|
+
write_file,
|
|
17
|
+
)
|
|
18
|
+
from digitalhub.utils.generic_utils import list_enum
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ConfigurationHandler:
|
|
22
|
+
"""
|
|
23
|
+
Handler for loading and writing configuration variables.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self):
|
|
27
|
+
self._current_profile = self._read_current_profile()
|
|
28
|
+
self._configuration: dict[str, Any] = self.load_configuration()
|
|
29
|
+
self._credentials: dict[str, Any] = self.load_credentials()
|
|
30
|
+
|
|
31
|
+
@staticmethod
|
|
32
|
+
def _read_env(variables: list) -> dict:
|
|
33
|
+
"""
|
|
34
|
+
Read configuration variables from the .dhcore file.
|
|
35
|
+
|
|
36
|
+
Parameters
|
|
37
|
+
----------
|
|
38
|
+
variables : list
|
|
39
|
+
List of environment variable names to read.
|
|
40
|
+
|
|
41
|
+
Returns
|
|
42
|
+
-------
|
|
43
|
+
dict
|
|
44
|
+
Dictionary of environment variables.
|
|
45
|
+
"""
|
|
46
|
+
return {var: os.getenv(var) for var in variables}
|
|
47
|
+
|
|
48
|
+
@staticmethod
|
|
49
|
+
def _read_file(variables: list, profile: str) -> dict:
|
|
50
|
+
"""
|
|
51
|
+
Read configuration variables from the .dhcore file.
|
|
52
|
+
|
|
53
|
+
Parameters
|
|
54
|
+
----------
|
|
55
|
+
variables : list
|
|
56
|
+
List of environment variable names to read.
|
|
57
|
+
profile : str
|
|
58
|
+
Profile name to read from.
|
|
59
|
+
|
|
60
|
+
Returns
|
|
61
|
+
-------
|
|
62
|
+
dict
|
|
63
|
+
Dictionary of configuration variables.
|
|
64
|
+
"""
|
|
65
|
+
file = load_file()
|
|
66
|
+
return {var: load_key(file, profile, var) for var in variables}
|
|
67
|
+
|
|
68
|
+
##############################
|
|
69
|
+
# Configuration methods
|
|
70
|
+
##############################
|
|
71
|
+
|
|
72
|
+
def load_configuration(self) -> dict[str, Any]:
|
|
73
|
+
"""
|
|
74
|
+
Load configuration with env > file precedence.
|
|
75
|
+
|
|
76
|
+
Returns
|
|
77
|
+
-------
|
|
78
|
+
dict
|
|
79
|
+
Merged configuration dictionary.
|
|
80
|
+
"""
|
|
81
|
+
profile = self.get_current_profile()
|
|
82
|
+
variables = list_enum(ConfigurationVars)
|
|
83
|
+
env_config = self._read_env(variables)
|
|
84
|
+
file_config = self._read_file(variables, profile)
|
|
85
|
+
return {**file_config, **{k: v for k, v in env_config.items() if v is not None}}
|
|
86
|
+
|
|
87
|
+
def reload_configuration(self) -> None:
|
|
88
|
+
"""
|
|
89
|
+
Reload configuration from environment and file.
|
|
90
|
+
"""
|
|
91
|
+
self._configuration = self.load_configuration()
|
|
92
|
+
|
|
93
|
+
def get_configuration(self) -> dict[str, Any]:
|
|
94
|
+
"""
|
|
95
|
+
Get the merged configuration dictionary.
|
|
96
|
+
|
|
97
|
+
Returns
|
|
98
|
+
-------
|
|
99
|
+
dict[str, Any]
|
|
100
|
+
The configuration dictionary.
|
|
101
|
+
"""
|
|
102
|
+
return self._configuration
|
|
103
|
+
|
|
104
|
+
##############################
|
|
105
|
+
# Credentials methods
|
|
106
|
+
##############################
|
|
107
|
+
|
|
108
|
+
def load_credentials(self) -> dict[str, Any]:
|
|
109
|
+
"""
|
|
110
|
+
Load credentials with file > env precedence.
|
|
111
|
+
|
|
112
|
+
Parameters
|
|
113
|
+
----------
|
|
114
|
+
profile : str
|
|
115
|
+
Profile name to load credentials from.
|
|
116
|
+
|
|
117
|
+
Returns
|
|
118
|
+
-------
|
|
119
|
+
dict
|
|
120
|
+
Merged credentials dictionary.
|
|
121
|
+
"""
|
|
122
|
+
variables = list_enum(CredentialsVars)
|
|
123
|
+
env_config = self._read_env(variables)
|
|
124
|
+
file_config = self._read_file(variables, self.get_current_profile())
|
|
125
|
+
return {**env_config, **{k: v for k, v in file_config.items() if v is not None}}
|
|
126
|
+
|
|
127
|
+
def reload_credentials(self) -> None:
|
|
128
|
+
"""
|
|
129
|
+
Reload credentials from environment and file.
|
|
130
|
+
"""
|
|
131
|
+
self._credentials = self.load_credentials()
|
|
132
|
+
|
|
133
|
+
def reload_credentials_from_env(self) -> None:
|
|
134
|
+
"""
|
|
135
|
+
Reload credentials from environment where env > file precedence.
|
|
136
|
+
Its a partial reload only from env variables used as fallback.
|
|
137
|
+
"""
|
|
138
|
+
variables = list_enum(CredentialsVars)
|
|
139
|
+
env_config = self._read_env(variables)
|
|
140
|
+
file_config = self._read_file(variables, self.get_current_profile())
|
|
141
|
+
self._credentials = {**file_config, **{k: v for k, v in env_config.items() if v is not None}}
|
|
142
|
+
|
|
143
|
+
def get_credentials(self) -> dict[str, Any]:
|
|
144
|
+
"""
|
|
145
|
+
Get the merged credentials dictionary.
|
|
146
|
+
|
|
147
|
+
Returns
|
|
148
|
+
-------
|
|
149
|
+
dict[str, Any]
|
|
150
|
+
The credentials dictionary.
|
|
151
|
+
"""
|
|
152
|
+
return self._credentials
|
|
153
|
+
|
|
154
|
+
##############################
|
|
155
|
+
# Profile Methods
|
|
156
|
+
##############################
|
|
157
|
+
|
|
158
|
+
@staticmethod
|
|
159
|
+
def _read_current_profile() -> str:
|
|
160
|
+
"""
|
|
161
|
+
Read the current credentials profile name.
|
|
162
|
+
|
|
163
|
+
Returns
|
|
164
|
+
-------
|
|
165
|
+
str
|
|
166
|
+
Name of the credentials profile.
|
|
167
|
+
"""
|
|
168
|
+
profile = os.getenv(SetCreds.DH_PROFILE.value)
|
|
169
|
+
if profile is not None:
|
|
170
|
+
return profile
|
|
171
|
+
file = load_file()
|
|
172
|
+
profile = load_profile(file)
|
|
173
|
+
if profile is not None:
|
|
174
|
+
return profile
|
|
175
|
+
return SetCreds.DEFAULT.value
|
|
176
|
+
|
|
177
|
+
def set_current_profile(self, profile: str) -> None:
|
|
178
|
+
"""
|
|
179
|
+
Set the current credentials profile name.
|
|
180
|
+
|
|
181
|
+
Parameters
|
|
182
|
+
----------
|
|
183
|
+
profile : str
|
|
184
|
+
Name of the credentials profile to set.
|
|
185
|
+
"""
|
|
186
|
+
self._current_profile = profile
|
|
187
|
+
set_current_profile(profile)
|
|
188
|
+
self.reload_configuration()
|
|
189
|
+
self.reload_credentials()
|
|
190
|
+
|
|
191
|
+
def get_current_profile(self) -> str:
|
|
192
|
+
"""
|
|
193
|
+
Get the current credentials profile name.
|
|
194
|
+
|
|
195
|
+
Returns
|
|
196
|
+
-------
|
|
197
|
+
str
|
|
198
|
+
Name of the current credentials profile.
|
|
199
|
+
"""
|
|
200
|
+
return self._current_profile
|
|
201
|
+
|
|
202
|
+
def write_file(self, variables: dict) -> None:
|
|
203
|
+
"""
|
|
204
|
+
Write variables to the .dhcore file for the current profile.
|
|
205
|
+
|
|
206
|
+
Parameters
|
|
207
|
+
----------
|
|
208
|
+
infos : dict
|
|
209
|
+
Information to write.
|
|
210
|
+
profile : str
|
|
211
|
+
Profile name to write to.
|
|
212
|
+
"""
|
|
213
|
+
write_file(variables, self._current_profile)
|
|
@@ -117,6 +117,37 @@ def write_config(creds: dict, environment: str) -> None:
|
|
|
117
117
|
raise ClientError(f"Failed to write env file: {e}")
|
|
118
118
|
|
|
119
119
|
|
|
120
|
+
def write_file(variables: dict, profile: str) -> None:
|
|
121
|
+
"""
|
|
122
|
+
Write variables to the .dhcore.ini file for the specified profile.
|
|
123
|
+
Overwrites any existing values for that profile.
|
|
124
|
+
|
|
125
|
+
Parameters
|
|
126
|
+
----------
|
|
127
|
+
variables : dict
|
|
128
|
+
Dictionary of variables to write.
|
|
129
|
+
profile : str
|
|
130
|
+
Name of the credentials profile to write to.
|
|
131
|
+
"""
|
|
132
|
+
try:
|
|
133
|
+
cfg = load_file()
|
|
134
|
+
|
|
135
|
+
sections = cfg.sections()
|
|
136
|
+
if profile not in sections:
|
|
137
|
+
cfg.add_section(profile)
|
|
138
|
+
|
|
139
|
+
cfg["DEFAULT"]["current_environment"] = profile
|
|
140
|
+
for k, v in variables.items():
|
|
141
|
+
cfg[profile][k] = str(v)
|
|
142
|
+
|
|
143
|
+
ENV_FILE.touch(exist_ok=True)
|
|
144
|
+
with open(ENV_FILE, "w") as inifile:
|
|
145
|
+
cfg.write(inifile)
|
|
146
|
+
|
|
147
|
+
except Exception as e:
|
|
148
|
+
raise ClientError(f"Failed to write env file: {e}")
|
|
149
|
+
|
|
150
|
+
|
|
120
151
|
def set_current_profile(environment: str) -> None:
|
|
121
152
|
"""
|
|
122
153
|
Set the current credentials profile in the .dhcore.ini file.
|
|
@@ -16,7 +16,6 @@ from digitalhub.utils.types import SourcesOrListOfSources
|
|
|
16
16
|
from digitalhub.utils.uri_utils import has_local_scheme
|
|
17
17
|
|
|
18
18
|
if typing.TYPE_CHECKING:
|
|
19
|
-
from digitalhub.stores.credentials.configurator import Configurator
|
|
20
19
|
from digitalhub.stores.readers.data._base.reader import DataframeReader
|
|
21
20
|
|
|
22
21
|
|
|
@@ -25,9 +24,6 @@ class Store:
|
|
|
25
24
|
Store abstract class.
|
|
26
25
|
"""
|
|
27
26
|
|
|
28
|
-
def __init__(self, configurator: Configurator | None = None) -> None:
|
|
29
|
-
self._configurator = configurator
|
|
30
|
-
|
|
31
27
|
##############################
|
|
32
28
|
# I/O methods
|
|
33
29
|
##############################
|
digitalhub/stores/data/api.py
CHANGED
|
@@ -7,7 +7,7 @@ from __future__ import annotations
|
|
|
7
7
|
import typing
|
|
8
8
|
|
|
9
9
|
from digitalhub.context.api import get_context
|
|
10
|
-
from digitalhub.stores.
|
|
10
|
+
from digitalhub.stores.configurator.configurator import configurator
|
|
11
11
|
from digitalhub.stores.data.builder import store_builder
|
|
12
12
|
from digitalhub.stores.data.enums import StoreEnv
|
|
13
13
|
|
|
@@ -41,9 +41,7 @@ def get_default_store(project: str) -> str:
|
|
|
41
41
|
if store is not None:
|
|
42
42
|
return store
|
|
43
43
|
|
|
44
|
-
store =
|
|
45
|
-
if store is None:
|
|
46
|
-
store = creds_handler.load_from_file([var]).get(var)
|
|
44
|
+
store = configurator.get_configuration().get(var)
|
|
47
45
|
|
|
48
46
|
if store is None or store == "":
|
|
49
47
|
raise ValueError(
|