digitalhub 0.10.2__py3-none-any.whl → 0.11.0__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 +52 -5
- digitalhub/entities/_base/material/utils.py +11 -11
- digitalhub/entities/_commons/enums.py +4 -0
- digitalhub/entities/_processors/base.py +15 -15
- digitalhub/entities/_processors/context.py +62 -15
- digitalhub/entities/_processors/utils.py +2 -2
- digitalhub/entities/builders.py +2 -0
- digitalhub/entities/function/_base/entity.py +3 -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 +20 -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 +40 -0
- digitalhub/entities/trigger/_base/status.py +9 -0
- digitalhub/entities/trigger/crud.py +309 -0
- digitalhub/entities/trigger/lifecycle/__init__.py +0 -0
- digitalhub/entities/trigger/lifecycle/builder.py +19 -0
- digitalhub/entities/trigger/lifecycle/entity.py +32 -0
- digitalhub/entities/trigger/lifecycle/spec.py +38 -0
- digitalhub/entities/trigger/lifecycle/status.py +9 -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 +29 -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 +80 -11
- 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 +0 -20
- digitalhub/stores/data/s3/enums.py +2 -3
- digitalhub/stores/data/s3/store.py +4 -10
- digitalhub/stores/data/s3/utils.py +13 -18
- digitalhub/stores/data/sql/configurator.py +9 -22
- digitalhub/stores/data/sql/store.py +1 -3
- digitalhub/stores/data/utils.py +34 -0
- digitalhub/utils/file_utils.py +1 -1
- digitalhub/utils/generic_utils.py +37 -0
- digitalhub/utils/uri_utils.py +5 -0
- {digitalhub-0.10.2.dist-info → digitalhub-0.11.0.dist-info}/METADATA +1 -1
- {digitalhub-0.10.2.dist-info → digitalhub-0.11.0.dist-info}/RECORD +69 -52
- digitalhub/factory/api.py +0 -277
- digitalhub/stores/data/s3/models.py +0 -21
- digitalhub/stores/data/sql/models.py +0 -24
- {digitalhub-0.10.2.dist-info → digitalhub-0.11.0.dist-info}/WHEEL +0 -0
- {digitalhub-0.10.2.dist-info → digitalhub-0.11.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -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 | None:
|
|
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:
|
|
128
|
+
return None
|
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,10 @@ class S3StoreConfigurator:
|
|
|
26
25
|
S3StoreEnv.SESSION_TOKEN,
|
|
27
26
|
]
|
|
28
27
|
|
|
29
|
-
def __init__(self, config: dict | None = None) -> None:
|
|
30
|
-
self.configure(config)
|
|
31
|
-
|
|
32
28
|
##############################
|
|
33
29
|
# Configuration methods
|
|
34
30
|
##############################
|
|
35
31
|
|
|
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
32
|
def get_boto3_client_config(self, origin: str) -> dict:
|
|
53
33
|
"""
|
|
54
34
|
Get S3 credentials (access key, secret key,
|
|
@@ -8,10 +8,9 @@ class S3StoreEnv(Enum):
|
|
|
8
8
|
S3Store environment
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
ENDPOINT_URL = "
|
|
11
|
+
ENDPOINT_URL = "AWS_ENDPOINT_URL"
|
|
12
12
|
ACCESS_KEY_ID = "AWS_ACCESS_KEY_ID"
|
|
13
13
|
SECRET_ACCESS_KEY = "AWS_SECRET_ACCESS_KEY"
|
|
14
14
|
SESSION_TOKEN = "AWS_SESSION_TOKEN"
|
|
15
|
-
|
|
16
|
-
REGION = "S3_REGION"
|
|
15
|
+
REGION = "AWS_REGION"
|
|
17
16
|
SIGNATURE_VERSION = "S3_SIGNATURE_VERSION"
|
|
@@ -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,8 +649,8 @@ class S3Store(Store):
|
|
|
655
649
|
"""
|
|
656
650
|
try:
|
|
657
651
|
client.head_bucket(Bucket=bucket)
|
|
658
|
-
except ClientError:
|
|
659
|
-
raise StoreError("No access to s3 bucket!")
|
|
652
|
+
except (ClientError, NoCredentialsError) as err:
|
|
653
|
+
raise StoreError(f"No access to s3 bucket! Error: {err}")
|
|
660
654
|
|
|
661
655
|
@staticmethod
|
|
662
656
|
def _get_key(path: str) -> str:
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import os
|
|
4
3
|
from pathlib import Path
|
|
5
4
|
from urllib.parse import urlparse
|
|
6
5
|
|
|
7
6
|
from boto3 import client as boto3_client
|
|
8
7
|
|
|
9
|
-
from digitalhub.stores.
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
from digitalhub.stores.configurator.enums import CredsOrigin
|
|
9
|
+
from digitalhub.stores.data.s3.configurator import S3StoreConfigurator
|
|
10
|
+
from digitalhub.utils.exceptions import StoreError
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
def get_bucket_name(path: str) -> str:
|
|
@@ -63,17 +62,13 @@ def get_s3_source(bucket: str, key: str, filename: Path) -> None:
|
|
|
63
62
|
-------
|
|
64
63
|
None
|
|
65
64
|
"""
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
str
|
|
77
|
-
The S3 bucket name.
|
|
78
|
-
"""
|
|
79
|
-
return os.getenv(S3StoreEnv.BUCKET_NAME.value, DEFAULT_BUCKET)
|
|
65
|
+
# Try to get client from environment variables
|
|
66
|
+
try:
|
|
67
|
+
cfg = S3StoreConfigurator().get_boto3_client_config(CredsOrigin.ENV.value)
|
|
68
|
+
s3 = boto3_client("s3", **cfg)
|
|
69
|
+
s3.download_file(bucket, key, filename)
|
|
70
|
+
|
|
71
|
+
# Fallback to file
|
|
72
|
+
except StoreError:
|
|
73
|
+
cfg = S3StoreConfigurator().get_boto3_client_config(CredsOrigin.FILE.value)
|
|
74
|
+
s3.download_file(bucket, key, filename)
|
|
@@ -12,31 +12,18 @@ 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
|
+
]
|
|
19
22
|
|
|
20
23
|
##############################
|
|
21
24
|
# Configuration methods
|
|
22
25
|
##############################
|
|
23
26
|
|
|
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
27
|
def get_sql_conn_string(self, origin: str) -> str:
|
|
41
28
|
"""
|
|
42
29
|
Get the connection string from environment variables.
|
|
@@ -74,7 +61,7 @@ class SqlStoreConfigurator:
|
|
|
74
61
|
dict
|
|
75
62
|
The credentials.
|
|
76
63
|
"""
|
|
77
|
-
credentials = {var.value: configurator.load_from_env(var.value) for var in self.
|
|
64
|
+
credentials = {var.value: configurator.load_from_env(var.value) for var in self.required_vars}
|
|
78
65
|
self._set_credentials(credentials)
|
|
79
66
|
return credentials
|
|
80
67
|
|
|
@@ -87,7 +74,7 @@ class SqlStoreConfigurator:
|
|
|
87
74
|
dict
|
|
88
75
|
The credentials.
|
|
89
76
|
"""
|
|
90
|
-
credentials = {var.value: configurator.load_from_file(var.value) for var in self.
|
|
77
|
+
credentials = {var.value: configurator.load_from_file(var.value) for var in self.required_vars}
|
|
91
78
|
self._set_credentials(credentials)
|
|
92
79
|
return credentials
|
|
93
80
|
|
|
@@ -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
|
|
@@ -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(StoreEnv.DEFAULT_FILES_STORE.value.lower())
|
|
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
|
+
f"in your environment (e.g. export {StoreEnv.DEFAULT_FILES_STORE.value}=) "
|
|
32
|
+
"or set it in project config."
|
|
33
|
+
)
|
|
34
|
+
return store
|
digitalhub/utils/file_utils.py
CHANGED
|
@@ -190,7 +190,7 @@ def get_file_info_from_s3(path: str, metadata: dict) -> None | dict:
|
|
|
190
190
|
if size < file_size_limit_multipart:
|
|
191
191
|
file_hash = "md5:" + file_hash
|
|
192
192
|
else:
|
|
193
|
-
file_hash = "
|
|
193
|
+
file_hash = "ETag:" + file_hash
|
|
194
194
|
|
|
195
195
|
name = get_path_name(path)
|
|
196
196
|
content_type = metadata["ContentType"]
|
|
@@ -8,6 +8,7 @@ from enum import Enum, EnumMeta
|
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
from types import MappingProxyType
|
|
10
10
|
from typing import Any, Callable
|
|
11
|
+
from warnings import warn
|
|
11
12
|
from zipfile import ZipFile
|
|
12
13
|
|
|
13
14
|
import numpy as np
|
|
@@ -235,3 +236,39 @@ def list_enum(enum: EnumMeta) -> list[Any]:
|
|
|
235
236
|
"""
|
|
236
237
|
vals: MappingProxyType[str, Enum] = enum.__members__
|
|
237
238
|
return [member.value for member in vals.values()]
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def carriage_return_warn(string: str) -> None:
|
|
242
|
+
"""
|
|
243
|
+
Print a warning message if string contains a carriage return (\r\n).
|
|
244
|
+
|
|
245
|
+
Parameters
|
|
246
|
+
----------
|
|
247
|
+
string : str
|
|
248
|
+
The string to check.
|
|
249
|
+
|
|
250
|
+
Returns
|
|
251
|
+
-------
|
|
252
|
+
None
|
|
253
|
+
"""
|
|
254
|
+
if "\r\n" in string:
|
|
255
|
+
warn("String contains a carriage return. It may not be parsed correctly from remote runtimes.")
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def read_source(path: str) -> str:
|
|
259
|
+
"""
|
|
260
|
+
Read a file.
|
|
261
|
+
|
|
262
|
+
Parameters
|
|
263
|
+
----------
|
|
264
|
+
path : Path
|
|
265
|
+
Path to the file.
|
|
266
|
+
|
|
267
|
+
Returns
|
|
268
|
+
-------
|
|
269
|
+
str
|
|
270
|
+
File content.
|
|
271
|
+
"""
|
|
272
|
+
text = read_text(path)
|
|
273
|
+
carriage_return_warn(text)
|
|
274
|
+
return encode_string(text)
|
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.0
|
|
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>
|