cosmotech-acceleration-library 2.0.0__py3-none-any.whl → 2.1.0rc1__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.
- cosmotech/coal/__init__.py +1 -1
- cosmotech/coal/azure/__init__.py +5 -5
- cosmotech/coal/azure/adx/__init__.py +24 -10
- cosmotech/coal/azure/adx/ingestion.py +10 -14
- cosmotech/coal/azure/adx/query.py +1 -1
- cosmotech/coal/azure/adx/utils.py +2 -2
- cosmotech/coal/azure/blob.py +14 -20
- cosmotech/coal/cosmotech_api/apis/dataset.py +135 -16
- cosmotech/coal/cosmotech_api/apis/runner.py +23 -19
- cosmotech/coal/postgresql/runner.py +8 -11
- cosmotech/coal/postgresql/store.py +20 -25
- cosmotech/coal/postgresql/utils.py +2 -1
- cosmotech/coal/singlestore/store.py +3 -2
- cosmotech/coal/store/__init__.py +16 -13
- cosmotech/coal/store/output/aws_channel.py +12 -11
- cosmotech/coal/store/output/az_storage_channel.py +9 -18
- cosmotech/coal/store/output/channel_interface.py +15 -0
- cosmotech/coal/store/output/channel_spliter.py +11 -5
- cosmotech/coal/store/output/postgres_channel.py +7 -10
- cosmotech/coal/store/pandas.py +1 -1
- cosmotech/coal/store/pyarrow.py +2 -2
- cosmotech/coal/store/store.py +4 -7
- cosmotech/coal/utils/configuration.py +76 -48
- cosmotech/csm_data/commands/adx_send_data.py +1 -1
- cosmotech/csm_data/commands/adx_send_runnerdata.py +3 -2
- cosmotech/csm_data/commands/api/run_load_data.py +10 -8
- cosmotech/csm_data/commands/az_storage_upload.py +3 -2
- cosmotech/csm_data/commands/store/dump_to_azure.py +3 -2
- cosmotech/csm_data/commands/store/dump_to_postgresql.py +3 -2
- cosmotech/csm_data/commands/store/list_tables.py +3 -2
- cosmotech/csm_data/commands/store/load_csv_folder.py +10 -4
- cosmotech/csm_data/commands/store/load_from_singlestore.py +3 -2
- cosmotech/csm_data/commands/store/reset.py +8 -3
- cosmotech/csm_data/main.py +4 -4
- cosmotech/csm_data/utils/decorators.py +4 -3
- cosmotech/translation/coal/en-US/coal/services/dataset.yml +6 -0
- {cosmotech_acceleration_library-2.0.0.dist-info → cosmotech_acceleration_library-2.1.0rc1.dist-info}/METADATA +26 -27
- {cosmotech_acceleration_library-2.0.0.dist-info → cosmotech_acceleration_library-2.1.0rc1.dist-info}/RECORD +42 -42
- {cosmotech_acceleration_library-2.0.0.dist-info → cosmotech_acceleration_library-2.1.0rc1.dist-info}/WHEEL +1 -1
- {cosmotech_acceleration_library-2.0.0.dist-info → cosmotech_acceleration_library-2.1.0rc1.dist-info}/entry_points.txt +0 -0
- {cosmotech_acceleration_library-2.0.0.dist-info → cosmotech_acceleration_library-2.1.0rc1.dist-info}/licenses/LICENSE +0 -0
- {cosmotech_acceleration_library-2.0.0.dist-info → cosmotech_acceleration_library-2.1.0rc1.dist-info}/top_level.txt +0 -0
cosmotech/coal/store/__init__.py
CHANGED
|
@@ -12,31 +12,34 @@ This module provides functions for working with the Store,
|
|
|
12
12
|
including loading and converting data.
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
|
-
# Re-export the Store class
|
|
16
|
-
from cosmotech.coal.store.store import Store
|
|
17
|
-
|
|
18
15
|
# Re-export functions from the csv module
|
|
19
16
|
from cosmotech.coal.store.csv import (
|
|
20
|
-
store_csv_file,
|
|
21
17
|
convert_store_table_to_csv,
|
|
18
|
+
store_csv_file,
|
|
22
19
|
)
|
|
23
20
|
|
|
24
21
|
# Re-export functions from the native_python module
|
|
25
22
|
from cosmotech.coal.store.native_python import (
|
|
26
|
-
store_pylist,
|
|
27
23
|
convert_table_as_pylist,
|
|
24
|
+
store_pylist,
|
|
28
25
|
)
|
|
29
|
-
|
|
30
|
-
# Re-export functions from the pandas module (if available)
|
|
31
|
-
|
|
32
26
|
from cosmotech.coal.store.pandas import (
|
|
33
|
-
store_dataframe,
|
|
34
27
|
convert_store_table_to_dataframe as convert_store_table_to_pandas_dataframe,
|
|
35
28
|
)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
29
|
+
from cosmotech.coal.store.pandas import (
|
|
30
|
+
store_dataframe,
|
|
31
|
+
)
|
|
39
32
|
from cosmotech.coal.store.pyarrow import (
|
|
40
|
-
store_table,
|
|
41
33
|
convert_store_table_to_dataframe as convert_store_table_to_pyarrow_table,
|
|
42
34
|
)
|
|
35
|
+
from cosmotech.coal.store.pyarrow import (
|
|
36
|
+
store_table,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# Re-export the Store class
|
|
40
|
+
from cosmotech.coal.store.store import Store
|
|
41
|
+
|
|
42
|
+
# Re-export functions from the pandas module (if available)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# Re-export functions from the pyarrow module (if available)
|
|
@@ -6,28 +6,29 @@ import pyarrow.parquet as pq
|
|
|
6
6
|
from cosmotech.orchestrator.utils.translate import T
|
|
7
7
|
|
|
8
8
|
from cosmotech.coal.aws import S3
|
|
9
|
-
from cosmotech.coal.store.output.channel_interface import
|
|
9
|
+
from cosmotech.coal.store.output.channel_interface import (
|
|
10
|
+
ChannelInterface,
|
|
11
|
+
MissingChannelConfigError,
|
|
12
|
+
)
|
|
10
13
|
from cosmotech.coal.store.store import Store
|
|
11
|
-
from cosmotech.coal.utils.configuration import Configuration
|
|
14
|
+
from cosmotech.coal.utils.configuration import Configuration, Dotdict
|
|
12
15
|
from cosmotech.coal.utils.logger import LOGGER
|
|
13
16
|
|
|
14
17
|
|
|
15
18
|
class AwsChannel(ChannelInterface):
|
|
16
19
|
required_keys = {
|
|
17
|
-
"
|
|
18
|
-
"dataset_absolute_path",
|
|
19
|
-
],
|
|
20
|
+
"coal": ["store"],
|
|
20
21
|
"s3": ["access_key_id", "endpoint_url", "secret_access_key"],
|
|
21
22
|
}
|
|
22
23
|
requirement_string = required_keys
|
|
23
24
|
|
|
24
|
-
def __init__(self, dct:
|
|
25
|
-
|
|
25
|
+
def __init__(self, dct: Dotdict = None):
|
|
26
|
+
super().__init__(dct)
|
|
26
27
|
self._s3 = S3(self.configuration)
|
|
27
28
|
|
|
28
|
-
def send(self,
|
|
29
|
+
def send(self, filter: Optional[list[str]] = None) -> bool:
|
|
29
30
|
|
|
30
|
-
_s = Store(
|
|
31
|
+
_s = Store(configuration=self.configuration)
|
|
31
32
|
|
|
32
33
|
if self._s3.output_type not in ("sqlite", "csv", "parquet"):
|
|
33
34
|
LOGGER.error(T("coal.common.errors.data_invalid_output_type").format(output_type=self._s3.output_type))
|
|
@@ -43,8 +44,8 @@ class AwsChannel(ChannelInterface):
|
|
|
43
44
|
self._s3.upload_file(_file_path, _uploaded_file_name)
|
|
44
45
|
else:
|
|
45
46
|
tables = list(_s.list_tables())
|
|
46
|
-
if
|
|
47
|
-
tables = [t for t in tables if t in
|
|
47
|
+
if filter:
|
|
48
|
+
tables = [t for t in tables if t in filter]
|
|
48
49
|
|
|
49
50
|
for table_name in tables:
|
|
50
51
|
_data_stream = BytesIO()
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
3
|
from cosmotech.coal.azure.blob import dump_store_to_azure
|
|
4
|
-
from cosmotech.coal.store.output.channel_interface import
|
|
5
|
-
|
|
4
|
+
from cosmotech.coal.store.output.channel_interface import (
|
|
5
|
+
ChannelInterface,
|
|
6
|
+
MissingChannelConfigError,
|
|
7
|
+
)
|
|
8
|
+
from cosmotech.coal.utils.configuration import Configuration, Dotdict
|
|
6
9
|
|
|
7
10
|
|
|
8
11
|
class AzureStorageChannel(ChannelInterface):
|
|
9
12
|
required_keys = {
|
|
10
|
-
"
|
|
11
|
-
"dataset_absolute_path",
|
|
12
|
-
],
|
|
13
|
+
"coal": ["store"],
|
|
13
14
|
"azure": [
|
|
14
15
|
"account_name",
|
|
15
16
|
"container_name",
|
|
@@ -22,20 +23,10 @@ class AzureStorageChannel(ChannelInterface):
|
|
|
22
23
|
}
|
|
23
24
|
requirement_string = required_keys
|
|
24
25
|
|
|
25
|
-
def
|
|
26
|
-
self.configuration = Configuration(dct)
|
|
27
|
-
|
|
28
|
-
def send(self, tables_filter: Optional[list[str]] = None) -> bool:
|
|
26
|
+
def send(self, filter: Optional[list[str]] = None) -> bool:
|
|
29
27
|
dump_store_to_azure(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
container_name=self.configuration.azure.container_name,
|
|
33
|
-
tenant_id=self.configuration.azure.tenant_id,
|
|
34
|
-
client_id=self.configuration.azure.client_id,
|
|
35
|
-
client_secret=self.configuration.azure.client_secret,
|
|
36
|
-
output_type=self.configuration.azure.output_type,
|
|
37
|
-
file_prefix=self.configuration.azure.file_prefix,
|
|
38
|
-
selected_tables=tables_filter,
|
|
28
|
+
self.configuration,
|
|
29
|
+
selected_tables=filter,
|
|
39
30
|
)
|
|
40
31
|
|
|
41
32
|
def delete(self):
|
|
@@ -2,11 +2,18 @@ from typing import Optional
|
|
|
2
2
|
|
|
3
3
|
from cosmotech.orchestrator.utils.translate import T
|
|
4
4
|
|
|
5
|
+
from cosmotech.coal.utils.configuration import Configuration, Dotdict
|
|
6
|
+
|
|
5
7
|
|
|
6
8
|
class ChannelInterface:
|
|
7
9
|
required_keys = {}
|
|
8
10
|
requirement_string: str = T("coal.store.output.data_interface.requirements")
|
|
9
11
|
|
|
12
|
+
def __init__(self, dct: Dotdict = None):
|
|
13
|
+
self.configuration = Configuration(dct)
|
|
14
|
+
if not self.is_available():
|
|
15
|
+
raise MissingChannelConfigError(self)
|
|
16
|
+
|
|
10
17
|
def send(self, filter: Optional[list[str]] = None) -> bool:
|
|
11
18
|
raise NotImplementedError()
|
|
12
19
|
|
|
@@ -21,3 +28,11 @@ class ChannelInterface:
|
|
|
21
28
|
)
|
|
22
29
|
except KeyError:
|
|
23
30
|
return False
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class MissingChannelConfigError(Exception):
|
|
34
|
+
def __init__(self, interface_class):
|
|
35
|
+
self.message = T("coal.store.output.split.requirements").format(
|
|
36
|
+
interface_name=interface_class.__class__.__name__, requirements=interface_class.requirement_string
|
|
37
|
+
)
|
|
38
|
+
super().__init__(self.message)
|
|
@@ -6,22 +6,24 @@ from cosmotech.coal.store.output.aws_channel import AwsChannel
|
|
|
6
6
|
from cosmotech.coal.store.output.az_storage_channel import AzureStorageChannel
|
|
7
7
|
from cosmotech.coal.store.output.channel_interface import ChannelInterface
|
|
8
8
|
from cosmotech.coal.store.output.postgres_channel import PostgresChannel
|
|
9
|
-
from cosmotech.coal.utils.configuration import
|
|
9
|
+
from cosmotech.coal.utils.configuration import Dotdict
|
|
10
10
|
from cosmotech.coal.utils.logger import LOGGER
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class ChannelSpliter(ChannelInterface):
|
|
14
14
|
requirement_string: str = "(Requires any working interface)"
|
|
15
|
-
targets =
|
|
15
|
+
targets = list()
|
|
16
16
|
available_interfaces: dict[str, ChannelInterface] = {
|
|
17
17
|
"s3": AwsChannel,
|
|
18
18
|
"az_storage": AzureStorageChannel,
|
|
19
19
|
"postgres": PostgresChannel,
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
def __init__(self,
|
|
23
|
-
|
|
24
|
-
self.targets =
|
|
22
|
+
def __init__(self, dct: Dotdict = None):
|
|
23
|
+
super().__init__(dct)
|
|
24
|
+
self.targets = list()
|
|
25
|
+
if "outputs" not in self.configuration:
|
|
26
|
+
raise AttributeError(T("coal.store.output.split.no_targets"))
|
|
25
27
|
for output in self.configuration.outputs:
|
|
26
28
|
channel = self.available_interfaces[output.type]
|
|
27
29
|
_i = channel(output.conf)
|
|
@@ -43,6 +45,8 @@ class ChannelSpliter(ChannelInterface):
|
|
|
43
45
|
any_ok = i.send(filter=filter) or any_ok
|
|
44
46
|
except Exception:
|
|
45
47
|
LOGGER.error(T("coal.store.output.split.send.error").format(interface_name=i.__class__.__name__))
|
|
48
|
+
if len(self.targets) < 2:
|
|
49
|
+
raise
|
|
46
50
|
return any_ok
|
|
47
51
|
|
|
48
52
|
def delete(self, filter: Optional[list[str]] = None) -> bool:
|
|
@@ -52,4 +56,6 @@ class ChannelSpliter(ChannelInterface):
|
|
|
52
56
|
any_ok = i.delete() or any_ok
|
|
53
57
|
except Exception:
|
|
54
58
|
LOGGER.error(T("coal.store.output.split.delete.error").format(interface_name=i.__class__.__name__))
|
|
59
|
+
if len(self.targets) < 2:
|
|
60
|
+
raise
|
|
55
61
|
return any_ok
|
|
@@ -6,15 +6,15 @@ from cosmotech.coal.postgresql.runner import (
|
|
|
6
6
|
)
|
|
7
7
|
from cosmotech.coal.postgresql.store import dump_store_to_postgresql_from_conf
|
|
8
8
|
from cosmotech.coal.store.output.channel_interface import ChannelInterface
|
|
9
|
-
from cosmotech.coal.utils.configuration import Configuration
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
class PostgresChannel(ChannelInterface):
|
|
13
12
|
required_keys = {
|
|
14
|
-
"
|
|
13
|
+
"coal": ["store"],
|
|
14
|
+
"cosmotech": ["organization_id", "workspace_id", "runner_id"],
|
|
15
15
|
"postgres": [
|
|
16
16
|
"host",
|
|
17
|
-
"
|
|
17
|
+
"port",
|
|
18
18
|
"db_name",
|
|
19
19
|
"db_schema",
|
|
20
20
|
"user_name",
|
|
@@ -23,16 +23,13 @@ class PostgresChannel(ChannelInterface):
|
|
|
23
23
|
}
|
|
24
24
|
requirement_string = required_keys
|
|
25
25
|
|
|
26
|
-
def
|
|
27
|
-
self.configuration = Configuration(dct)
|
|
28
|
-
|
|
29
|
-
def send(self, tables_filter: Optional[list[str]] = None) -> bool:
|
|
26
|
+
def send(self, filter: Optional[list[str]] = None) -> bool:
|
|
30
27
|
run_id = send_runner_metadata_to_postgresql(self.configuration)
|
|
31
28
|
dump_store_to_postgresql_from_conf(
|
|
32
|
-
self.configuration,
|
|
33
|
-
|
|
34
|
-
selected_tables=tables_filter,
|
|
29
|
+
configuration=self.configuration,
|
|
30
|
+
selected_tables=filter,
|
|
35
31
|
fk_id=run_id,
|
|
32
|
+
replace=False,
|
|
36
33
|
)
|
|
37
34
|
|
|
38
35
|
def delete(self):
|
cosmotech/coal/store/pandas.py
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
# etc., to any person is prohibited unless it has been previously and
|
|
6
6
|
# specifically authorized by written means by Cosmo Tech.
|
|
7
7
|
|
|
8
|
+
import pandas as pd
|
|
8
9
|
import pyarrow
|
|
9
10
|
|
|
10
11
|
from cosmotech.coal.store.store import Store
|
|
11
|
-
import pandas as pd
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def store_dataframe(
|
cosmotech/coal/store/pyarrow.py
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
# etc., to any person is prohibited unless it has been previously and
|
|
6
6
|
# specifically authorized by written means by Cosmo Tech.
|
|
7
7
|
|
|
8
|
-
from cosmotech.coal.store.store import Store
|
|
9
|
-
|
|
10
8
|
import pyarrow as pa
|
|
11
9
|
|
|
10
|
+
from cosmotech.coal.store.store import Store
|
|
11
|
+
|
|
12
12
|
|
|
13
13
|
def store_table(
|
|
14
14
|
table_name: str,
|
cosmotech/coal/store/store.py
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
# etc., to any person is prohibited unless it has been previously and
|
|
6
6
|
# specifically authorized by written means by Cosmo Tech.
|
|
7
7
|
|
|
8
|
-
import os
|
|
9
8
|
import pathlib
|
|
10
9
|
|
|
11
10
|
import pyarrow
|
|
12
11
|
from adbc_driver_sqlite import dbapi
|
|
12
|
+
from cosmotech.orchestrator.utils.translate import T
|
|
13
13
|
|
|
14
|
+
from cosmotech.coal.utils.configuration import Configuration
|
|
14
15
|
from cosmotech.coal.utils.logger import LOGGER
|
|
15
|
-
from cosmotech.orchestrator.utils.translate import T
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class Store:
|
|
@@ -20,11 +20,8 @@ class Store:
|
|
|
20
20
|
def sanitize_column(column_name: str) -> str:
|
|
21
21
|
return column_name.replace(" ", "_")
|
|
22
22
|
|
|
23
|
-
def __init__(
|
|
24
|
-
|
|
25
|
-
reset=False,
|
|
26
|
-
store_location: pathlib.Path = pathlib.Path(os.environ.get("CSM_PARAMETERS_ABSOLUTE_PATH", ".")),
|
|
27
|
-
):
|
|
23
|
+
def __init__(self, reset=False, configuration: Configuration = Configuration()):
|
|
24
|
+
store_location = configuration.safe_get("coal.store", ".")
|
|
28
25
|
self.store_location = pathlib.Path(store_location) / ".coal/store"
|
|
29
26
|
self.store_location.mkdir(parents=True, exist_ok=True)
|
|
30
27
|
self._tables = dict()
|
|
@@ -6,6 +6,10 @@ from cosmotech.orchestrator.utils.translate import T
|
|
|
6
6
|
from cosmotech.coal.utils.logger import LOGGER
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
class ReferenceKeyError(KeyError):
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
|
|
9
13
|
class Dotdict(dict):
|
|
10
14
|
"""dot.notation access to dictionary attributes"""
|
|
11
15
|
|
|
@@ -17,9 +21,13 @@ class Dotdict(dict):
|
|
|
17
21
|
_v = self.__getitem__(key)
|
|
18
22
|
if isinstance(_v, str) and _v.startswith("$"):
|
|
19
23
|
_r = self.root
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
try:
|
|
25
|
+
for _p in _v[1:].split("."):
|
|
26
|
+
_r = _r.__getattr__(_p)
|
|
27
|
+
return _r
|
|
28
|
+
except (KeyError, AttributeError):
|
|
29
|
+
LOGGER.warning(f"dotdict Ref {_v} doesn't exist")
|
|
30
|
+
raise ReferenceKeyError(_v)
|
|
23
31
|
return _v
|
|
24
32
|
|
|
25
33
|
__delattr__ = dict.__delitem__
|
|
@@ -35,48 +43,56 @@ class Dotdict(dict):
|
|
|
35
43
|
return data
|
|
36
44
|
|
|
37
45
|
for k, v in dct.items():
|
|
38
|
-
self
|
|
46
|
+
self.__setattr__(k, update(v))
|
|
39
47
|
|
|
40
48
|
def merge(self, d):
|
|
41
49
|
for k, v in d.items():
|
|
42
50
|
if isinstance(v, Dotdict) and k in self:
|
|
43
51
|
self[k].merge(v)
|
|
44
52
|
else:
|
|
45
|
-
|
|
53
|
+
# this trigger dict to dotdict conversion at merge
|
|
54
|
+
self.__setattr__(k, v)
|
|
46
55
|
|
|
47
56
|
|
|
48
57
|
class Configuration(Dotdict):
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
"post": "$postgres.post",
|
|
65
|
-
"db_name": "$postgres.db_name",
|
|
66
|
-
"db_schema": "$postgres.db_schema",
|
|
67
|
-
"user_name": "$postgres.user_name",
|
|
68
|
-
"user_password": "$postgres.user_password",
|
|
69
|
-
},
|
|
58
|
+
# Env var set by the cosmotech api at runtime
|
|
59
|
+
API_ENV_DICT = {
|
|
60
|
+
"secrets": {
|
|
61
|
+
"cosmotech": {
|
|
62
|
+
"twin_cache": {
|
|
63
|
+
"host": "TWIN_CACHE_HOST",
|
|
64
|
+
"port": "TWIN_CACHE_PORT",
|
|
65
|
+
"password": "TWIN_CACHE_PASSWORD",
|
|
66
|
+
"username": "TWIN_CACHE_USERNAME",
|
|
67
|
+
},
|
|
68
|
+
"idp": {
|
|
69
|
+
"base_url": "IDP_BASE_URL",
|
|
70
|
+
"tenant_id": "IDP_TENANT_ID",
|
|
71
|
+
"client_id": "IDP_CLIENT_ID",
|
|
72
|
+
"client_secret": "IDP_CLIENT_SECRET",
|
|
70
73
|
},
|
|
74
|
+
"api": {"url": "CSM_API_URL", "scope": "CSM_API_SCOPE"},
|
|
75
|
+
"dataset_absolute_path": "CSM_DATASET_ABSOLUTE_PATH",
|
|
76
|
+
"parameters_absolute_path": "CSM_PARAMETERS_ABSOLUTE_PATH",
|
|
77
|
+
"organization_id": "CSM_ORGANIZATION_ID",
|
|
78
|
+
"workspace_id": "CSM_WORKSPACE_ID",
|
|
79
|
+
"runner_id": "CSM_RUNNER_ID",
|
|
80
|
+
"run_id": "CSM_RUN_ID",
|
|
81
|
+
"run_template_id": "CSM_RUN_TEMPLATE_ID",
|
|
71
82
|
}
|
|
72
|
-
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
# HARD CODED ENVVAR CONVERSION
|
|
86
|
+
CONVERSION_DICT = {
|
|
73
87
|
"secrets": {
|
|
74
88
|
"log_level": "LOG_LEVEL",
|
|
75
89
|
"s3": {
|
|
76
90
|
"access_key_id": "AWS_ACCESS_KEY_ID",
|
|
77
91
|
"endpoint_url": "AWS_ENDPOINT_URL",
|
|
78
92
|
"secret_access_key": "AWS_SECRET_ACCESS_KEY",
|
|
93
|
+
"bucket_name": "CSM_DATA_BUCKET_NAME",
|
|
79
94
|
"bucket_prefix": "CSM_DATA_BUCKET_PREFIX",
|
|
95
|
+
"ca_bundle": "CSM_S3_CA_BUNDLE",
|
|
80
96
|
},
|
|
81
97
|
"azure": {
|
|
82
98
|
"account_name": "AZURE_ACCOUNT_NAME",
|
|
@@ -87,30 +103,16 @@ class Configuration(Dotdict):
|
|
|
87
103
|
"data_explorer_resource_ingest_uri": "AZURE_DATA_EXPLORER_RESOURCE_INGEST_URI",
|
|
88
104
|
"data_explorer_resource_uri": "AZURE_DATA_EXPLORER_RESOURCE_URI",
|
|
89
105
|
"storage_blob_name": "AZURE_STORAGE_BLOB_NAME",
|
|
106
|
+
"data_blob_prefix": "CSM_DATA_BLOB_PREFIX",
|
|
107
|
+
"data_prefix": "CSM_DATA_PREFIX",
|
|
90
108
|
"storage_sas_url": "AZURE_STORAGE_SAS_URL",
|
|
91
109
|
"tenant_id": "AZURE_TENANT_ID",
|
|
92
110
|
},
|
|
93
111
|
"cosmotech": {
|
|
94
|
-
"api_url": "CSM_API_URL",
|
|
95
|
-
"container_mode": "CSM_CONTAINER_MODE",
|
|
96
112
|
"data_adx_tag": "CSM_DATA_ADX_TAG",
|
|
97
113
|
"data_adx_wait_ingestion": "CSM_DATA_ADX_WAIT_INGESTION",
|
|
98
|
-
"data_blob_prefix": "CSM_DATA_BLOB_PREFIX",
|
|
99
|
-
"data_bucket_name": "CSM_DATA_BUCKET_NAME",
|
|
100
|
-
"data_prefix": "CSM_DATA_PREFIX",
|
|
101
|
-
"dataset_absolute_path": "CSM_DATASET_ABSOLUTE_PATH",
|
|
102
|
-
"organization_id": "CSM_ORGANIZATION_ID",
|
|
103
|
-
"parameters_absolute_path": "CSM_PARAMETERS_ABSOLUTE_PATH",
|
|
104
|
-
"run_id": "CSM_RUN_ID",
|
|
105
|
-
"runner_id": "CSM_RUNNER_ID",
|
|
106
|
-
"run_template_id": "CSM_RUN_TEMPLATE_ID",
|
|
107
|
-
"s3_ca_bundle": "CSM_S3_CA_BUNDLE",
|
|
108
|
-
"scenario_id": "CSM_SCENARIO_ID",
|
|
109
114
|
"send_datawarehouse_datasets": "CSM_SEND_DATAWAREHOUSE_DATASETS",
|
|
110
115
|
"send_datawarehouse_parameters": "CSM_SEND_DATAWAREHOUSE_PARAMETERS",
|
|
111
|
-
"workspace_id": "CSM_WORKSPACE_ID",
|
|
112
|
-
"fetch_dataset": "FETCH_DATASET",
|
|
113
|
-
"fetch_datasets_in_parallel": "FETCH_DATASETS_IN_PARALLEL",
|
|
114
116
|
},
|
|
115
117
|
"postgres": {
|
|
116
118
|
"db_name": "POSTGRES_DB_NAME",
|
|
@@ -132,38 +134,64 @@ class Configuration(Dotdict):
|
|
|
132
134
|
},
|
|
133
135
|
}
|
|
134
136
|
|
|
137
|
+
# HARD CODED configmap mount path set in K8s simulation pod by API run function
|
|
138
|
+
K8S_CONFIG = "/mnt/coal/coal-config.toml"
|
|
139
|
+
|
|
135
140
|
def __init__(self, dct: dict = None):
|
|
136
|
-
if dct:
|
|
141
|
+
if isinstance(dct, Dotdict):
|
|
142
|
+
super().__init__(dct, root=dct.root)
|
|
143
|
+
elif isinstance(dct, dict):
|
|
137
144
|
super().__init__(dct)
|
|
138
145
|
elif config_path := os.environ.get("CONFIG_FILE_PATH", default=None):
|
|
139
|
-
with open(config_path, "rb") as
|
|
140
|
-
super().__init__(tomllib.load(
|
|
146
|
+
with open(config_path, "rb") as config:
|
|
147
|
+
super().__init__(tomllib.load(config))
|
|
148
|
+
elif os.path.isfile(self.K8S_CONFIG):
|
|
149
|
+
with open(self.K8S_CONFIG, "rb") as config:
|
|
150
|
+
super().__init__(tomllib.load(config))
|
|
141
151
|
else:
|
|
142
152
|
LOGGER.info(T("coal.utils.configuration.no_config_file"))
|
|
143
153
|
super().__init__(self.CONVERSION_DICT)
|
|
144
154
|
|
|
155
|
+
# add envvar set by the API
|
|
156
|
+
self.merge(Dotdict(self.API_ENV_DICT))
|
|
157
|
+
|
|
145
158
|
if "secrets" in self:
|
|
146
159
|
self.secrets = self._env_swap_recusion(self.secrets)
|
|
147
160
|
# set secret section back to respective section
|
|
148
161
|
self.merge(self.secrets)
|
|
149
162
|
del self.secrets
|
|
150
163
|
|
|
164
|
+
# add coal.store default value if ont define
|
|
165
|
+
if self.safe_get("coal.store") is None:
|
|
166
|
+
self.merge({"coal": {"store": "$cosmotech.parameters_absolute_path"}})
|
|
167
|
+
|
|
151
168
|
# convert value to env
|
|
152
169
|
def _env_swap_recusion(self, dic):
|
|
153
170
|
for k, v in dic.items():
|
|
154
171
|
if isinstance(v, Dotdict):
|
|
155
172
|
dic[k] = self._env_swap_recusion(v)
|
|
156
|
-
# remove value not found
|
|
157
173
|
dic[k] = {k: v for k, v in dic[k].items() if v is not None}
|
|
158
174
|
elif isinstance(v, list):
|
|
159
175
|
dic[k] = list(self._env_swap_recusion(_v) for _v in v)
|
|
160
176
|
elif isinstance(v, str):
|
|
161
177
|
dic[k] = os.environ.get(v)
|
|
178
|
+
# remove value not found
|
|
179
|
+
dic = {k: v for k, v in dic.items() if v}
|
|
162
180
|
return dic
|
|
163
181
|
|
|
164
182
|
def merge_in(self, dic):
|
|
165
183
|
trans_dic = self._env_swap_recusion(dic)
|
|
166
|
-
self.
|
|
184
|
+
self.merge(trans_dic)
|
|
185
|
+
|
|
186
|
+
def safe_get(self, key, default=None):
|
|
187
|
+
try:
|
|
188
|
+
_r = self
|
|
189
|
+
for _k in key.split("."):
|
|
190
|
+
_r = _r.__getattr__(_k)
|
|
191
|
+
return _r
|
|
192
|
+
except (KeyError, AttributeError) as err:
|
|
193
|
+
LOGGER.debug(f"{err} not found; returning {default}")
|
|
194
|
+
return default
|
|
167
195
|
|
|
168
196
|
|
|
169
197
|
ENVIRONMENT_CONFIGURATION = Configuration()
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
from cosmotech.orchestrator.utils.translate import T
|
|
8
8
|
|
|
9
9
|
from cosmotech.csm_data.utils.click import click
|
|
10
|
-
from cosmotech.csm_data.utils.decorators import
|
|
10
|
+
from cosmotech.csm_data.utils.decorators import translate_help, web_help
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
@click.command()
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
# etc., to any person is prohibited unless it has been previously and
|
|
6
6
|
# specifically authorized by written means by Cosmo Tech.
|
|
7
7
|
|
|
8
|
-
from cosmotech.csm_data.utils.click import click
|
|
9
|
-
from cosmotech.csm_data.utils.decorators import web_help, translate_help
|
|
10
8
|
from cosmotech.orchestrator.utils.translate import T
|
|
11
9
|
|
|
10
|
+
from cosmotech.csm_data.utils.click import click
|
|
11
|
+
from cosmotech.csm_data.utils.decorators import translate_help, web_help
|
|
12
|
+
|
|
12
13
|
|
|
13
14
|
@click.command()
|
|
14
15
|
@web_help("csm-data/adx-send-runner-data")
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
from cosmotech.orchestrator.utils.translate import T
|
|
9
9
|
|
|
10
|
+
from cosmotech.coal.utils.configuration import Configuration
|
|
10
11
|
from cosmotech.csm_data.utils.click import click
|
|
11
12
|
from cosmotech.csm_data.utils.decorators import require_env, translate_help, web_help
|
|
12
13
|
|
|
@@ -66,15 +67,16 @@ def run_load_data(
|
|
|
66
67
|
# Import the function at the start of the command
|
|
67
68
|
from cosmotech.coal.cosmotech_api.apis.runner import RunnerApi
|
|
68
69
|
|
|
69
|
-
|
|
70
|
+
_configuration = Configuration()
|
|
71
|
+
_configuration.cosmotech.organization_id = organization_id
|
|
72
|
+
_configuration.cosmotech.workspace_id = workspace_id
|
|
73
|
+
_configuration.cosmotech.runner_id = runner_id
|
|
74
|
+
_configuration.cosmotech.parameters_absolute_path = parameters_absolute_path
|
|
75
|
+
_configuration.cosmotech.dataset_absolute_path = dataset_absolute_path
|
|
70
76
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
runner_id=runner_id,
|
|
75
|
-
parameter_folder=parameters_absolute_path,
|
|
76
|
-
dataset_folder=dataset_absolute_path,
|
|
77
|
-
)
|
|
77
|
+
_r = RunnerApi(_configuration)
|
|
78
|
+
|
|
79
|
+
return _r.download_runner_data(download_datasets=True)
|
|
78
80
|
|
|
79
81
|
|
|
80
82
|
if __name__ == "__main__":
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
# etc., to any person is prohibited unless it has been previously and
|
|
6
6
|
# specifically authorized by written means by Cosmo Tech.
|
|
7
7
|
|
|
8
|
-
from cosmotech.csm_data.utils.click import click
|
|
9
|
-
from cosmotech.csm_data.utils.decorators import web_help, translate_help
|
|
10
8
|
from cosmotech.orchestrator.utils.translate import T
|
|
11
9
|
|
|
10
|
+
from cosmotech.csm_data.utils.click import click
|
|
11
|
+
from cosmotech.csm_data.utils.decorators import translate_help, web_help
|
|
12
|
+
|
|
12
13
|
|
|
13
14
|
@click.command()
|
|
14
15
|
@click.option(
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
# etc., to any person is prohibited unless it has been previously and
|
|
6
6
|
# specifically authorized by written means by Cosmo Tech.
|
|
7
7
|
|
|
8
|
-
from cosmotech.csm_data.utils.click import click
|
|
9
|
-
from cosmotech.csm_data.utils.decorators import web_help, translate_help
|
|
10
8
|
from cosmotech.orchestrator.utils.translate import T
|
|
11
9
|
|
|
10
|
+
from cosmotech.csm_data.utils.click import click
|
|
11
|
+
from cosmotech.csm_data.utils.decorators import translate_help, web_help
|
|
12
|
+
|
|
12
13
|
VALID_TYPES = (
|
|
13
14
|
"sqlite",
|
|
14
15
|
"csv",
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
# etc., to any person is prohibited unless it has been previously and
|
|
6
6
|
# specifically authorized by written means by Cosmo Tech.
|
|
7
7
|
|
|
8
|
-
from cosmotech.csm_data.utils.click import click
|
|
9
|
-
from cosmotech.csm_data.utils.decorators import web_help, translate_help
|
|
10
8
|
from cosmotech.orchestrator.utils.translate import T
|
|
11
9
|
|
|
10
|
+
from cosmotech.csm_data.utils.click import click
|
|
11
|
+
from cosmotech.csm_data.utils.decorators import translate_help, web_help
|
|
12
|
+
|
|
12
13
|
|
|
13
14
|
@click.command()
|
|
14
15
|
@web_help("csm-data/store/dump-to-postgres")
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
# etc., to any person is prohibited unless it has been previously and
|
|
6
6
|
# specifically authorized by written means by Cosmo Tech.
|
|
7
7
|
|
|
8
|
-
from cosmotech.csm_data.utils.click import click
|
|
9
|
-
from cosmotech.csm_data.utils.decorators import web_help, translate_help
|
|
10
8
|
from cosmotech.orchestrator.utils.translate import T
|
|
11
9
|
|
|
10
|
+
from cosmotech.csm_data.utils.click import click
|
|
11
|
+
from cosmotech.csm_data.utils.decorators import translate_help, web_help
|
|
12
|
+
|
|
12
13
|
|
|
13
14
|
@click.command()
|
|
14
15
|
@web_help("csm-data/store/list-tables")
|