cosmotech-acceleration-library 1.0.1__py3-none-any.whl → 2.0.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.
- cosmotech/coal/__init__.py +1 -1
- cosmotech/coal/aws/__init__.py +1 -9
- cosmotech/coal/aws/s3.py +181 -214
- cosmotech/coal/azure/adx/auth.py +2 -2
- cosmotech/coal/azure/adx/runner.py +13 -14
- cosmotech/coal/azure/adx/store.py +5 -86
- cosmotech/coal/azure/adx/tables.py +2 -2
- cosmotech/coal/azure/blob.py +6 -6
- cosmotech/coal/azure/storage.py +3 -3
- cosmotech/coal/cosmotech_api/__init__.py +0 -24
- cosmotech/coal/cosmotech_api/apis/__init__.py +14 -0
- cosmotech/coal/cosmotech_api/apis/dataset.py +103 -0
- cosmotech/coal/cosmotech_api/apis/meta.py +25 -0
- cosmotech/coal/cosmotech_api/apis/organization.py +24 -0
- cosmotech/coal/cosmotech_api/apis/run.py +38 -0
- cosmotech/coal/cosmotech_api/apis/runner.py +71 -0
- cosmotech/coal/cosmotech_api/apis/solution.py +23 -0
- cosmotech/coal/cosmotech_api/apis/workspace.py +108 -0
- cosmotech/coal/cosmotech_api/objects/__init__.py +9 -0
- cosmotech/coal/cosmotech_api/objects/connection.py +125 -0
- cosmotech/coal/cosmotech_api/objects/parameters.py +127 -0
- cosmotech/coal/postgresql/runner.py +56 -36
- cosmotech/coal/postgresql/store.py +60 -14
- cosmotech/coal/postgresql/utils.py +254 -0
- cosmotech/coal/store/output/__init__.py +0 -0
- cosmotech/coal/store/output/aws_channel.py +73 -0
- cosmotech/coal/store/output/az_storage_channel.py +42 -0
- cosmotech/coal/store/output/channel_interface.py +23 -0
- cosmotech/coal/store/output/channel_spliter.py +55 -0
- cosmotech/coal/store/output/postgres_channel.py +40 -0
- cosmotech/coal/utils/configuration.py +169 -0
- cosmotech/coal/utils/decorator.py +22 -0
- cosmotech/csm_data/commands/api/api.py +6 -19
- cosmotech/csm_data/commands/api/postgres_send_runner_metadata.py +20 -16
- cosmotech/csm_data/commands/api/run_load_data.py +7 -46
- cosmotech/csm_data/commands/api/wsf_load_file.py +14 -15
- cosmotech/csm_data/commands/api/wsf_send_file.py +12 -13
- cosmotech/csm_data/commands/s3_bucket_delete.py +16 -15
- cosmotech/csm_data/commands/s3_bucket_download.py +16 -16
- cosmotech/csm_data/commands/s3_bucket_upload.py +16 -14
- cosmotech/csm_data/commands/store/dump_to_s3.py +18 -16
- cosmotech/csm_data/commands/store/output.py +35 -0
- cosmotech/csm_data/commands/store/store.py +3 -4
- cosmotech/translation/coal/en-US/coal/cosmotech_api/initialization.yml +8 -0
- cosmotech/translation/coal/en-US/coal/services/dataset.yml +4 -14
- cosmotech/translation/coal/en-US/coal/store/output/data_interface.yml +1 -0
- cosmotech/translation/coal/en-US/coal/store/output/split.yml +6 -0
- cosmotech/translation/coal/en-US/coal/utils/configuration.yml +2 -0
- cosmotech/translation/csm_data/en-US/csm_data/commands/store/output.yml +7 -0
- {cosmotech_acceleration_library-1.0.1.dist-info → cosmotech_acceleration_library-2.0.0.dist-info}/METADATA +8 -9
- {cosmotech_acceleration_library-1.0.1.dist-info → cosmotech_acceleration_library-2.0.0.dist-info}/RECORD +55 -71
- cosmotech/coal/azure/functions.py +0 -72
- cosmotech/coal/cosmotech_api/connection.py +0 -96
- cosmotech/coal/cosmotech_api/dataset/__init__.py +0 -26
- cosmotech/coal/cosmotech_api/dataset/converters.py +0 -164
- cosmotech/coal/cosmotech_api/dataset/download/__init__.py +0 -19
- cosmotech/coal/cosmotech_api/dataset/download/adt.py +0 -119
- cosmotech/coal/cosmotech_api/dataset/download/common.py +0 -140
- cosmotech/coal/cosmotech_api/dataset/download/file.py +0 -216
- cosmotech/coal/cosmotech_api/dataset/download/twingraph.py +0 -188
- cosmotech/coal/cosmotech_api/dataset/utils.py +0 -132
- cosmotech/coal/cosmotech_api/parameters.py +0 -48
- cosmotech/coal/cosmotech_api/run.py +0 -25
- cosmotech/coal/cosmotech_api/run_data.py +0 -173
- cosmotech/coal/cosmotech_api/run_template.py +0 -108
- cosmotech/coal/cosmotech_api/runner/__init__.py +0 -28
- cosmotech/coal/cosmotech_api/runner/data.py +0 -38
- cosmotech/coal/cosmotech_api/runner/datasets.py +0 -364
- cosmotech/coal/cosmotech_api/runner/download.py +0 -146
- cosmotech/coal/cosmotech_api/runner/metadata.py +0 -42
- cosmotech/coal/cosmotech_api/runner/parameters.py +0 -157
- cosmotech/coal/cosmotech_api/twin_data_layer.py +0 -512
- cosmotech/coal/cosmotech_api/workspace.py +0 -127
- cosmotech/coal/utils/api.py +0 -68
- cosmotech/coal/utils/postgresql.py +0 -236
- cosmotech/csm_data/commands/api/rds_load_csv.py +0 -90
- cosmotech/csm_data/commands/api/rds_send_csv.py +0 -74
- cosmotech/csm_data/commands/api/rds_send_store.py +0 -74
- cosmotech/csm_data/commands/api/runtemplate_load_handler.py +0 -66
- cosmotech/csm_data/commands/api/tdl_load_files.py +0 -76
- cosmotech/csm_data/commands/api/tdl_send_files.py +0 -82
- cosmotech/orchestrator_plugins/csm-data/templates/api/rds_load_csv.json +0 -27
- cosmotech/orchestrator_plugins/csm-data/templates/api/rds_send_csv.json +0 -27
- cosmotech/orchestrator_plugins/csm-data/templates/api/rds_send_store.json +0 -27
- cosmotech/orchestrator_plugins/csm-data/templates/api/runtemplate_load_handler.json +0 -27
- cosmotech/orchestrator_plugins/csm-data/templates/api/tdl_load_files.json +0 -32
- cosmotech/orchestrator_plugins/csm-data/templates/api/tdl_send_files.json +0 -27
- cosmotech/translation/coal/en-US/coal/cosmotech_api/run_data.yml +0 -2
- cosmotech/translation/csm_data/en-US/csm_data/commands/api/rds_load_csv.yml +0 -13
- cosmotech/translation/csm_data/en-US/csm_data/commands/api/rds_send_csv.yml +0 -12
- cosmotech/translation/csm_data/en-US/csm_data/commands/api/rds_send_store.yml +0 -12
- cosmotech/translation/csm_data/en-US/csm_data/commands/api/tdl_load_files.yml +0 -14
- cosmotech/translation/csm_data/en-US/csm_data/commands/api/tdl_send_files.yml +0 -18
- {cosmotech_acceleration_library-1.0.1.dist-info → cosmotech_acceleration_library-2.0.0.dist-info}/WHEEL +0 -0
- {cosmotech_acceleration_library-1.0.1.dist-info → cosmotech_acceleration_library-2.0.0.dist-info}/entry_points.txt +0 -0
- {cosmotech_acceleration_library-1.0.1.dist-info → cosmotech_acceleration_library-2.0.0.dist-info}/licenses/LICENSE +0 -0
- {cosmotech_acceleration_library-1.0.1.dist-info → cosmotech_acceleration_library-2.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from io import BytesIO
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
import pyarrow.csv as pc
|
|
5
|
+
import pyarrow.parquet as pq
|
|
6
|
+
from cosmotech.orchestrator.utils.translate import T
|
|
7
|
+
|
|
8
|
+
from cosmotech.coal.aws import S3
|
|
9
|
+
from cosmotech.coal.store.output.channel_interface import ChannelInterface
|
|
10
|
+
from cosmotech.coal.store.store import Store
|
|
11
|
+
from cosmotech.coal.utils.configuration import Configuration
|
|
12
|
+
from cosmotech.coal.utils.logger import LOGGER
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class AwsChannel(ChannelInterface):
|
|
16
|
+
required_keys = {
|
|
17
|
+
"cosmotech": [
|
|
18
|
+
"dataset_absolute_path",
|
|
19
|
+
],
|
|
20
|
+
"s3": ["access_key_id", "endpoint_url", "secret_access_key"],
|
|
21
|
+
}
|
|
22
|
+
requirement_string = required_keys
|
|
23
|
+
|
|
24
|
+
def __init__(self, dct: dict = None):
|
|
25
|
+
self.configuration = Configuration(dct)
|
|
26
|
+
self._s3 = S3(self.configuration)
|
|
27
|
+
|
|
28
|
+
def send(self, tables_filter: Optional[list[str]] = None) -> bool:
|
|
29
|
+
|
|
30
|
+
_s = Store(store_location=self.configuration.cosmotech.parameters_absolute_path)
|
|
31
|
+
|
|
32
|
+
if self._s3.output_type not in ("sqlite", "csv", "parquet"):
|
|
33
|
+
LOGGER.error(T("coal.common.errors.data_invalid_output_type").format(output_type=self._s3.output_type))
|
|
34
|
+
raise ValueError(T("coal.common.errors.data_invalid_output_type").format(output_type=self._s3.output_type))
|
|
35
|
+
|
|
36
|
+
if self._s3.output_type == "sqlite":
|
|
37
|
+
_file_path = _s._database_path
|
|
38
|
+
_file_name = "db.sqlite"
|
|
39
|
+
_uploaded_file_name = self.configuration.s3.bucket_prefix + _file_name
|
|
40
|
+
LOGGER.info(
|
|
41
|
+
T("coal.common.data_transfer.file_sent").format(file_path=_file_path, uploaded_name=_uploaded_file_name)
|
|
42
|
+
)
|
|
43
|
+
self._s3.upload_file(_file_path, _uploaded_file_name)
|
|
44
|
+
else:
|
|
45
|
+
tables = list(_s.list_tables())
|
|
46
|
+
if tables_filter:
|
|
47
|
+
tables = [t for t in tables if t in tables_filter]
|
|
48
|
+
|
|
49
|
+
for table_name in tables:
|
|
50
|
+
_data_stream = BytesIO()
|
|
51
|
+
_file_name = None
|
|
52
|
+
_data = _s.get_table(table_name)
|
|
53
|
+
if not len(_data):
|
|
54
|
+
LOGGER.info(T("coal.common.data_transfer.table_empty").format(table_name=table_name))
|
|
55
|
+
continue
|
|
56
|
+
if self._s3.output_type == "csv":
|
|
57
|
+
_file_name = table_name + ".csv"
|
|
58
|
+
pc.write_csv(_data, _data_stream)
|
|
59
|
+
elif self._s3.output_type == "parquet":
|
|
60
|
+
_file_name = table_name + ".parquet"
|
|
61
|
+
pq.write_table(_data, _data_stream)
|
|
62
|
+
LOGGER.info(
|
|
63
|
+
T("coal.common.data_transfer.sending_table").format(
|
|
64
|
+
table_name=table_name, output_type=self._s3.output_type
|
|
65
|
+
)
|
|
66
|
+
)
|
|
67
|
+
self._s3.upload_data_stream(
|
|
68
|
+
data_stream=_data_stream,
|
|
69
|
+
file_name=_file_name,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
def delete(self):
|
|
73
|
+
self._s3.delete_objects()
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from cosmotech.coal.azure.blob import dump_store_to_azure
|
|
4
|
+
from cosmotech.coal.store.output.channel_interface import ChannelInterface
|
|
5
|
+
from cosmotech.coal.utils.configuration import Configuration
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AzureStorageChannel(ChannelInterface):
|
|
9
|
+
required_keys = {
|
|
10
|
+
"cosmotech": [
|
|
11
|
+
"dataset_absolute_path",
|
|
12
|
+
],
|
|
13
|
+
"azure": [
|
|
14
|
+
"account_name",
|
|
15
|
+
"container_name",
|
|
16
|
+
"tenant_id",
|
|
17
|
+
"client_id",
|
|
18
|
+
"client_secret",
|
|
19
|
+
"output_type",
|
|
20
|
+
"file_prefix",
|
|
21
|
+
],
|
|
22
|
+
}
|
|
23
|
+
requirement_string = required_keys
|
|
24
|
+
|
|
25
|
+
def __init__(self, dct: dict = None):
|
|
26
|
+
self.configuration = Configuration(dct)
|
|
27
|
+
|
|
28
|
+
def send(self, tables_filter: Optional[list[str]] = None) -> bool:
|
|
29
|
+
dump_store_to_azure(
|
|
30
|
+
store_folder=self.configuration.cosmotech.dataset_absolute_path,
|
|
31
|
+
account_name=self.configuration.azure.account_name,
|
|
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,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
def delete(self):
|
|
42
|
+
pass
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from cosmotech.orchestrator.utils.translate import T
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ChannelInterface:
|
|
7
|
+
required_keys = {}
|
|
8
|
+
requirement_string: str = T("coal.store.output.data_interface.requirements")
|
|
9
|
+
|
|
10
|
+
def send(self, filter: Optional[list[str]] = None) -> bool:
|
|
11
|
+
raise NotImplementedError()
|
|
12
|
+
|
|
13
|
+
def delete(self) -> bool:
|
|
14
|
+
raise NotImplementedError()
|
|
15
|
+
|
|
16
|
+
def is_available(self) -> bool:
|
|
17
|
+
try:
|
|
18
|
+
return all(
|
|
19
|
+
all(key in self.configuration[section] for key in self.required_keys[section])
|
|
20
|
+
for section in self.required_keys.keys()
|
|
21
|
+
)
|
|
22
|
+
except KeyError:
|
|
23
|
+
return False
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from cosmotech.orchestrator.utils.translate import T
|
|
4
|
+
|
|
5
|
+
from cosmotech.coal.store.output.aws_channel import AwsChannel
|
|
6
|
+
from cosmotech.coal.store.output.az_storage_channel import AzureStorageChannel
|
|
7
|
+
from cosmotech.coal.store.output.channel_interface import ChannelInterface
|
|
8
|
+
from cosmotech.coal.store.output.postgres_channel import PostgresChannel
|
|
9
|
+
from cosmotech.coal.utils.configuration import Configuration
|
|
10
|
+
from cosmotech.coal.utils.logger import LOGGER
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ChannelSpliter(ChannelInterface):
|
|
14
|
+
requirement_string: str = "(Requires any working interface)"
|
|
15
|
+
targets = []
|
|
16
|
+
available_interfaces: dict[str, ChannelInterface] = {
|
|
17
|
+
"s3": AwsChannel,
|
|
18
|
+
"az_storage": AzureStorageChannel,
|
|
19
|
+
"postgres": PostgresChannel,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
def __init__(self, configuration: Configuration):
|
|
23
|
+
self.configuration = configuration
|
|
24
|
+
self.targets = []
|
|
25
|
+
for output in self.configuration.outputs:
|
|
26
|
+
channel = self.available_interfaces[output.type]
|
|
27
|
+
_i = channel(output.conf)
|
|
28
|
+
if _i.is_available():
|
|
29
|
+
self.targets.append(_i)
|
|
30
|
+
else:
|
|
31
|
+
LOGGER.warning(
|
|
32
|
+
T("coal.store.output.split.requirements").format(
|
|
33
|
+
interface_name=channel.__class__.__name__, requirements=channel.requirement_string
|
|
34
|
+
)
|
|
35
|
+
)
|
|
36
|
+
if not self.targets:
|
|
37
|
+
raise AttributeError(T("coal.store.output.split.no_targets"))
|
|
38
|
+
|
|
39
|
+
def send(self, filter: Optional[list[str]] = None) -> bool:
|
|
40
|
+
any_ok = False
|
|
41
|
+
for i in self.targets:
|
|
42
|
+
try:
|
|
43
|
+
any_ok = i.send(filter=filter) or any_ok
|
|
44
|
+
except Exception:
|
|
45
|
+
LOGGER.error(T("coal.store.output.split.send.error").format(interface_name=i.__class__.__name__))
|
|
46
|
+
return any_ok
|
|
47
|
+
|
|
48
|
+
def delete(self, filter: Optional[list[str]] = None) -> bool:
|
|
49
|
+
any_ok = False
|
|
50
|
+
for i in self.targets:
|
|
51
|
+
try:
|
|
52
|
+
any_ok = i.delete() or any_ok
|
|
53
|
+
except Exception:
|
|
54
|
+
LOGGER.error(T("coal.store.output.split.delete.error").format(interface_name=i.__class__.__name__))
|
|
55
|
+
return any_ok
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from cosmotech.coal.postgresql.runner import (
|
|
4
|
+
remove_runner_metadata_from_postgresql,
|
|
5
|
+
send_runner_metadata_to_postgresql,
|
|
6
|
+
)
|
|
7
|
+
from cosmotech.coal.postgresql.store import dump_store_to_postgresql_from_conf
|
|
8
|
+
from cosmotech.coal.store.output.channel_interface import ChannelInterface
|
|
9
|
+
from cosmotech.coal.utils.configuration import Configuration
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PostgresChannel(ChannelInterface):
|
|
13
|
+
required_keys = {
|
|
14
|
+
"cosmotech": ["dataset_absolute_path", "organization_id", "workspace_id", "runner_id"],
|
|
15
|
+
"postgres": [
|
|
16
|
+
"host",
|
|
17
|
+
"post",
|
|
18
|
+
"db_name",
|
|
19
|
+
"db_schema",
|
|
20
|
+
"user_name",
|
|
21
|
+
"user_password",
|
|
22
|
+
],
|
|
23
|
+
}
|
|
24
|
+
requirement_string = required_keys
|
|
25
|
+
|
|
26
|
+
def __init__(self, dct: dict = None):
|
|
27
|
+
self.configuration = Configuration(dct)
|
|
28
|
+
|
|
29
|
+
def send(self, tables_filter: Optional[list[str]] = None) -> bool:
|
|
30
|
+
run_id = send_runner_metadata_to_postgresql(self.configuration)
|
|
31
|
+
dump_store_to_postgresql_from_conf(
|
|
32
|
+
self.configuration,
|
|
33
|
+
store_folder=self.configuration.cosmotech.dataset_absolute_path,
|
|
34
|
+
selected_tables=tables_filter,
|
|
35
|
+
fk_id=run_id,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
def delete(self):
|
|
39
|
+
# removing metadata will trigger cascade delete on real data
|
|
40
|
+
remove_runner_metadata_from_postgresql(self.configuration)
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import tomllib
|
|
3
|
+
|
|
4
|
+
from cosmotech.orchestrator.utils.translate import T
|
|
5
|
+
|
|
6
|
+
from cosmotech.coal.utils.logger import LOGGER
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Dotdict(dict):
|
|
10
|
+
"""dot.notation access to dictionary attributes"""
|
|
11
|
+
|
|
12
|
+
def __setattr__(self, key, val):
|
|
13
|
+
dd = Dotdict(val, root=self.root) if isinstance(val, dict) else val
|
|
14
|
+
self.__setitem__(key, dd)
|
|
15
|
+
|
|
16
|
+
def __getattr__(self, key):
|
|
17
|
+
_v = self.__getitem__(key)
|
|
18
|
+
if isinstance(_v, str) and _v.startswith("$"):
|
|
19
|
+
_r = self.root
|
|
20
|
+
for _p in _v[1:].split("."):
|
|
21
|
+
_r = _r[_p]
|
|
22
|
+
return _r
|
|
23
|
+
return _v
|
|
24
|
+
|
|
25
|
+
__delattr__ = dict.__delitem__
|
|
26
|
+
|
|
27
|
+
def __init__(self, dct=dict(), root=None):
|
|
28
|
+
object.__setattr__(self, "root", self if root is None else root)
|
|
29
|
+
|
|
30
|
+
def update(data):
|
|
31
|
+
if isinstance(data, dict):
|
|
32
|
+
return Dotdict(data, root=self.root)
|
|
33
|
+
elif isinstance(data, list):
|
|
34
|
+
return [update(d) for d in data]
|
|
35
|
+
return data
|
|
36
|
+
|
|
37
|
+
for k, v in dct.items():
|
|
38
|
+
self[k] = update(v)
|
|
39
|
+
|
|
40
|
+
def merge(self, d):
|
|
41
|
+
for k, v in d.items():
|
|
42
|
+
if isinstance(v, Dotdict) and k in self:
|
|
43
|
+
self[k].merge(v)
|
|
44
|
+
else:
|
|
45
|
+
self[k] = v
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class Configuration(Dotdict):
|
|
49
|
+
|
|
50
|
+
# HARD CODED ENVVAR CONVERSION
|
|
51
|
+
CONVERSION_DICT = {
|
|
52
|
+
"outputs": [
|
|
53
|
+
{
|
|
54
|
+
"type": "postgres",
|
|
55
|
+
"conf": {
|
|
56
|
+
"cosmotech": {
|
|
57
|
+
"dataset_absolute_path": "$cosmotech.dataset_absolute_path",
|
|
58
|
+
"organization_id": "$cosmotech.organization_id",
|
|
59
|
+
"workspace_id": "$cosmotech.workspace_id",
|
|
60
|
+
"runner_id": "$cosmotech.runner_id",
|
|
61
|
+
},
|
|
62
|
+
"postgres": {
|
|
63
|
+
"host": "$postgres.host",
|
|
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
|
+
},
|
|
70
|
+
},
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
"secrets": {
|
|
74
|
+
"log_level": "LOG_LEVEL",
|
|
75
|
+
"s3": {
|
|
76
|
+
"access_key_id": "AWS_ACCESS_KEY_ID",
|
|
77
|
+
"endpoint_url": "AWS_ENDPOINT_URL",
|
|
78
|
+
"secret_access_key": "AWS_SECRET_ACCESS_KEY",
|
|
79
|
+
"bucket_prefix": "CSM_DATA_BUCKET_PREFIX",
|
|
80
|
+
},
|
|
81
|
+
"azure": {
|
|
82
|
+
"account_name": "AZURE_ACCOUNT_NAME",
|
|
83
|
+
"client_id": "AZURE_CLIENT_ID",
|
|
84
|
+
"client_secret": "AZURE_CLIENT_SECRET",
|
|
85
|
+
"container_name": "AZURE_CONTAINER_NAME",
|
|
86
|
+
"data_explorer_database_name": "AZURE_DATA_EXPLORER_DATABASE_NAME",
|
|
87
|
+
"data_explorer_resource_ingest_uri": "AZURE_DATA_EXPLORER_RESOURCE_INGEST_URI",
|
|
88
|
+
"data_explorer_resource_uri": "AZURE_DATA_EXPLORER_RESOURCE_URI",
|
|
89
|
+
"storage_blob_name": "AZURE_STORAGE_BLOB_NAME",
|
|
90
|
+
"storage_sas_url": "AZURE_STORAGE_SAS_URL",
|
|
91
|
+
"tenant_id": "AZURE_TENANT_ID",
|
|
92
|
+
},
|
|
93
|
+
"cosmotech": {
|
|
94
|
+
"api_url": "CSM_API_URL",
|
|
95
|
+
"container_mode": "CSM_CONTAINER_MODE",
|
|
96
|
+
"data_adx_tag": "CSM_DATA_ADX_TAG",
|
|
97
|
+
"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
|
+
"send_datawarehouse_datasets": "CSM_SEND_DATAWAREHOUSE_DATASETS",
|
|
110
|
+
"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
|
+
},
|
|
115
|
+
"postgres": {
|
|
116
|
+
"db_name": "POSTGRES_DB_NAME",
|
|
117
|
+
"db_schema": "POSTGRES_DB_SCHEMA",
|
|
118
|
+
"port": "POSTGRES_HOST_PORT",
|
|
119
|
+
"host": "POSTGRES_HOST_URI",
|
|
120
|
+
"user_name": "POSTGRES_USER_NAME",
|
|
121
|
+
"user_password": "POSTGRES_USER_PASSWORD",
|
|
122
|
+
"password_encoding": "CSM_PSQL_FORCE_PASSWORD_ENCODING",
|
|
123
|
+
},
|
|
124
|
+
"single_store": {
|
|
125
|
+
"db": "SINGLE_STORE_DB",
|
|
126
|
+
"host": "SINGLE_STORE_HOST",
|
|
127
|
+
"password": "SINGLE_STORE_PASSWORD",
|
|
128
|
+
"port": "SINGLE_STORE_PORT",
|
|
129
|
+
"tables": "SINGLE_STORE_TABLES",
|
|
130
|
+
"username": "SINGLE_STORE_USERNAME",
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
def __init__(self, dct: dict = None):
|
|
136
|
+
if dct:
|
|
137
|
+
super().__init__(dct)
|
|
138
|
+
elif config_path := os.environ.get("CONFIG_FILE_PATH", default=None):
|
|
139
|
+
with open(config_path, "rb") as f:
|
|
140
|
+
super().__init__(tomllib.load(f))
|
|
141
|
+
else:
|
|
142
|
+
LOGGER.info(T("coal.utils.configuration.no_config_file"))
|
|
143
|
+
super().__init__(self.CONVERSION_DICT)
|
|
144
|
+
|
|
145
|
+
if "secrets" in self:
|
|
146
|
+
self.secrets = self._env_swap_recusion(self.secrets)
|
|
147
|
+
# set secret section back to respective section
|
|
148
|
+
self.merge(self.secrets)
|
|
149
|
+
del self.secrets
|
|
150
|
+
|
|
151
|
+
# convert value to env
|
|
152
|
+
def _env_swap_recusion(self, dic):
|
|
153
|
+
for k, v in dic.items():
|
|
154
|
+
if isinstance(v, Dotdict):
|
|
155
|
+
dic[k] = self._env_swap_recusion(v)
|
|
156
|
+
# remove value not found
|
|
157
|
+
dic[k] = {k: v for k, v in dic[k].items() if v is not None}
|
|
158
|
+
elif isinstance(v, list):
|
|
159
|
+
dic[k] = list(self._env_swap_recusion(_v) for _v in v)
|
|
160
|
+
elif isinstance(v, str):
|
|
161
|
+
dic[k] = os.environ.get(v)
|
|
162
|
+
return dic
|
|
163
|
+
|
|
164
|
+
def merge_in(self, dic):
|
|
165
|
+
trans_dic = self._env_swap_recusion(dic)
|
|
166
|
+
self._merge(trans_dic)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
ENVIRONMENT_CONFIGURATION = Configuration()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from functools import wraps
|
|
3
|
+
|
|
4
|
+
from cosmotech.orchestrator.utils.translate import T
|
|
5
|
+
|
|
6
|
+
from cosmotech.coal.utils.logger import LOGGER
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def timed(operation, debug=False):
|
|
10
|
+
def decorator(func):
|
|
11
|
+
@wraps(func)
|
|
12
|
+
def wrapper(*args, **kwargs):
|
|
13
|
+
process_start = time.time()
|
|
14
|
+
r = func(*args, **kwargs)
|
|
15
|
+
process_time = time.time() - process_start
|
|
16
|
+
log_function = LOGGER.debug if debug else LOGGER.info
|
|
17
|
+
log_function(T("coal.common.timing.operation_completed").format(operation=operation, time=process_time))
|
|
18
|
+
return r
|
|
19
|
+
|
|
20
|
+
return wrapper
|
|
21
|
+
|
|
22
|
+
return decorator
|
|
@@ -4,25 +4,18 @@
|
|
|
4
4
|
# Any use, reproduction, translation, broadcasting, transmission, distribution,
|
|
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
|
+
from cosmotech.orchestrator.utils.translate import T
|
|
8
|
+
|
|
9
|
+
from cosmotech.coal.cosmotech_api.objects.connection import Connection
|
|
10
|
+
from cosmotech.coal.utils.logger import LOGGER
|
|
7
11
|
from cosmotech.csm_data.commands.api.postgres_send_runner_metadata import (
|
|
8
12
|
postgres_send_runner_metadata,
|
|
9
13
|
)
|
|
10
|
-
from cosmotech.csm_data.commands.api.rds_load_csv import rds_load_csv
|
|
11
|
-
from cosmotech.csm_data.commands.api.rds_send_csv import rds_send_csv
|
|
12
|
-
from cosmotech.csm_data.commands.api.rds_send_store import rds_send_store
|
|
13
14
|
from cosmotech.csm_data.commands.api.run_load_data import run_load_data
|
|
14
|
-
from cosmotech.csm_data.commands.api.runtemplate_load_handler import (
|
|
15
|
-
runtemplate_load_handler,
|
|
16
|
-
)
|
|
17
|
-
from cosmotech.csm_data.commands.api.tdl_load_files import tdl_load_files
|
|
18
|
-
from cosmotech.csm_data.commands.api.tdl_send_files import tdl_send_files
|
|
19
15
|
from cosmotech.csm_data.commands.api.wsf_load_file import wsf_load_file
|
|
20
16
|
from cosmotech.csm_data.commands.api.wsf_send_file import wsf_send_file
|
|
21
17
|
from cosmotech.csm_data.utils.click import click
|
|
22
18
|
from cosmotech.csm_data.utils.decorators import translate_help, web_help
|
|
23
|
-
from cosmotech.coal.cosmotech_api.connection import get_api_client
|
|
24
|
-
from cosmotech.coal.utils.logger import LOGGER
|
|
25
|
-
from cosmotech.orchestrator.utils.translate import T
|
|
26
19
|
|
|
27
20
|
|
|
28
21
|
@click.group(invoke_without_command=True)
|
|
@@ -32,19 +25,13 @@ from cosmotech.orchestrator.utils.translate import T
|
|
|
32
25
|
def api(ctx: click.Context):
|
|
33
26
|
if ctx.invoked_subcommand is None:
|
|
34
27
|
try:
|
|
35
|
-
|
|
36
|
-
LOGGER.info(T("coal.cosmotech_api.connection.found_valid").format(type=
|
|
28
|
+
connection = Connection()
|
|
29
|
+
LOGGER.info(T("coal.cosmotech_api.connection.found_valid").format(type=connection.api_type))
|
|
37
30
|
except EnvironmentError:
|
|
38
31
|
raise click.Abort()
|
|
39
32
|
|
|
40
33
|
|
|
41
|
-
api.add_command(rds_send_csv, "rds-send-csv")
|
|
42
|
-
api.add_command(rds_send_store, "rds-send-store")
|
|
43
|
-
api.add_command(rds_load_csv, "rds-load-csv")
|
|
44
34
|
api.add_command(wsf_send_file, "wsf-send-file")
|
|
45
35
|
api.add_command(wsf_load_file, "wsf-load-file")
|
|
46
|
-
api.add_command(tdl_send_files, "tdl-send-files")
|
|
47
|
-
api.add_command(tdl_load_files, "tdl-load-files")
|
|
48
|
-
api.add_command(runtemplate_load_handler, "runtemplate-load-handler")
|
|
49
36
|
api.add_command(run_load_data, "run-load-data")
|
|
50
37
|
api.add_command(postgres_send_runner_metadata, "postgres-send-runner-metadata")
|
|
@@ -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/api/postgres-send-runner-metadata")
|
|
@@ -93,7 +94,7 @@ from cosmotech.orchestrator.utils.translate import T
|
|
|
93
94
|
@click.option(
|
|
94
95
|
"--encode-password/--no-encode-password",
|
|
95
96
|
"force_encode",
|
|
96
|
-
help=T("csm_data.commands.
|
|
97
|
+
help=T("csm_data.commands.api.postgres_send_runner_metadata.parameters.encode_password"),
|
|
97
98
|
envvar="CSM_PSQL_FORCE_PASSWORD_ENCODING",
|
|
98
99
|
show_envvar=True,
|
|
99
100
|
default=True,
|
|
@@ -115,17 +116,20 @@ def postgres_send_runner_metadata(
|
|
|
115
116
|
):
|
|
116
117
|
# Import the function at the start of the command
|
|
117
118
|
from cosmotech.coal.postgresql import send_runner_metadata_to_postgresql
|
|
119
|
+
from cosmotech.coal.utils.configuration import Configuration
|
|
120
|
+
|
|
121
|
+
_c = Configuration()
|
|
122
|
+
_c.postgres.host = postgres_host
|
|
123
|
+
_c.postgres.port = postgres_port
|
|
124
|
+
_c.postgres.db_name = postgres_db
|
|
125
|
+
_c.postgres.db_schema = postgres_schema
|
|
126
|
+
_c.postgres.user_name = postgres_user
|
|
127
|
+
_c.postgres.user_password = postgres_password
|
|
128
|
+
_c.postgres.password_encoding = force_encode
|
|
129
|
+
_c.postgres.table_prefix = table_prefix
|
|
130
|
+
|
|
131
|
+
_c.cosmotech.organization_id = organization_id
|
|
132
|
+
_c.cosmotech.workspace_id = workspace_id
|
|
133
|
+
_c.cosmotech.runner_id = runner_id
|
|
118
134
|
|
|
119
|
-
send_runner_metadata_to_postgresql(
|
|
120
|
-
organization_id=organization_id,
|
|
121
|
-
workspace_id=workspace_id,
|
|
122
|
-
runner_id=runner_id,
|
|
123
|
-
table_prefix=table_prefix,
|
|
124
|
-
postgres_host=postgres_host,
|
|
125
|
-
postgres_port=postgres_port,
|
|
126
|
-
postgres_db=postgres_db,
|
|
127
|
-
postgres_schema=postgres_schema,
|
|
128
|
-
postgres_user=postgres_user,
|
|
129
|
-
postgres_password=postgres_password,
|
|
130
|
-
force_encode=force_encode,
|
|
131
|
-
)
|
|
135
|
+
send_runner_metadata_to_postgresql(_c)
|
|
@@ -5,11 +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 require_env
|
|
10
|
-
from cosmotech.csm_data.utils.decorators import web_help, translate_help
|
|
11
8
|
from cosmotech.orchestrator.utils.translate import T
|
|
12
9
|
|
|
10
|
+
from cosmotech.csm_data.utils.click import click
|
|
11
|
+
from cosmotech.csm_data.utils.decorators import require_env, translate_help, web_help
|
|
12
|
+
|
|
13
13
|
|
|
14
14
|
@click.command()
|
|
15
15
|
@click.option(
|
|
@@ -52,38 +52,6 @@ from cosmotech.orchestrator.utils.translate import T
|
|
|
52
52
|
help=T("csm_data.commands.api.run_load_data.parameters.parameters_absolute_path"),
|
|
53
53
|
required=True,
|
|
54
54
|
)
|
|
55
|
-
@click.option(
|
|
56
|
-
"--write-json/--no-write-json",
|
|
57
|
-
envvar="WRITE_JSON",
|
|
58
|
-
show_envvar=True,
|
|
59
|
-
default=True,
|
|
60
|
-
show_default=True,
|
|
61
|
-
help=T("csm_data.commands.api.run_load_data.parameters.write_json"),
|
|
62
|
-
)
|
|
63
|
-
@click.option(
|
|
64
|
-
"--write-csv/--no-write-csv",
|
|
65
|
-
envvar="WRITE_CSV",
|
|
66
|
-
show_envvar=True,
|
|
67
|
-
default=False,
|
|
68
|
-
show_default=True,
|
|
69
|
-
help=T("csm_data.commands.api.run_load_data.parameters.write_csv"),
|
|
70
|
-
)
|
|
71
|
-
@click.option(
|
|
72
|
-
"--fetch-dataset/--no-fetch-dataset",
|
|
73
|
-
envvar="FETCH_DATASET",
|
|
74
|
-
show_envvar=True,
|
|
75
|
-
default=True,
|
|
76
|
-
show_default=True,
|
|
77
|
-
help=T("csm_data.commands.api.run_load_data.parameters.fetch_dataset"),
|
|
78
|
-
)
|
|
79
|
-
@click.option(
|
|
80
|
-
"--parallel/--no-parallel",
|
|
81
|
-
envvar="FETCH_DATASETS_IN_PARALLEL",
|
|
82
|
-
show_envvar=True,
|
|
83
|
-
default=True,
|
|
84
|
-
show_default=True,
|
|
85
|
-
help=T("csm_data.commands.api.run_load_data.parameters.parallel"),
|
|
86
|
-
)
|
|
87
55
|
@require_env("CSM_API_SCOPE", "The identification scope of a Cosmotech API")
|
|
88
56
|
@require_env("CSM_API_URL", "The URL to a Cosmotech API")
|
|
89
57
|
@web_help("csm-data/api/run-load-data")
|
|
@@ -94,25 +62,18 @@ def run_load_data(
|
|
|
94
62
|
organization_id: str,
|
|
95
63
|
dataset_absolute_path: str,
|
|
96
64
|
parameters_absolute_path: str,
|
|
97
|
-
write_json: bool,
|
|
98
|
-
write_csv: bool,
|
|
99
|
-
fetch_dataset: bool,
|
|
100
|
-
parallel: bool,
|
|
101
65
|
):
|
|
102
66
|
# Import the function at the start of the command
|
|
103
|
-
from cosmotech.coal.cosmotech_api.runner
|
|
67
|
+
from cosmotech.coal.cosmotech_api.apis.runner import RunnerApi
|
|
68
|
+
|
|
69
|
+
_r = RunnerApi()
|
|
104
70
|
|
|
105
|
-
return download_runner_data(
|
|
71
|
+
return _r.download_runner_data(
|
|
106
72
|
organization_id=organization_id,
|
|
107
73
|
workspace_id=workspace_id,
|
|
108
74
|
runner_id=runner_id,
|
|
109
75
|
parameter_folder=parameters_absolute_path,
|
|
110
76
|
dataset_folder=dataset_absolute_path,
|
|
111
|
-
read_files=False,
|
|
112
|
-
parallel=parallel,
|
|
113
|
-
write_json=write_json,
|
|
114
|
-
write_csv=write_csv,
|
|
115
|
-
fetch_dataset=fetch_dataset,
|
|
116
77
|
)
|
|
117
78
|
|
|
118
79
|
|
|
@@ -6,13 +6,11 @@
|
|
|
6
6
|
# specifically authorized by written means by Cosmo Tech.
|
|
7
7
|
import pathlib
|
|
8
8
|
|
|
9
|
-
from cosmotech.csm_data.utils.click import click
|
|
10
|
-
from cosmotech.csm_data.utils.decorators import web_help, translate_help
|
|
11
|
-
from cosmotech.coal.cosmotech_api.connection import get_api_client
|
|
12
|
-
from cosmotech.coal.cosmotech_api.workspace import download_workspace_file
|
|
13
|
-
from cosmotech.coal.cosmotech_api.workspace import list_workspace_files
|
|
14
9
|
from cosmotech.orchestrator.utils.translate import T
|
|
15
10
|
|
|
11
|
+
from cosmotech.csm_data.utils.click import click
|
|
12
|
+
from cosmotech.csm_data.utils.decorators import translate_help, web_help
|
|
13
|
+
|
|
16
14
|
|
|
17
15
|
@click.command()
|
|
18
16
|
@click.option(
|
|
@@ -53,14 +51,15 @@ from cosmotech.orchestrator.utils.translate import T
|
|
|
53
51
|
@web_help("csm-data/api/wsf-load-file")
|
|
54
52
|
@translate_help("csm_data.commands.api.wsf_load_file.description")
|
|
55
53
|
def wsf_load_file(organization_id, workspace_id, workspace_path: str, target_folder: str):
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
from cosmotech.coal.cosmotech_api.apis.workspace import WorkspaceApi
|
|
55
|
+
|
|
56
|
+
ws_api = WorkspaceApi()
|
|
57
|
+
target_list = ws_api.list_filtered_workspace_files(organization_id, workspace_id, workspace_path)
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
)
|
|
59
|
+
for target in target_list:
|
|
60
|
+
ws_api.download_workspace_file(
|
|
61
|
+
organization_id,
|
|
62
|
+
workspace_id,
|
|
63
|
+
target,
|
|
64
|
+
pathlib.Path(target_folder),
|
|
65
|
+
)
|