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.
- digitalhub/__init__.py +1 -1
- digitalhub/context/api.py +5 -5
- digitalhub/context/builder.py +3 -5
- digitalhub/context/context.py +9 -1
- digitalhub/entities/_base/material/entity.py +3 -3
- digitalhub/entities/_commons/metrics.py +64 -30
- digitalhub/entities/_commons/utils.py +36 -9
- digitalhub/entities/_processors/base.py +150 -79
- digitalhub/entities/_processors/context.py +363 -212
- digitalhub/entities/_processors/utils.py +74 -30
- digitalhub/entities/artifact/utils.py +28 -13
- digitalhub/entities/dataitem/crud.py +10 -2
- digitalhub/entities/dataitem/table/entity.py +3 -3
- digitalhub/entities/dataitem/utils.py +84 -35
- digitalhub/entities/model/utils.py +28 -13
- digitalhub/entities/task/_base/models.py +12 -3
- digitalhub/factory/factory.py +25 -3
- digitalhub/factory/utils.py +11 -3
- digitalhub/runtimes/_base.py +1 -1
- digitalhub/runtimes/builder.py +18 -1
- digitalhub/stores/client/__init__.py +12 -0
- digitalhub/stores/client/_base/api_builder.py +14 -0
- digitalhub/stores/client/_base/client.py +93 -0
- digitalhub/stores/client/_base/key_builder.py +28 -0
- digitalhub/stores/client/_base/params_builder.py +14 -0
- digitalhub/stores/client/api.py +10 -5
- digitalhub/stores/client/builder.py +3 -1
- digitalhub/stores/client/dhcore/api_builder.py +17 -0
- digitalhub/stores/client/dhcore/client.py +276 -58
- digitalhub/stores/client/dhcore/configurator.py +336 -141
- digitalhub/stores/client/dhcore/error_parser.py +35 -1
- digitalhub/stores/client/dhcore/params_builder.py +113 -17
- digitalhub/stores/client/dhcore/utils.py +32 -14
- digitalhub/stores/client/local/api_builder.py +17 -0
- digitalhub/stores/client/local/client.py +6 -8
- digitalhub/stores/credentials/api.py +8 -8
- digitalhub/stores/credentials/configurator.py +176 -3
- digitalhub/stores/credentials/enums.py +17 -3
- digitalhub/stores/credentials/handler.py +73 -45
- digitalhub/stores/credentials/ini_module.py +59 -27
- digitalhub/stores/credentials/store.py +33 -1
- digitalhub/stores/data/_base/store.py +8 -3
- digitalhub/stores/data/api.py +20 -16
- digitalhub/stores/data/builder.py +69 -13
- digitalhub/stores/data/s3/configurator.py +64 -23
- digitalhub/stores/data/s3/store.py +30 -27
- digitalhub/stores/data/s3/utils.py +9 -9
- digitalhub/stores/data/sql/configurator.py +76 -25
- digitalhub/stores/data/sql/store.py +180 -91
- digitalhub/utils/exceptions.py +6 -0
- digitalhub/utils/file_utils.py +53 -30
- digitalhub/utils/generic_utils.py +41 -33
- digitalhub/utils/git_utils.py +24 -14
- digitalhub/utils/io_utils.py +19 -18
- digitalhub/utils/uri_utils.py +31 -31
- {digitalhub-0.13.0b2.dist-info → digitalhub-0.13.0b4.dist-info}/METADATA +1 -1
- {digitalhub-0.13.0b2.dist-info → digitalhub-0.13.0b4.dist-info}/RECORD +60 -61
- digitalhub/entities/_commons/types.py +0 -9
- {digitalhub-0.13.0b2.dist-info → digitalhub-0.13.0b4.dist-info}/WHEEL +0 -0
- {digitalhub-0.13.0b2.dist-info → digitalhub-0.13.0b4.dist-info}/licenses/AUTHORS +0 -0
- {digitalhub-0.13.0b2.dist-info → digitalhub-0.13.0b4.dist-info}/licenses/LICENSE +0 -0
|
@@ -7,104 +7,132 @@ from __future__ import annotations
|
|
|
7
7
|
import os
|
|
8
8
|
|
|
9
9
|
from digitalhub.stores.credentials.enums import SetCreds
|
|
10
|
-
from digitalhub.stores.credentials.ini_module import
|
|
10
|
+
from digitalhub.stores.credentials.ini_module import (
|
|
11
|
+
load_file,
|
|
12
|
+
load_key,
|
|
13
|
+
load_profile,
|
|
14
|
+
set_current_profile,
|
|
15
|
+
write_config,
|
|
16
|
+
)
|
|
11
17
|
from digitalhub.stores.credentials.store import CredentialsStore
|
|
12
18
|
|
|
13
19
|
|
|
14
20
|
class CredentialHandler:
|
|
15
21
|
"""
|
|
16
|
-
|
|
22
|
+
Handler for configuring clients and managing credentials.
|
|
23
|
+
|
|
24
|
+
Attributes
|
|
25
|
+
----------
|
|
26
|
+
_creds_store : CredentialsStore
|
|
27
|
+
Store for credentials.
|
|
28
|
+
_profile : str
|
|
29
|
+
Current credentials profile name.
|
|
17
30
|
"""
|
|
18
31
|
|
|
19
32
|
def __init__(self) -> None:
|
|
20
|
-
# Store
|
|
21
33
|
self._creds_store = CredentialsStore()
|
|
34
|
+
self._profile = self._read_current_profile()
|
|
22
35
|
|
|
23
|
-
|
|
24
|
-
|
|
36
|
+
@staticmethod
|
|
37
|
+
def _read_current_profile() -> str:
|
|
38
|
+
"""
|
|
39
|
+
Read the current credentials profile name.
|
|
40
|
+
|
|
41
|
+
Returns
|
|
42
|
+
-------
|
|
43
|
+
str
|
|
44
|
+
Name of the credentials profile.
|
|
45
|
+
"""
|
|
46
|
+
profile = os.getenv(SetCreds.DH_PROFILE.value)
|
|
47
|
+
if profile is not None:
|
|
48
|
+
return profile
|
|
49
|
+
file = load_file()
|
|
50
|
+
profile = load_profile(file)
|
|
51
|
+
if profile is not None:
|
|
52
|
+
return profile
|
|
53
|
+
return SetCreds.DEFAULT.value
|
|
25
54
|
|
|
26
55
|
##############################
|
|
27
56
|
# Public methods
|
|
28
57
|
##############################
|
|
29
58
|
|
|
30
|
-
def
|
|
59
|
+
def set_current_profile(self, creds_set: str) -> None:
|
|
31
60
|
"""
|
|
32
|
-
Set the current credentials
|
|
61
|
+
Set the current credentials profile name.
|
|
33
62
|
|
|
34
63
|
Parameters
|
|
35
64
|
----------
|
|
36
65
|
creds_set : str
|
|
37
|
-
|
|
66
|
+
Name of the credentials profile to set.
|
|
38
67
|
|
|
39
68
|
Returns
|
|
40
69
|
-------
|
|
41
70
|
None
|
|
42
71
|
"""
|
|
43
|
-
self.
|
|
44
|
-
|
|
72
|
+
self._profile = creds_set
|
|
73
|
+
set_current_profile(creds_set)
|
|
45
74
|
|
|
46
|
-
def
|
|
75
|
+
def get_current_profile(self) -> str:
|
|
47
76
|
"""
|
|
48
|
-
Get the current credentials
|
|
77
|
+
Get the current credentials profile name.
|
|
49
78
|
|
|
50
79
|
Returns
|
|
51
80
|
-------
|
|
52
81
|
str
|
|
53
|
-
|
|
82
|
+
Name of the current credentials profile.
|
|
54
83
|
"""
|
|
55
|
-
return self.
|
|
84
|
+
return self._profile
|
|
56
85
|
|
|
57
|
-
def load_from_env(self,
|
|
86
|
+
def load_from_env(self, vars: list[str]) -> dict:
|
|
58
87
|
"""
|
|
59
|
-
Load
|
|
88
|
+
Load variables from environment.
|
|
60
89
|
|
|
61
90
|
Parameters
|
|
62
91
|
----------
|
|
63
|
-
|
|
64
|
-
|
|
92
|
+
vars : list of str
|
|
93
|
+
List of environment variable names to load.
|
|
65
94
|
|
|
66
95
|
Returns
|
|
67
96
|
-------
|
|
68
|
-
|
|
69
|
-
|
|
97
|
+
dict
|
|
98
|
+
Dictionary of environment variable values.
|
|
70
99
|
"""
|
|
71
|
-
|
|
72
|
-
if env_var != "":
|
|
73
|
-
return env_var
|
|
100
|
+
return {var: os.getenv(var) for var in vars}
|
|
74
101
|
|
|
75
|
-
def load_from_file(self,
|
|
102
|
+
def load_from_file(self, vars: list[str]) -> dict:
|
|
76
103
|
"""
|
|
77
|
-
Load
|
|
104
|
+
Load variables from credentials config file.
|
|
78
105
|
|
|
79
106
|
Parameters
|
|
80
107
|
----------
|
|
81
|
-
|
|
82
|
-
|
|
108
|
+
vars : list of str
|
|
109
|
+
List of variable names to load from file.
|
|
83
110
|
|
|
84
111
|
Returns
|
|
85
112
|
-------
|
|
86
|
-
|
|
87
|
-
|
|
113
|
+
dict
|
|
114
|
+
Dictionary of variable values from file.
|
|
88
115
|
"""
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
116
|
+
file = load_file()
|
|
117
|
+
profile = load_profile(file)
|
|
118
|
+
if profile is not None:
|
|
119
|
+
self._profile = profile
|
|
120
|
+
return {var: load_key(file, self._profile, var) for var in vars}
|
|
93
121
|
|
|
94
122
|
def write_env(self, creds: dict) -> None:
|
|
95
123
|
"""
|
|
96
|
-
Write
|
|
124
|
+
Write credentials to the .dhcore file for the current profile.
|
|
97
125
|
|
|
98
126
|
Parameters
|
|
99
127
|
----------
|
|
100
128
|
creds : dict
|
|
101
|
-
Credentials.
|
|
129
|
+
Credentials to write.
|
|
102
130
|
|
|
103
131
|
Returns
|
|
104
132
|
-------
|
|
105
133
|
None
|
|
106
134
|
"""
|
|
107
|
-
write_config(creds, self.
|
|
135
|
+
write_config(creds, self._profile)
|
|
108
136
|
|
|
109
137
|
##############################
|
|
110
138
|
# Credentials store methods
|
|
@@ -112,37 +140,37 @@ class CredentialHandler:
|
|
|
112
140
|
|
|
113
141
|
def set_credentials(self, origin: str, creds: dict) -> None:
|
|
114
142
|
"""
|
|
115
|
-
Set credentials.
|
|
143
|
+
Set credentials for the current profile and origin.
|
|
116
144
|
|
|
117
145
|
Parameters
|
|
118
146
|
----------
|
|
119
147
|
origin : str
|
|
120
|
-
The origin of the credentials.
|
|
148
|
+
The origin of the credentials ('env' or 'file').
|
|
121
149
|
creds : dict
|
|
122
|
-
|
|
150
|
+
Credentials to set.
|
|
123
151
|
|
|
124
152
|
Returns
|
|
125
153
|
-------
|
|
126
154
|
None
|
|
127
155
|
"""
|
|
128
|
-
self._creds_store.set_credentials(self.
|
|
156
|
+
self._creds_store.set_credentials(self._profile, origin, creds)
|
|
129
157
|
|
|
130
158
|
def get_credentials(self, origin: str) -> dict:
|
|
131
159
|
"""
|
|
132
|
-
Get credentials from origin.
|
|
160
|
+
Get credentials for the current profile from the specified origin.
|
|
133
161
|
|
|
134
162
|
Parameters
|
|
135
163
|
----------
|
|
136
164
|
origin : str
|
|
137
|
-
The origin
|
|
165
|
+
The origin to get credentials from ('env' or 'file').
|
|
138
166
|
|
|
139
167
|
Returns
|
|
140
168
|
-------
|
|
141
169
|
dict
|
|
142
|
-
|
|
170
|
+
Dictionary of credentials.
|
|
143
171
|
"""
|
|
144
|
-
return self._creds_store.get_credentials(self.
|
|
172
|
+
return self._creds_store.get_credentials(self._profile, origin)
|
|
145
173
|
|
|
146
174
|
|
|
147
|
-
# Define global
|
|
175
|
+
# Define global credential handler
|
|
148
176
|
creds_handler = CredentialHandler()
|
|
@@ -9,22 +9,23 @@ from pathlib import Path
|
|
|
9
9
|
|
|
10
10
|
from digitalhub.utils.exceptions import ClientError
|
|
11
11
|
|
|
12
|
-
# File where to write
|
|
13
|
-
# It's used because we inject the variables in jupyter env,
|
|
14
|
-
# but refresh token is only available once. Is it's used, we cannot
|
|
15
|
-
# overwrite it with coder, so we need to store the new one in a file,
|
|
16
|
-
# preserved for jupyter restart
|
|
12
|
+
# File where to write credementials
|
|
17
13
|
ENV_FILE = Path.home() / ".dhcore.ini"
|
|
18
14
|
|
|
19
15
|
|
|
20
16
|
def load_file() -> ConfigParser:
|
|
21
17
|
"""
|
|
22
|
-
Load
|
|
18
|
+
Load the credentials configuration from the .dhcore.ini file.
|
|
23
19
|
|
|
24
20
|
Returns
|
|
25
21
|
-------
|
|
26
22
|
ConfigParser
|
|
27
|
-
|
|
23
|
+
Parsed configuration file object.
|
|
24
|
+
|
|
25
|
+
Raises
|
|
26
|
+
------
|
|
27
|
+
ClientError
|
|
28
|
+
If the file cannot be read.
|
|
28
29
|
"""
|
|
29
30
|
try:
|
|
30
31
|
file = ConfigParser()
|
|
@@ -34,45 +35,71 @@ def load_file() -> ConfigParser:
|
|
|
34
35
|
raise ClientError(f"Failed to read env file: {e}")
|
|
35
36
|
|
|
36
37
|
|
|
37
|
-
def
|
|
38
|
+
def load_profile(file: ConfigParser) -> str | None:
|
|
38
39
|
"""
|
|
39
|
-
Load
|
|
40
|
+
Load the current credentials profile name from the .dhcore.ini file.
|
|
40
41
|
|
|
41
42
|
Parameters
|
|
42
43
|
----------
|
|
44
|
+
file : ConfigParser
|
|
45
|
+
Parsed configuration file object.
|
|
46
|
+
|
|
47
|
+
Returns
|
|
48
|
+
-------
|
|
49
|
+
str or None
|
|
50
|
+
Name of the credentials profile, or None if not found.
|
|
51
|
+
"""
|
|
52
|
+
try:
|
|
53
|
+
return file["DEFAULT"]["current_environment"]
|
|
54
|
+
except KeyError:
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def load_key(file: ConfigParser, profile: str, key: str) -> str | None:
|
|
59
|
+
"""
|
|
60
|
+
Load a specific key value from the credentials profile in the
|
|
61
|
+
.dhcore.ini file.
|
|
62
|
+
|
|
63
|
+
Parameters
|
|
64
|
+
----------
|
|
65
|
+
file : ConfigParser
|
|
66
|
+
Parsed configuration file object.
|
|
43
67
|
profile : str
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
68
|
+
Name of the credentials profile.
|
|
69
|
+
key : str
|
|
70
|
+
Name of the key to retrieve.
|
|
47
71
|
|
|
48
72
|
Returns
|
|
49
73
|
-------
|
|
50
|
-
str
|
|
51
|
-
|
|
74
|
+
str or None
|
|
75
|
+
Value of the key, or None if not found.
|
|
52
76
|
"""
|
|
53
77
|
try:
|
|
54
|
-
|
|
55
|
-
profile = cfg["DEFAULT"]["current_environment"]
|
|
56
|
-
return cfg[profile].get(var)
|
|
78
|
+
return file[profile][key]
|
|
57
79
|
except KeyError:
|
|
58
80
|
return
|
|
59
81
|
|
|
60
82
|
|
|
61
83
|
def write_config(creds: dict, environment: str) -> None:
|
|
62
84
|
"""
|
|
63
|
-
Write
|
|
64
|
-
|
|
85
|
+
Write credentials to the .dhcore.ini file for the specified environment.
|
|
86
|
+
Overwrites any existing values for that environment.
|
|
65
87
|
|
|
66
88
|
Parameters
|
|
67
89
|
----------
|
|
68
90
|
creds : dict
|
|
69
|
-
|
|
91
|
+
Dictionary of credentials to write.
|
|
70
92
|
environment : str
|
|
71
|
-
|
|
93
|
+
Name of the credentials profile/environment.
|
|
72
94
|
|
|
73
95
|
Returns
|
|
74
96
|
-------
|
|
75
97
|
None
|
|
98
|
+
|
|
99
|
+
Raises
|
|
100
|
+
------
|
|
101
|
+
ClientError
|
|
102
|
+
If the file cannot be written.
|
|
76
103
|
"""
|
|
77
104
|
try:
|
|
78
105
|
cfg = load_file()
|
|
@@ -93,18 +120,23 @@ def write_config(creds: dict, environment: str) -> None:
|
|
|
93
120
|
raise ClientError(f"Failed to write env file: {e}")
|
|
94
121
|
|
|
95
122
|
|
|
96
|
-
def
|
|
123
|
+
def set_current_profile(environment: str) -> None:
|
|
97
124
|
"""
|
|
98
|
-
Set the current credentials
|
|
125
|
+
Set the current credentials profile in the .dhcore.ini file.
|
|
99
126
|
|
|
100
127
|
Parameters
|
|
101
128
|
----------
|
|
102
129
|
environment : str
|
|
103
|
-
|
|
130
|
+
Name of the credentials profile to set as current.
|
|
104
131
|
|
|
105
132
|
Returns
|
|
106
133
|
-------
|
|
107
134
|
None
|
|
135
|
+
|
|
136
|
+
Raises
|
|
137
|
+
------
|
|
138
|
+
ClientError
|
|
139
|
+
If the file cannot be written.
|
|
108
140
|
"""
|
|
109
141
|
try:
|
|
110
142
|
cfg = load_file()
|
|
@@ -118,12 +150,12 @@ def set_current_env(environment: str) -> None:
|
|
|
118
150
|
|
|
119
151
|
def read_env_from_file() -> str | None:
|
|
120
152
|
"""
|
|
121
|
-
Read the current credentials
|
|
153
|
+
Read the current credentials profile name from the .dhcore.ini file.
|
|
122
154
|
|
|
123
155
|
Returns
|
|
124
156
|
-------
|
|
125
|
-
str
|
|
126
|
-
|
|
157
|
+
str or None
|
|
158
|
+
Name of the current credentials profile, or None if not found.
|
|
127
159
|
"""
|
|
128
160
|
try:
|
|
129
161
|
cfg = load_file()
|
|
@@ -11,7 +11,14 @@ from digitalhub.stores.credentials.enums import CredsOrigin
|
|
|
11
11
|
|
|
12
12
|
class CredentialsStore:
|
|
13
13
|
"""
|
|
14
|
-
|
|
14
|
+
Store and retrieve credentials for different profiles and origins.
|
|
15
|
+
|
|
16
|
+
Attributes
|
|
17
|
+
----------
|
|
18
|
+
_file_creds : dict of str to dict
|
|
19
|
+
Credentials stored by profile from file origin.
|
|
20
|
+
_env_creds : dict of str to Any
|
|
21
|
+
Credentials stored from environment origin.
|
|
15
22
|
"""
|
|
16
23
|
|
|
17
24
|
def __init__(self) -> None:
|
|
@@ -26,6 +33,19 @@ class CredentialsStore:
|
|
|
26
33
|
) -> None:
|
|
27
34
|
"""
|
|
28
35
|
Set all credentials for a given profile and origin.
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
profile : str
|
|
40
|
+
Name of the credentials profile.
|
|
41
|
+
origin : str
|
|
42
|
+
Origin of the credentials ('env' or 'file').
|
|
43
|
+
credentials : dict of str to Any
|
|
44
|
+
Dictionary of credentials to set.
|
|
45
|
+
|
|
46
|
+
Returns
|
|
47
|
+
-------
|
|
48
|
+
None
|
|
29
49
|
"""
|
|
30
50
|
if origin == CredsOrigin.ENV.value:
|
|
31
51
|
for key, value in credentials.items():
|
|
@@ -43,6 +63,18 @@ class CredentialsStore:
|
|
|
43
63
|
) -> dict[str, Any]:
|
|
44
64
|
"""
|
|
45
65
|
Get all credentials for a given profile and origin.
|
|
66
|
+
|
|
67
|
+
Parameters
|
|
68
|
+
----------
|
|
69
|
+
profile : str
|
|
70
|
+
Name of the credentials profile.
|
|
71
|
+
origin : str
|
|
72
|
+
Origin of the credentials ('env' or 'file').
|
|
73
|
+
|
|
74
|
+
Returns
|
|
75
|
+
-------
|
|
76
|
+
dict of str to Any
|
|
77
|
+
Dictionary of credentials for the profile and origin.
|
|
46
78
|
"""
|
|
47
79
|
if origin == CredsOrigin.ENV.value:
|
|
48
80
|
return self._env_creds
|
|
@@ -186,9 +186,14 @@ class Store:
|
|
|
186
186
|
"""
|
|
187
187
|
if not isinstance(path, Path):
|
|
188
188
|
path = Path(path)
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
189
|
+
# If the path does not exist, we need to infer if it's a file or directory
|
|
190
|
+
if path.suffix and not path.name.startswith("."):
|
|
191
|
+
# Looks like a file, use parent
|
|
192
|
+
dir_path = path.parent
|
|
193
|
+
else:
|
|
194
|
+
# Looks like a directory (even if it contains dots)
|
|
195
|
+
dir_path = path
|
|
196
|
+
dir_path.mkdir(parents=True, exist_ok=True)
|
|
192
197
|
|
|
193
198
|
@staticmethod
|
|
194
199
|
def _build_temp() -> Path:
|
digitalhub/stores/data/api.py
CHANGED
|
@@ -17,53 +17,57 @@ if typing.TYPE_CHECKING:
|
|
|
17
17
|
|
|
18
18
|
def get_default_store(project: str) -> str:
|
|
19
19
|
"""
|
|
20
|
-
|
|
20
|
+
Returns the default store URI for a given project.
|
|
21
21
|
|
|
22
22
|
Parameters
|
|
23
23
|
----------
|
|
24
24
|
project : str
|
|
25
|
-
|
|
25
|
+
The name of the project.
|
|
26
26
|
|
|
27
27
|
Returns
|
|
28
28
|
-------
|
|
29
29
|
str
|
|
30
|
-
|
|
30
|
+
The default store URI.
|
|
31
|
+
|
|
32
|
+
Raises
|
|
33
|
+
------
|
|
34
|
+
ValueError
|
|
35
|
+
If no default store is found.
|
|
31
36
|
"""
|
|
37
|
+
var = StoreEnv.DEFAULT_FILES_STORE.value
|
|
38
|
+
|
|
32
39
|
context = get_context(project)
|
|
33
|
-
store = context.config.get(
|
|
40
|
+
store = context.config.get(var.lower().replace("dhcore_", ""))
|
|
34
41
|
if store is not None:
|
|
35
42
|
return store
|
|
36
43
|
|
|
37
|
-
store = creds_handler.load_from_env(
|
|
44
|
+
store = creds_handler.load_from_env([var]).get(var)
|
|
38
45
|
if store is None:
|
|
39
|
-
store = creds_handler.load_from_file(
|
|
46
|
+
store = creds_handler.load_from_file([var]).get(var)
|
|
40
47
|
|
|
41
48
|
if store is None or store == "":
|
|
42
49
|
raise ValueError(
|
|
43
50
|
"No default store found. "
|
|
44
51
|
"Please set a default store "
|
|
45
|
-
f"in your environment (e.g. export {
|
|
52
|
+
f"in your environment (e.g. export {var}=) "
|
|
53
|
+
" in the .dhcore.ini file "
|
|
46
54
|
"or set it in project config."
|
|
47
55
|
)
|
|
48
56
|
return store
|
|
49
57
|
|
|
50
58
|
|
|
51
|
-
def get_store(
|
|
59
|
+
def get_store(uri: str) -> Store:
|
|
52
60
|
"""
|
|
53
|
-
|
|
61
|
+
Returns a store instance for the given URI.
|
|
54
62
|
|
|
55
63
|
Parameters
|
|
56
|
-
|
|
57
|
-
project : str
|
|
58
|
-
Project name.
|
|
64
|
+
----------
|
|
59
65
|
uri : str
|
|
60
|
-
URI to parse.
|
|
61
|
-
config : dict
|
|
62
|
-
Store configuration.
|
|
66
|
+
The URI to parse.
|
|
63
67
|
|
|
64
68
|
Returns
|
|
65
69
|
-------
|
|
66
70
|
Store
|
|
67
|
-
|
|
71
|
+
The store instance corresponding to the URI.
|
|
68
72
|
"""
|
|
69
73
|
return store_builder.get(uri)
|
|
@@ -6,7 +6,6 @@ from __future__ import annotations
|
|
|
6
6
|
|
|
7
7
|
import typing
|
|
8
8
|
|
|
9
|
-
from digitalhub.stores.credentials.api import get_current_env
|
|
10
9
|
from digitalhub.stores.data.local.store import LocalStore
|
|
11
10
|
from digitalhub.stores.data.remote.store import RemoteStore
|
|
12
11
|
from digitalhub.stores.data.s3.configurator import S3StoreConfigurator
|
|
@@ -22,6 +21,20 @@ if typing.TYPE_CHECKING:
|
|
|
22
21
|
|
|
23
22
|
|
|
24
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
|
+
|
|
25
38
|
def __init__(self, store: Store, configurator: Configurator | None = None) -> None:
|
|
26
39
|
self._store = store
|
|
27
40
|
self._configurator = configurator
|
|
@@ -29,7 +42,19 @@ class StoreInfo:
|
|
|
29
42
|
|
|
30
43
|
class StoreBuilder:
|
|
31
44
|
"""
|
|
32
|
-
Store
|
|
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.
|
|
33
58
|
"""
|
|
34
59
|
|
|
35
60
|
def __init__(self) -> None:
|
|
@@ -42,6 +67,31 @@ class StoreBuilder:
|
|
|
42
67
|
store: Store,
|
|
43
68
|
configurator: Configurator | None = None,
|
|
44
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
|
+
"""
|
|
45
95
|
if store_type not in self._builders:
|
|
46
96
|
self._builders[store_type] = StoreInfo(store, configurator)
|
|
47
97
|
else:
|
|
@@ -49,27 +99,33 @@ class StoreBuilder:
|
|
|
49
99
|
|
|
50
100
|
def get(self, uri: str) -> Store:
|
|
51
101
|
"""
|
|
52
|
-
Get a store instance
|
|
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.
|
|
53
107
|
|
|
54
108
|
Parameters
|
|
55
109
|
----------
|
|
56
110
|
uri : str
|
|
57
|
-
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.
|
|
58
114
|
|
|
59
115
|
Returns
|
|
60
116
|
-------
|
|
61
117
|
Store
|
|
62
|
-
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.
|
|
63
124
|
"""
|
|
64
|
-
env_profile = get_current_env()
|
|
65
125
|
store_type = map_uri_scheme(uri)
|
|
66
126
|
|
|
67
|
-
# Ensure env exists in _instances
|
|
68
|
-
if env_profile not in self._instances:
|
|
69
|
-
self._instances[env_profile] = {}
|
|
70
|
-
|
|
71
127
|
# Build the store instance if not already present
|
|
72
|
-
if store_type not in self._instances
|
|
128
|
+
if store_type not in self._instances:
|
|
73
129
|
store_info = self._builders[store_type]
|
|
74
130
|
store_cls = store_info._store
|
|
75
131
|
cfgrt_cls = store_info._configurator
|
|
@@ -78,9 +134,9 @@ class StoreBuilder:
|
|
|
78
134
|
store = store_cls()
|
|
79
135
|
else:
|
|
80
136
|
store = store_cls(cfgrt_cls())
|
|
81
|
-
self._instances[
|
|
137
|
+
self._instances[store_type] = store
|
|
82
138
|
|
|
83
|
-
return self._instances[
|
|
139
|
+
return self._instances[store_type]
|
|
84
140
|
|
|
85
141
|
|
|
86
142
|
store_builder = StoreBuilder()
|