digitalhub 0.10.2__py3-none-any.whl → 0.11.0b1__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 +10 -0
- digitalhub/context/api.py +10 -4
- digitalhub/context/builder.py +35 -20
- digitalhub/context/context.py +35 -24
- digitalhub/entities/_base/entity/builder.py +11 -0
- digitalhub/entities/_base/executable/entity.py +30 -4
- digitalhub/entities/_base/material/utils.py +11 -11
- digitalhub/entities/_commons/enums.py +2 -0
- digitalhub/entities/_processors/base.py +15 -15
- digitalhub/entities/_processors/context.py +13 -13
- digitalhub/entities/_processors/utils.py +2 -2
- digitalhub/entities/builders.py +2 -0
- digitalhub/entities/function/_base/entity.py +49 -3
- digitalhub/entities/project/_base/builder.py +4 -0
- digitalhub/entities/project/_base/entity.py +5 -2
- digitalhub/entities/project/_base/models.py +18 -0
- digitalhub/entities/project/_base/spec.py +6 -0
- digitalhub/entities/project/crud.py +2 -13
- digitalhub/entities/run/_base/entity.py +6 -12
- digitalhub/entities/task/_base/entity.py +4 -4
- digitalhub/entities/task/_base/models.py +22 -2
- digitalhub/entities/trigger/__init__.py +0 -0
- digitalhub/entities/trigger/_base/__init__.py +0 -0
- digitalhub/entities/trigger/_base/builder.py +70 -0
- digitalhub/entities/trigger/_base/entity.py +34 -0
- digitalhub/entities/trigger/_base/spec.py +30 -0
- digitalhub/entities/trigger/_base/status.py +9 -0
- digitalhub/entities/trigger/crud.py +303 -0
- digitalhub/entities/trigger/scheduler/__init__.py +0 -0
- digitalhub/entities/trigger/scheduler/builder.py +19 -0
- digitalhub/entities/trigger/scheduler/entity.py +32 -0
- digitalhub/entities/trigger/scheduler/spec.py +22 -0
- digitalhub/entities/trigger/scheduler/status.py +9 -0
- digitalhub/entities/workflow/_base/entity.py +3 -3
- digitalhub/factory/factory.py +113 -26
- digitalhub/factory/utils.py +31 -14
- digitalhub/runtimes/_base.py +22 -11
- digitalhub/runtimes/builder.py +16 -3
- digitalhub/runtimes/enums.py +11 -1
- digitalhub/stores/client/dhcore/client.py +1 -0
- digitalhub/stores/client/dhcore/configurator.py +19 -0
- digitalhub/stores/client/dhcore/utils.py +1 -0
- digitalhub/stores/configurator/configurator.py +5 -2
- digitalhub/stores/configurator/enums.py +9 -0
- digitalhub/stores/configurator/ini_module.py +58 -4
- digitalhub/stores/data/api.py +2 -2
- digitalhub/stores/data/builder.py +5 -6
- digitalhub/stores/data/enums.py +11 -0
- digitalhub/stores/data/local/store.py +0 -3
- digitalhub/stores/data/remote/store.py +0 -3
- digitalhub/stores/data/s3/configurator.py +2 -19
- digitalhub/stores/data/s3/store.py +3 -9
- digitalhub/stores/data/sql/configurator.py +11 -21
- digitalhub/stores/data/sql/store.py +1 -3
- digitalhub/stores/data/utils.py +34 -0
- digitalhub/utils/uri_utils.py +5 -0
- {digitalhub-0.10.2.dist-info → digitalhub-0.11.0b1.dist-info}/METADATA +1 -1
- {digitalhub-0.10.2.dist-info → digitalhub-0.11.0b1.dist-info}/RECORD +60 -46
- digitalhub/factory/api.py +0 -277
- {digitalhub-0.10.2.dist-info → digitalhub-0.11.0b1.dist-info}/WHEEL +0 -0
- {digitalhub-0.10.2.dist-info → digitalhub-0.11.0b1.dist-info}/licenses/LICENSE.txt +0 -0
digitalhub/factory/utils.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import importlib
|
|
4
|
-
import importlib.metadata
|
|
5
4
|
import pkgutil
|
|
6
5
|
import re
|
|
7
6
|
from types import ModuleType
|
|
@@ -11,17 +10,24 @@ from digitalhub.factory.factory import factory
|
|
|
11
10
|
|
|
12
11
|
def import_module(package: str) -> ModuleType:
|
|
13
12
|
"""
|
|
14
|
-
Import
|
|
13
|
+
Import a module dynamically by package name.
|
|
15
14
|
|
|
16
15
|
Parameters
|
|
17
16
|
----------
|
|
18
17
|
package : str
|
|
19
|
-
|
|
18
|
+
The fully qualified package name to import.
|
|
20
19
|
|
|
21
20
|
Returns
|
|
22
21
|
-------
|
|
23
22
|
ModuleType
|
|
24
|
-
|
|
23
|
+
The imported module object.
|
|
24
|
+
|
|
25
|
+
Raises
|
|
26
|
+
------
|
|
27
|
+
ModuleNotFoundError
|
|
28
|
+
If the specified package cannot be found.
|
|
29
|
+
RuntimeError
|
|
30
|
+
If any other error occurs during import.
|
|
25
31
|
"""
|
|
26
32
|
try:
|
|
27
33
|
return importlib.import_module(package)
|
|
@@ -33,12 +39,20 @@ def import_module(package: str) -> ModuleType:
|
|
|
33
39
|
|
|
34
40
|
def list_runtimes() -> list[str]:
|
|
35
41
|
"""
|
|
36
|
-
List installed
|
|
42
|
+
List all installed DigitalHub runtime packages.
|
|
43
|
+
|
|
44
|
+
Scans installed packages for those matching the pattern
|
|
45
|
+
'digitalhub_runtime_*'.
|
|
37
46
|
|
|
38
47
|
Returns
|
|
39
48
|
-------
|
|
40
49
|
list[str]
|
|
41
|
-
List of
|
|
50
|
+
List of runtime package names.
|
|
51
|
+
|
|
52
|
+
Raises
|
|
53
|
+
------
|
|
54
|
+
RuntimeError
|
|
55
|
+
If an error occurs while scanning for runtime packages.
|
|
42
56
|
"""
|
|
43
57
|
pattern = r"digitalhub_runtime_.*"
|
|
44
58
|
runtimes: list[str] = []
|
|
@@ -53,11 +67,10 @@ def list_runtimes() -> list[str]:
|
|
|
53
67
|
|
|
54
68
|
def register_runtimes_entities() -> None:
|
|
55
69
|
"""
|
|
56
|
-
Register
|
|
70
|
+
Register all runtime builders and their entities into the factory.
|
|
57
71
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
None
|
|
72
|
+
Imports each runtime package and registers its entity and runtime
|
|
73
|
+
builders with the global factory instance.
|
|
61
74
|
"""
|
|
62
75
|
for package in list_runtimes():
|
|
63
76
|
module = import_module(package)
|
|
@@ -74,11 +87,15 @@ def register_runtimes_entities() -> None:
|
|
|
74
87
|
|
|
75
88
|
def register_entities() -> None:
|
|
76
89
|
"""
|
|
77
|
-
Register
|
|
90
|
+
Register core entity builders into the factory.
|
|
78
91
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
92
|
+
Imports the core entities module and registers all entity builders
|
|
93
|
+
with the global factory instance.
|
|
94
|
+
|
|
95
|
+
Raises
|
|
96
|
+
------
|
|
97
|
+
RuntimeError
|
|
98
|
+
If registration of core entities fails.
|
|
82
99
|
"""
|
|
83
100
|
try:
|
|
84
101
|
module = import_module("digitalhub.entities.builders")
|
digitalhub/runtimes/_base.py
CHANGED
|
@@ -3,14 +3,14 @@ from __future__ import annotations
|
|
|
3
3
|
from abc import abstractmethod
|
|
4
4
|
from typing import Any, Callable
|
|
5
5
|
|
|
6
|
-
from digitalhub.factory.
|
|
6
|
+
from digitalhub.factory.factory import factory
|
|
7
7
|
from digitalhub.utils.exceptions import EntityError
|
|
8
8
|
from digitalhub.utils.logger import LOGGER
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class Runtime:
|
|
12
12
|
"""
|
|
13
|
-
Base Runtime class.
|
|
13
|
+
Base Runtime class for executing tasks in the DigitalHub platform.
|
|
14
14
|
|
|
15
15
|
Runtimes are the entities responsible for the actual execution
|
|
16
16
|
of a given run. They are highly specialized components which
|
|
@@ -25,13 +25,13 @@ class Runtime:
|
|
|
25
25
|
@abstractmethod
|
|
26
26
|
def build(self, executable: dict, task: dict, run: dict) -> dict:
|
|
27
27
|
"""
|
|
28
|
-
Build run
|
|
28
|
+
Build run specification from executable, task and run configurations.
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
31
|
@abstractmethod
|
|
32
32
|
def run(self, run: dict) -> dict:
|
|
33
33
|
"""
|
|
34
|
-
Execute run task.
|
|
34
|
+
Execute run task based on the run specification.
|
|
35
35
|
"""
|
|
36
36
|
|
|
37
37
|
##############################
|
|
@@ -40,9 +40,10 @@ class Runtime:
|
|
|
40
40
|
|
|
41
41
|
def _validate_task(self, run: dict) -> str:
|
|
42
42
|
"""
|
|
43
|
-
Check if task is allowed
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
Check if task is allowed by validating against allowed actions.
|
|
44
|
+
|
|
45
|
+
This method presumes that the runtime holds a list of allowed actions
|
|
46
|
+
in the self.allowed_actions attribute.
|
|
46
47
|
|
|
47
48
|
Parameters
|
|
48
49
|
----------
|
|
@@ -52,7 +53,12 @@ class Runtime:
|
|
|
52
53
|
Returns
|
|
53
54
|
-------
|
|
54
55
|
str
|
|
55
|
-
|
|
56
|
+
The validated action name to execute.
|
|
57
|
+
|
|
58
|
+
Raises
|
|
59
|
+
------
|
|
60
|
+
RuntimeError
|
|
61
|
+
If the run specification is malformed or task is not allowed.
|
|
56
62
|
"""
|
|
57
63
|
try:
|
|
58
64
|
task_kind = run["spec"]["task"].split(":")[0]
|
|
@@ -62,7 +68,7 @@ class Runtime:
|
|
|
62
68
|
raise RuntimeError(msg)
|
|
63
69
|
|
|
64
70
|
try:
|
|
65
|
-
return get_action_from_task_kind(task_kind, task_kind)
|
|
71
|
+
return factory.get_action_from_task_kind(task_kind, task_kind)
|
|
66
72
|
except EntityError:
|
|
67
73
|
msg = f"Task {task_kind} not allowed."
|
|
68
74
|
LOGGER.exception(msg)
|
|
@@ -71,7 +77,7 @@ class Runtime:
|
|
|
71
77
|
@staticmethod
|
|
72
78
|
def _execute(func: Callable, *args, **kwargs) -> Any:
|
|
73
79
|
"""
|
|
74
|
-
Execute function.
|
|
80
|
+
Execute a function with provided arguments safely.
|
|
75
81
|
|
|
76
82
|
Parameters
|
|
77
83
|
----------
|
|
@@ -85,7 +91,12 @@ class Runtime:
|
|
|
85
91
|
Returns
|
|
86
92
|
-------
|
|
87
93
|
Any
|
|
88
|
-
Function
|
|
94
|
+
Function return value.
|
|
95
|
+
|
|
96
|
+
Raises
|
|
97
|
+
------
|
|
98
|
+
RuntimeError
|
|
99
|
+
If any exception occurs during function execution.
|
|
89
100
|
"""
|
|
90
101
|
try:
|
|
91
102
|
return func(*args, **kwargs)
|
digitalhub/runtimes/builder.py
CHANGED
|
@@ -10,10 +10,23 @@ if typing.TYPE_CHECKING:
|
|
|
10
10
|
|
|
11
11
|
class RuntimeBuilder:
|
|
12
12
|
"""
|
|
13
|
-
Builder class for
|
|
13
|
+
Builder class for instantiating runtime objects.
|
|
14
|
+
|
|
15
|
+
This class implements the Builder pattern to create Runtime instances.
|
|
16
|
+
Subclasses must set the RUNTIME_CLASS class variable to specify which
|
|
17
|
+
Runtime implementation to build.
|
|
18
|
+
|
|
19
|
+
Attributes
|
|
20
|
+
----------
|
|
21
|
+
RUNTIME_CLASS : Runtime
|
|
22
|
+
The Runtime class to be instantiated by this builder.
|
|
23
|
+
|
|
24
|
+
Raises
|
|
25
|
+
------
|
|
26
|
+
BuilderError
|
|
27
|
+
If RUNTIME_CLASS is not set in the implementing class.
|
|
14
28
|
"""
|
|
15
29
|
|
|
16
|
-
# Class variables
|
|
17
30
|
RUNTIME_CLASS: Runtime = None
|
|
18
31
|
|
|
19
32
|
def __init__(self) -> None:
|
|
@@ -27,6 +40,6 @@ class RuntimeBuilder:
|
|
|
27
40
|
Returns
|
|
28
41
|
-------
|
|
29
42
|
Runtime
|
|
30
|
-
Runtime
|
|
43
|
+
A new instance of the configured Runtime class.
|
|
31
44
|
"""
|
|
32
45
|
return self.RUNTIME_CLASS(project, *args, **kwargs)
|
digitalhub/runtimes/enums.py
CHANGED
|
@@ -5,7 +5,17 @@ from enum import Enum
|
|
|
5
5
|
|
|
6
6
|
class RuntimeEnvVar(Enum):
|
|
7
7
|
"""
|
|
8
|
-
Environment variables.
|
|
8
|
+
Environment variables used by runtime execution environments.
|
|
9
|
+
|
|
10
|
+
These variables are automatically set in the runtime context
|
|
11
|
+
and can be accessed during task execution.
|
|
12
|
+
|
|
13
|
+
Values
|
|
14
|
+
------
|
|
15
|
+
PROJECT : str
|
|
16
|
+
Environment variable name for the current project identifier
|
|
17
|
+
RUN_ID : str
|
|
18
|
+
Environment variable name for the current run identifier
|
|
9
19
|
"""
|
|
10
20
|
|
|
11
21
|
PROJECT = "PROJECT_NAME"
|
|
@@ -31,10 +31,29 @@ class ClientDHCoreConfigurator:
|
|
|
31
31
|
Configurator object used to configure the client.
|
|
32
32
|
"""
|
|
33
33
|
|
|
34
|
+
def __init__(self) -> None:
|
|
35
|
+
self._current_env = configurator.get_current_env()
|
|
36
|
+
|
|
34
37
|
##############################
|
|
35
38
|
# Configuration methods
|
|
36
39
|
##############################
|
|
37
40
|
|
|
41
|
+
def check_config(self) -> None:
|
|
42
|
+
"""
|
|
43
|
+
Check if the config is valid.
|
|
44
|
+
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
config : dict
|
|
48
|
+
Configuration dictionary.
|
|
49
|
+
|
|
50
|
+
Returns
|
|
51
|
+
-------
|
|
52
|
+
None
|
|
53
|
+
"""
|
|
54
|
+
if configurator.get_current_env() != self._current_env:
|
|
55
|
+
self.configure()
|
|
56
|
+
|
|
38
57
|
def configure(self, config: dict | None = None) -> None:
|
|
39
58
|
"""
|
|
40
59
|
Configure the client attributes with config (given or from
|
|
@@ -3,7 +3,8 @@ from __future__ import annotations
|
|
|
3
3
|
import os
|
|
4
4
|
|
|
5
5
|
from digitalhub.stores.configurator.credentials_store import CredentialsStore
|
|
6
|
-
from digitalhub.stores.configurator.
|
|
6
|
+
from digitalhub.stores.configurator.enums import SetCreds
|
|
7
|
+
from digitalhub.stores.configurator.ini_module import load_from_file, read_env_from_file, set_current_env, write_config
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class EnvConfigurator:
|
|
@@ -16,7 +17,7 @@ class EnvConfigurator:
|
|
|
16
17
|
self._creds_store = CredentialsStore()
|
|
17
18
|
|
|
18
19
|
# Current credentials set (__default by default)
|
|
19
|
-
self._environment =
|
|
20
|
+
self._environment = os.getenv(SetCreds.DH_ENV.value, SetCreds.DEFAULT.value)
|
|
20
21
|
|
|
21
22
|
##############################
|
|
22
23
|
# Public methods
|
|
@@ -36,6 +37,7 @@ class EnvConfigurator:
|
|
|
36
37
|
None
|
|
37
38
|
"""
|
|
38
39
|
self._environment = creds_set
|
|
40
|
+
set_current_env(creds_set)
|
|
39
41
|
|
|
40
42
|
def get_current_env(self) -> str:
|
|
41
43
|
"""
|
|
@@ -105,6 +107,7 @@ class EnvConfigurator:
|
|
|
105
107
|
str | None
|
|
106
108
|
Environment variable value.
|
|
107
109
|
"""
|
|
110
|
+
self._environment = read_env_from_file()
|
|
108
111
|
return load_from_file(var)
|
|
109
112
|
|
|
110
113
|
def write_env(self, key_to_include: list[str] | None = None) -> None:
|
|
@@ -13,6 +13,23 @@ from digitalhub.utils.exceptions import ClientError
|
|
|
13
13
|
ENV_FILE = Path.home() / ".dhcore.ini"
|
|
14
14
|
|
|
15
15
|
|
|
16
|
+
def load_file() -> ConfigParser:
|
|
17
|
+
"""
|
|
18
|
+
Load current credentials set from the .dhcore.ini file.
|
|
19
|
+
|
|
20
|
+
Returns
|
|
21
|
+
-------
|
|
22
|
+
ConfigParser
|
|
23
|
+
Credentials set name.
|
|
24
|
+
"""
|
|
25
|
+
try:
|
|
26
|
+
file = ConfigParser()
|
|
27
|
+
file.read(ENV_FILE)
|
|
28
|
+
return file
|
|
29
|
+
except Exception as e:
|
|
30
|
+
raise ClientError(f"Failed to read env file: {e}")
|
|
31
|
+
|
|
32
|
+
|
|
16
33
|
def load_from_file(var: str) -> str | None:
|
|
17
34
|
"""
|
|
18
35
|
Load variable from config file.
|
|
@@ -29,9 +46,8 @@ def load_from_file(var: str) -> str | None:
|
|
|
29
46
|
str | None
|
|
30
47
|
Environment variable value.
|
|
31
48
|
"""
|
|
32
|
-
cfg = ConfigParser()
|
|
33
|
-
cfg.read(ENV_FILE)
|
|
34
49
|
try:
|
|
50
|
+
cfg = load_file()
|
|
35
51
|
profile = cfg["DEFAULT"]["current_environment"]
|
|
36
52
|
return cfg[profile].get(var)
|
|
37
53
|
except KeyError:
|
|
@@ -55,8 +71,7 @@ def write_config(creds: dict, environment: str) -> None:
|
|
|
55
71
|
None
|
|
56
72
|
"""
|
|
57
73
|
try:
|
|
58
|
-
cfg =
|
|
59
|
-
cfg.read(ENV_FILE)
|
|
74
|
+
cfg = load_file()
|
|
60
75
|
|
|
61
76
|
sections = cfg.sections()
|
|
62
77
|
if environment not in sections:
|
|
@@ -72,3 +87,42 @@ def write_config(creds: dict, environment: str) -> None:
|
|
|
72
87
|
|
|
73
88
|
except Exception as e:
|
|
74
89
|
raise ClientError(f"Failed to write env file: {e}")
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def set_current_env(environment: str) -> None:
|
|
93
|
+
"""
|
|
94
|
+
Set the current credentials set.
|
|
95
|
+
|
|
96
|
+
Parameters
|
|
97
|
+
----------
|
|
98
|
+
environment : str
|
|
99
|
+
Credentials set name.
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
103
|
+
None
|
|
104
|
+
"""
|
|
105
|
+
try:
|
|
106
|
+
cfg = load_file()
|
|
107
|
+
cfg["DEFAULT"]["current_environment"] = environment
|
|
108
|
+
with open(ENV_FILE, "w") as inifile:
|
|
109
|
+
cfg.write(inifile)
|
|
110
|
+
|
|
111
|
+
except Exception as e:
|
|
112
|
+
raise ClientError(f"Failed to write env file: {e}")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def read_env_from_file() -> str:
|
|
116
|
+
"""
|
|
117
|
+
Read the current credentials set from the .dhcore.ini file.
|
|
118
|
+
|
|
119
|
+
Returns
|
|
120
|
+
-------
|
|
121
|
+
str
|
|
122
|
+
Credentials set name.
|
|
123
|
+
"""
|
|
124
|
+
try:
|
|
125
|
+
cfg = load_file()
|
|
126
|
+
return cfg["DEFAULT"]["current_environment"]
|
|
127
|
+
except Exception as e:
|
|
128
|
+
raise ClientError(f"Failed to read env file: {e}")
|
digitalhub/stores/data/api.py
CHANGED
|
@@ -8,7 +8,7 @@ if typing.TYPE_CHECKING:
|
|
|
8
8
|
from digitalhub.stores.data._base.store import Store
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
def get_store(project: str, uri: str
|
|
11
|
+
def get_store(project: str, uri: str) -> Store:
|
|
12
12
|
"""
|
|
13
13
|
Get store instance by URI.
|
|
14
14
|
|
|
@@ -26,4 +26,4 @@ def get_store(project: str, uri: str, config: dict | None = None) -> Store:
|
|
|
26
26
|
Store
|
|
27
27
|
Store instance.
|
|
28
28
|
"""
|
|
29
|
-
return store_builder.get(
|
|
29
|
+
return store_builder.get(project, uri)
|
|
@@ -44,9 +44,9 @@ class StoreBuilder:
|
|
|
44
44
|
"""
|
|
45
45
|
|
|
46
46
|
def __init__(self) -> None:
|
|
47
|
-
self._instances: dict[str, Store] = {}
|
|
47
|
+
self._instances: dict[str, dict[str, Store]] = {}
|
|
48
48
|
|
|
49
|
-
def build(self,
|
|
49
|
+
def build(self, project: str, store_type: str) -> None:
|
|
50
50
|
"""
|
|
51
51
|
Build a store instance and register it.
|
|
52
52
|
|
|
@@ -55,7 +55,6 @@ class StoreBuilder:
|
|
|
55
55
|
store_type : str
|
|
56
56
|
Store type.
|
|
57
57
|
config : dict
|
|
58
|
-
Store configuration.
|
|
59
58
|
|
|
60
59
|
Returns
|
|
61
60
|
-------
|
|
@@ -64,9 +63,9 @@ class StoreBuilder:
|
|
|
64
63
|
env = get_current_env()
|
|
65
64
|
if env not in self._instances:
|
|
66
65
|
self._instances[env] = {}
|
|
67
|
-
self._instances[env][store_type] = _get_class_from_type(store_type)(
|
|
66
|
+
self._instances[env][store_type] = _get_class_from_type(store_type)()
|
|
68
67
|
|
|
69
|
-
def get(self,
|
|
68
|
+
def get(self, project: str, uri: str) -> Store:
|
|
70
69
|
"""
|
|
71
70
|
Get a store instance by URI.
|
|
72
71
|
|
|
@@ -87,7 +86,7 @@ class StoreBuilder:
|
|
|
87
86
|
try:
|
|
88
87
|
return self._instances[env][store_type]
|
|
89
88
|
except KeyError:
|
|
90
|
-
self.build(
|
|
89
|
+
self.build(project, store_type)
|
|
91
90
|
return self._instances[env][store_type]
|
|
92
91
|
|
|
93
92
|
|
|
@@ -18,7 +18,6 @@ class S3StoreConfigurator:
|
|
|
18
18
|
S3StoreEnv.ENDPOINT_URL,
|
|
19
19
|
S3StoreEnv.ACCESS_KEY_ID,
|
|
20
20
|
S3StoreEnv.SECRET_ACCESS_KEY,
|
|
21
|
-
S3StoreEnv.BUCKET_NAME,
|
|
22
21
|
]
|
|
23
22
|
optional_vars = [
|
|
24
23
|
S3StoreEnv.REGION,
|
|
@@ -26,29 +25,13 @@ class S3StoreConfigurator:
|
|
|
26
25
|
S3StoreEnv.SESSION_TOKEN,
|
|
27
26
|
]
|
|
28
27
|
|
|
29
|
-
def __init__(self, config: dict
|
|
30
|
-
|
|
28
|
+
def __init__(self, config: dict) -> None:
|
|
29
|
+
...
|
|
31
30
|
|
|
32
31
|
##############################
|
|
33
32
|
# Configuration methods
|
|
34
33
|
##############################
|
|
35
34
|
|
|
36
|
-
def configure(self, config: dict | None = None) -> None:
|
|
37
|
-
"""
|
|
38
|
-
Configure the store by getting the credentials from user
|
|
39
|
-
provided config or from environment.
|
|
40
|
-
|
|
41
|
-
Parameters
|
|
42
|
-
----------
|
|
43
|
-
config : dict
|
|
44
|
-
Configuration dictionary.
|
|
45
|
-
|
|
46
|
-
Returns
|
|
47
|
-
-------
|
|
48
|
-
None
|
|
49
|
-
"""
|
|
50
|
-
self._get_env_config()
|
|
51
|
-
|
|
52
35
|
def get_boto3_client_config(self, origin: str) -> dict:
|
|
53
36
|
"""
|
|
54
37
|
Get S3 credentials (access key, secret key,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import typing
|
|
4
3
|
from io import BytesIO
|
|
5
4
|
from pathlib import Path
|
|
6
5
|
from typing import Any, Type
|
|
@@ -8,7 +7,7 @@ from urllib.parse import urlparse
|
|
|
8
7
|
|
|
9
8
|
import boto3
|
|
10
9
|
import botocore.client # pylint: disable=unused-import
|
|
11
|
-
from botocore.exceptions import ClientError
|
|
10
|
+
from botocore.exceptions import ClientError, NoCredentialsError
|
|
12
11
|
|
|
13
12
|
from digitalhub.stores.configurator.enums import CredsOrigin
|
|
14
13
|
from digitalhub.stores.data._base.store import Store
|
|
@@ -19,9 +18,6 @@ from digitalhub.utils.exceptions import StoreError
|
|
|
19
18
|
from digitalhub.utils.file_utils import get_file_info_from_s3, get_file_mime_type
|
|
20
19
|
from digitalhub.utils.types import SourcesOrListOfSources
|
|
21
20
|
|
|
22
|
-
if typing.TYPE_CHECKING:
|
|
23
|
-
pass
|
|
24
|
-
|
|
25
21
|
# Type aliases
|
|
26
22
|
S3Client = Type["botocore.client.S3"]
|
|
27
23
|
|
|
@@ -32,10 +28,8 @@ class S3Store(Store):
|
|
|
32
28
|
artifacts on S3 based storage.
|
|
33
29
|
"""
|
|
34
30
|
|
|
35
|
-
def __init__(self
|
|
36
|
-
super().__init__()
|
|
31
|
+
def __init__(self) -> None:
|
|
37
32
|
self._configurator = S3StoreConfigurator()
|
|
38
|
-
self._configurator.configure(config)
|
|
39
33
|
|
|
40
34
|
##############################
|
|
41
35
|
# I/O methods
|
|
@@ -655,7 +649,7 @@ class S3Store(Store):
|
|
|
655
649
|
"""
|
|
656
650
|
try:
|
|
657
651
|
client.head_bucket(Bucket=bucket)
|
|
658
|
-
except ClientError:
|
|
652
|
+
except (ClientError, NoCredentialsError):
|
|
659
653
|
raise StoreError("No access to s3 bucket!")
|
|
660
654
|
|
|
661
655
|
@staticmethod
|
|
@@ -12,31 +12,21 @@ class SqlStoreConfigurator:
|
|
|
12
12
|
provided config or from environment.
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
required_vars = [
|
|
16
|
+
SqlStoreEnv.USERNAME,
|
|
17
|
+
SqlStoreEnv.PASSWORD,
|
|
18
|
+
SqlStoreEnv.HOST,
|
|
19
|
+
SqlStoreEnv.PORT,
|
|
20
|
+
SqlStoreEnv.DATABASE,
|
|
21
|
+
]
|
|
16
22
|
|
|
17
|
-
def __init__(self
|
|
18
|
-
self.configure(
|
|
23
|
+
def __init__(self) -> None:
|
|
24
|
+
self.config = self.configure()
|
|
19
25
|
|
|
20
26
|
##############################
|
|
21
27
|
# Configuration methods
|
|
22
28
|
##############################
|
|
23
29
|
|
|
24
|
-
def configure(self, config: dict | None = None) -> None:
|
|
25
|
-
"""
|
|
26
|
-
Configure the store by getting the credentials from user
|
|
27
|
-
provided config or from environment.
|
|
28
|
-
|
|
29
|
-
Parameters
|
|
30
|
-
----------
|
|
31
|
-
config : dict
|
|
32
|
-
Configuration dictionary.
|
|
33
|
-
|
|
34
|
-
Returns
|
|
35
|
-
-------
|
|
36
|
-
None
|
|
37
|
-
"""
|
|
38
|
-
self._get_env_config()
|
|
39
|
-
|
|
40
30
|
def get_sql_conn_string(self, origin: str) -> str:
|
|
41
31
|
"""
|
|
42
32
|
Get the connection string from environment variables.
|
|
@@ -74,7 +64,7 @@ class SqlStoreConfigurator:
|
|
|
74
64
|
dict
|
|
75
65
|
The credentials.
|
|
76
66
|
"""
|
|
77
|
-
credentials = {var.value: configurator.load_from_env(var.value) for var in self.
|
|
67
|
+
credentials = {var.value: configurator.load_from_env(var.value) for var in self.required_vars}
|
|
78
68
|
self._set_credentials(credentials)
|
|
79
69
|
return credentials
|
|
80
70
|
|
|
@@ -87,7 +77,7 @@ class SqlStoreConfigurator:
|
|
|
87
77
|
dict
|
|
88
78
|
The credentials.
|
|
89
79
|
"""
|
|
90
|
-
credentials = {var.value: configurator.load_from_file(var.value) for var in self.
|
|
80
|
+
credentials = {var.value: configurator.load_from_file(var.value) for var in self.required_vars}
|
|
91
81
|
self._set_credentials(credentials)
|
|
92
82
|
return credentials
|
|
93
83
|
|
|
@@ -27,10 +27,8 @@ class SqlStore(Store):
|
|
|
27
27
|
artifacts on SQL based storage.
|
|
28
28
|
"""
|
|
29
29
|
|
|
30
|
-
def __init__(self
|
|
31
|
-
super().__init__()
|
|
30
|
+
def __init__(self) -> None:
|
|
32
31
|
self._configurator = SqlStoreConfigurator()
|
|
33
|
-
self._configurator.configure(config)
|
|
34
32
|
|
|
35
33
|
##############################
|
|
36
34
|
# I/O methods
|