digitalhub 0.10.1__py3-none-any.whl → 0.11.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.
- 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/configurator/configurator.py +2 -1
- digitalhub/stores/configurator/enums.py +9 -0
- digitalhub/stores/data/api.py +4 -2
- digitalhub/stores/data/builder.py +4 -4
- digitalhub/stores/data/enums.py +11 -0
- digitalhub/stores/data/local/store.py +2 -2
- digitalhub/stores/data/remote/store.py +2 -2
- digitalhub/stores/data/s3/configurator.py +11 -7
- digitalhub/stores/data/s3/store.py +4 -10
- digitalhub/stores/data/sql/configurator.py +20 -11
- digitalhub/stores/data/sql/store.py +2 -4
- digitalhub/stores/data/utils.py +34 -0
- digitalhub/utils/uri_utils.py +5 -0
- {digitalhub-0.10.1.dist-info → digitalhub-0.11.0b0.dist-info}/METADATA +2 -3
- {digitalhub-0.10.1.dist-info → digitalhub-0.11.0b0.dist-info}/RECORD +56 -42
- digitalhub/factory/api.py +0 -277
- {digitalhub-0.10.1.dist-info → digitalhub-0.11.0b0.dist-info}/WHEEL +0 -0
- {digitalhub-0.10.1.dist-info → digitalhub-0.11.0b0.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"
|
|
@@ -3,6 +3,7 @@ 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.enums import SetCreds
|
|
6
7
|
from digitalhub.stores.configurator.ini_module import load_from_file, write_config
|
|
7
8
|
|
|
8
9
|
|
|
@@ -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
|
digitalhub/stores/data/api.py
CHANGED
|
@@ -2,13 +2,14 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import typing
|
|
4
4
|
|
|
5
|
+
from digitalhub.context.api import get_context
|
|
5
6
|
from digitalhub.stores.data.builder import store_builder
|
|
6
7
|
|
|
7
8
|
if typing.TYPE_CHECKING:
|
|
8
9
|
from digitalhub.stores.data._base.store import Store
|
|
9
10
|
|
|
10
11
|
|
|
11
|
-
def get_store(project: str, uri: str
|
|
12
|
+
def get_store(project: str, uri: str) -> Store:
|
|
12
13
|
"""
|
|
13
14
|
Get store instance by URI.
|
|
14
15
|
|
|
@@ -26,4 +27,5 @@ def get_store(project: str, uri: str, config: dict | None = None) -> Store:
|
|
|
26
27
|
Store
|
|
27
28
|
Store instance.
|
|
28
29
|
"""
|
|
29
|
-
|
|
30
|
+
config = get_context(project).config
|
|
31
|
+
return store_builder.get(project, uri, config)
|
|
@@ -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, store_type: str, config: dict
|
|
49
|
+
def build(self, project: str, store_type: str, config: dict) -> None:
|
|
50
50
|
"""
|
|
51
51
|
Build a store instance and register it.
|
|
52
52
|
|
|
@@ -66,7 +66,7 @@ class StoreBuilder:
|
|
|
66
66
|
self._instances[env] = {}
|
|
67
67
|
self._instances[env][store_type] = _get_class_from_type(store_type)(config)
|
|
68
68
|
|
|
69
|
-
def get(self, uri: str, config: dict
|
|
69
|
+
def get(self, project: str, uri: str, config: dict) -> Store:
|
|
70
70
|
"""
|
|
71
71
|
Get a store instance by URI.
|
|
72
72
|
|
|
@@ -87,7 +87,7 @@ class StoreBuilder:
|
|
|
87
87
|
try:
|
|
88
88
|
return self._instances[env][store_type]
|
|
89
89
|
except KeyError:
|
|
90
|
-
self.build(store_type, config)
|
|
90
|
+
self.build(project, store_type, config)
|
|
91
91
|
return self._instances[env][store_type]
|
|
92
92
|
|
|
93
93
|
|
|
@@ -17,8 +17,8 @@ class LocalStore(Store):
|
|
|
17
17
|
artifacts on local filesystem based storage.
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
|
-
def __init__(self, config: dict
|
|
21
|
-
|
|
20
|
+
def __init__(self, config: dict):
|
|
21
|
+
pass
|
|
22
22
|
|
|
23
23
|
##############################
|
|
24
24
|
# I/O methods
|
|
@@ -16,8 +16,8 @@ class RemoteStore(Store):
|
|
|
16
16
|
artifacts from remote HTTP based storage.
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
|
-
def __init__(self, config: dict
|
|
20
|
-
|
|
19
|
+
def __init__(self, config: dict):
|
|
20
|
+
pass
|
|
21
21
|
|
|
22
22
|
##############################
|
|
23
23
|
# I/O methods
|
|
@@ -25,18 +25,20 @@ class S3StoreConfigurator:
|
|
|
25
25
|
S3StoreEnv.SIGNATURE_VERSION,
|
|
26
26
|
S3StoreEnv.SESSION_TOKEN,
|
|
27
27
|
]
|
|
28
|
+
project_vars = [
|
|
29
|
+
S3StoreEnv.BUCKET_NAME,
|
|
30
|
+
]
|
|
28
31
|
|
|
29
|
-
def __init__(self, config: dict
|
|
30
|
-
self.configure(config)
|
|
32
|
+
def __init__(self, config: dict) -> None:
|
|
33
|
+
self.config = self.configure(config)
|
|
31
34
|
|
|
32
35
|
##############################
|
|
33
36
|
# Configuration methods
|
|
34
37
|
##############################
|
|
35
38
|
|
|
36
|
-
def configure(self, config: dict
|
|
39
|
+
def configure(self, config: dict) -> dict:
|
|
37
40
|
"""
|
|
38
|
-
Configure the store by getting
|
|
39
|
-
provided config or from environment.
|
|
41
|
+
Configure the store by getting vars from project.
|
|
40
42
|
|
|
41
43
|
Parameters
|
|
42
44
|
----------
|
|
@@ -45,9 +47,10 @@ class S3StoreConfigurator:
|
|
|
45
47
|
|
|
46
48
|
Returns
|
|
47
49
|
-------
|
|
48
|
-
|
|
50
|
+
dict
|
|
51
|
+
Configuration dictionary.
|
|
49
52
|
"""
|
|
50
|
-
|
|
53
|
+
return {k: v for k, v in config.items() if k in self.project_vars}
|
|
51
54
|
|
|
52
55
|
def get_boto3_client_config(self, origin: str) -> dict:
|
|
53
56
|
"""
|
|
@@ -70,6 +73,7 @@ class S3StoreConfigurator:
|
|
|
70
73
|
creds = self._get_file_config()
|
|
71
74
|
else:
|
|
72
75
|
raise StoreError(f"Unknown origin: {origin}")
|
|
76
|
+
creds = {**creds, **self.config}
|
|
73
77
|
return {
|
|
74
78
|
"endpoint_url": creds[S3StoreEnv.ENDPOINT_URL.value],
|
|
75
79
|
"aws_access_key_id": creds[S3StoreEnv.ACCESS_KEY_ID.value],
|
|
@@ -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, config: dict
|
|
36
|
-
|
|
37
|
-
self._configurator = S3StoreConfigurator()
|
|
38
|
-
self._configurator.configure(config)
|
|
31
|
+
def __init__(self, config: dict) -> None:
|
|
32
|
+
self._configurator = S3StoreConfigurator(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,19 +12,27 @@ class SqlStoreConfigurator:
|
|
|
12
12
|
provided config or from environment.
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
required_vars = [
|
|
16
|
+
SqlStoreEnv.USERNAME,
|
|
17
|
+
SqlStoreEnv.PASSWORD,
|
|
18
|
+
SqlStoreEnv.HOST,
|
|
19
|
+
SqlStoreEnv.PORT,
|
|
20
|
+
SqlStoreEnv.DATABASE,
|
|
21
|
+
]
|
|
22
|
+
project_vars = [
|
|
23
|
+
SqlStoreEnv.DATABASE,
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
def __init__(self, config: dict) -> None:
|
|
27
|
+
self.config = self.configure(config)
|
|
19
28
|
|
|
20
29
|
##############################
|
|
21
30
|
# Configuration methods
|
|
22
31
|
##############################
|
|
23
32
|
|
|
24
|
-
def configure(self, config: dict
|
|
33
|
+
def configure(self, config: dict) -> dict:
|
|
25
34
|
"""
|
|
26
|
-
Configure the store by getting
|
|
27
|
-
provided config or from environment.
|
|
35
|
+
Configure the store by getting vars from project.
|
|
28
36
|
|
|
29
37
|
Parameters
|
|
30
38
|
----------
|
|
@@ -33,9 +41,10 @@ class SqlStoreConfigurator:
|
|
|
33
41
|
|
|
34
42
|
Returns
|
|
35
43
|
-------
|
|
36
|
-
|
|
44
|
+
dict
|
|
45
|
+
Configuration dictionary.
|
|
37
46
|
"""
|
|
38
|
-
|
|
47
|
+
return {k: v for k, v in config.items() if k in self.project_vars}
|
|
39
48
|
|
|
40
49
|
def get_sql_conn_string(self, origin: str) -> str:
|
|
41
50
|
"""
|
|
@@ -74,7 +83,7 @@ class SqlStoreConfigurator:
|
|
|
74
83
|
dict
|
|
75
84
|
The credentials.
|
|
76
85
|
"""
|
|
77
|
-
credentials = {var.value: configurator.load_from_env(var.value) for var in self.
|
|
86
|
+
credentials = {var.value: configurator.load_from_env(var.value) for var in self.required_vars}
|
|
78
87
|
self._set_credentials(credentials)
|
|
79
88
|
return credentials
|
|
80
89
|
|
|
@@ -87,7 +96,7 @@ class SqlStoreConfigurator:
|
|
|
87
96
|
dict
|
|
88
97
|
The credentials.
|
|
89
98
|
"""
|
|
90
|
-
credentials = {var.value: configurator.load_from_file(var.value) for var in self.
|
|
99
|
+
credentials = {var.value: configurator.load_from_file(var.value) for var in self.required_vars}
|
|
91
100
|
self._set_credentials(credentials)
|
|
92
101
|
return credentials
|
|
93
102
|
|
|
@@ -27,10 +27,8 @@ class SqlStore(Store):
|
|
|
27
27
|
artifacts on SQL based storage.
|
|
28
28
|
"""
|
|
29
29
|
|
|
30
|
-
def __init__(self, config: dict
|
|
31
|
-
|
|
32
|
-
self._configurator = SqlStoreConfigurator()
|
|
33
|
-
self._configurator.configure(config)
|
|
30
|
+
def __init__(self, config: dict) -> None:
|
|
31
|
+
self._configurator = SqlStoreConfigurator(config)
|
|
34
32
|
|
|
35
33
|
##############################
|
|
36
34
|
# I/O methods
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from digitalhub.context.api import get_context
|
|
4
|
+
from digitalhub.stores.configurator.configurator import configurator
|
|
5
|
+
from digitalhub.stores.data.enums import StoreEnv
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_default_store(project: str) -> str:
|
|
9
|
+
"""
|
|
10
|
+
Get default store URI.
|
|
11
|
+
|
|
12
|
+
Parameters
|
|
13
|
+
----------
|
|
14
|
+
project : str
|
|
15
|
+
Project name.
|
|
16
|
+
|
|
17
|
+
Returns
|
|
18
|
+
-------
|
|
19
|
+
str
|
|
20
|
+
Default store URI.
|
|
21
|
+
"""
|
|
22
|
+
context = get_context(project)
|
|
23
|
+
store = context.config.get("default_files_store")
|
|
24
|
+
if store is not None:
|
|
25
|
+
return store
|
|
26
|
+
store = configurator.load_var(StoreEnv.DEFAULT_FILES_STORE.value)
|
|
27
|
+
if store is None or store == "":
|
|
28
|
+
raise ValueError(
|
|
29
|
+
"No default store found. "
|
|
30
|
+
"Please set a default store "
|
|
31
|
+
"in your environment (e.g. export DEFAULT_FILES_STORE=) "
|
|
32
|
+
"or set it in project config."
|
|
33
|
+
)
|
|
34
|
+
return store
|
digitalhub/utils/uri_utils.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import re
|
|
3
4
|
from enum import Enum
|
|
4
5
|
from urllib.parse import unquote, urlparse
|
|
5
6
|
|
|
@@ -95,6 +96,10 @@ def map_uri_scheme(uri: str) -> str:
|
|
|
95
96
|
ValueError
|
|
96
97
|
If the scheme is unknown or invalid.
|
|
97
98
|
"""
|
|
99
|
+
# Check for Windows paths (e.g. C:\path\to\file or \\network\share)
|
|
100
|
+
if re.match(r"^[a-zA-Z]:\\", uri) or uri.startswith(r"\\"):
|
|
101
|
+
return SchemeCategory.LOCAL.value
|
|
102
|
+
|
|
98
103
|
scheme = urlparse(uri).scheme
|
|
99
104
|
if scheme in list_enum(LocalSchemes):
|
|
100
105
|
return SchemeCategory.LOCAL.value
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: digitalhub
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0b0
|
|
4
4
|
Summary: Python SDK for Digitalhub
|
|
5
5
|
Project-URL: Homepage, https://github.com/scc-digitalhub/digitalhub-sdk
|
|
6
6
|
Author-email: Fondazione Bruno Kessler <dslab@fbk.eu>, Matteo Martini <mmartini@fbk.eu>
|
|
@@ -230,11 +230,10 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
230
230
|
Requires-Python: <3.13,>=3.9
|
|
231
231
|
Requires-Dist: boto3
|
|
232
232
|
Requires-Dist: gitpython>=3
|
|
233
|
-
Requires-Dist: numpy
|
|
233
|
+
Requires-Dist: numpy
|
|
234
234
|
Requires-Dist: psycopg2-binary
|
|
235
235
|
Requires-Dist: pyarrow
|
|
236
236
|
Requires-Dist: pydantic
|
|
237
|
-
Requires-Dist: python-dotenv
|
|
238
237
|
Requires-Dist: python-slugify
|
|
239
238
|
Requires-Dist: pyyaml
|
|
240
239
|
Requires-Dist: requests
|