cosmotech-acceleration-library 1.1.0__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.
Files changed (98) hide show
  1. cosmotech/coal/__init__.py +1 -1
  2. cosmotech/coal/aws/__init__.py +1 -9
  3. cosmotech/coal/aws/s3.py +181 -214
  4. cosmotech/coal/azure/adx/auth.py +2 -2
  5. cosmotech/coal/azure/adx/runner.py +13 -14
  6. cosmotech/coal/azure/adx/store.py +5 -86
  7. cosmotech/coal/azure/adx/tables.py +2 -2
  8. cosmotech/coal/azure/blob.py +6 -6
  9. cosmotech/coal/azure/storage.py +3 -3
  10. cosmotech/coal/cosmotech_api/__init__.py +0 -28
  11. cosmotech/coal/cosmotech_api/apis/__init__.py +14 -0
  12. cosmotech/coal/cosmotech_api/apis/dataset.py +103 -0
  13. cosmotech/coal/cosmotech_api/apis/meta.py +25 -0
  14. cosmotech/coal/cosmotech_api/apis/organization.py +24 -0
  15. cosmotech/coal/cosmotech_api/apis/run.py +38 -0
  16. cosmotech/coal/cosmotech_api/apis/runner.py +71 -0
  17. cosmotech/coal/cosmotech_api/apis/solution.py +23 -0
  18. cosmotech/coal/cosmotech_api/apis/workspace.py +108 -0
  19. cosmotech/coal/cosmotech_api/objects/__init__.py +9 -0
  20. cosmotech/coal/cosmotech_api/objects/connection.py +125 -0
  21. cosmotech/coal/cosmotech_api/objects/parameters.py +127 -0
  22. cosmotech/coal/postgresql/runner.py +56 -36
  23. cosmotech/coal/postgresql/store.py +60 -14
  24. cosmotech/coal/postgresql/utils.py +254 -0
  25. cosmotech/coal/store/output/__init__.py +0 -0
  26. cosmotech/coal/store/output/aws_channel.py +73 -0
  27. cosmotech/coal/store/output/az_storage_channel.py +42 -0
  28. cosmotech/coal/store/output/channel_interface.py +23 -0
  29. cosmotech/coal/store/output/channel_spliter.py +55 -0
  30. cosmotech/coal/store/output/postgres_channel.py +40 -0
  31. cosmotech/coal/utils/configuration.py +169 -0
  32. cosmotech/coal/utils/decorator.py +4 -7
  33. cosmotech/csm_data/commands/api/api.py +6 -19
  34. cosmotech/csm_data/commands/api/postgres_send_runner_metadata.py +20 -16
  35. cosmotech/csm_data/commands/api/run_load_data.py +7 -46
  36. cosmotech/csm_data/commands/api/wsf_load_file.py +13 -16
  37. cosmotech/csm_data/commands/api/wsf_send_file.py +11 -14
  38. cosmotech/csm_data/commands/s3_bucket_delete.py +16 -15
  39. cosmotech/csm_data/commands/s3_bucket_download.py +16 -16
  40. cosmotech/csm_data/commands/s3_bucket_upload.py +16 -14
  41. cosmotech/csm_data/commands/store/dump_to_s3.py +18 -16
  42. cosmotech/csm_data/commands/store/output.py +35 -0
  43. cosmotech/csm_data/commands/store/store.py +3 -3
  44. cosmotech/translation/coal/en-US/coal/cosmotech_api/initialization.yml +8 -0
  45. cosmotech/translation/coal/en-US/coal/services/dataset.yml +4 -14
  46. cosmotech/translation/coal/en-US/coal/store/output/data_interface.yml +1 -0
  47. cosmotech/translation/coal/en-US/coal/store/output/split.yml +6 -0
  48. cosmotech/translation/coal/en-US/coal/utils/configuration.yml +2 -0
  49. cosmotech/translation/csm_data/en-US/csm_data/commands/store/output.yml +7 -0
  50. {cosmotech_acceleration_library-1.1.0.dist-info → cosmotech_acceleration_library-2.0.0.dist-info}/METADATA +5 -8
  51. {cosmotech_acceleration_library-1.1.0.dist-info → cosmotech_acceleration_library-2.0.0.dist-info}/RECORD +55 -73
  52. cosmotech/coal/azure/functions.py +0 -72
  53. cosmotech/coal/cosmotech_api/connection.py +0 -96
  54. cosmotech/coal/cosmotech_api/dataset/__init__.py +0 -26
  55. cosmotech/coal/cosmotech_api/dataset/converters.py +0 -164
  56. cosmotech/coal/cosmotech_api/dataset/download/__init__.py +0 -19
  57. cosmotech/coal/cosmotech_api/dataset/download/adt.py +0 -119
  58. cosmotech/coal/cosmotech_api/dataset/download/common.py +0 -140
  59. cosmotech/coal/cosmotech_api/dataset/download/file.py +0 -229
  60. cosmotech/coal/cosmotech_api/dataset/download/twingraph.py +0 -185
  61. cosmotech/coal/cosmotech_api/dataset/upload.py +0 -41
  62. cosmotech/coal/cosmotech_api/dataset/utils.py +0 -132
  63. cosmotech/coal/cosmotech_api/parameters.py +0 -48
  64. cosmotech/coal/cosmotech_api/run.py +0 -25
  65. cosmotech/coal/cosmotech_api/run_data.py +0 -173
  66. cosmotech/coal/cosmotech_api/run_template.py +0 -108
  67. cosmotech/coal/cosmotech_api/runner/__init__.py +0 -28
  68. cosmotech/coal/cosmotech_api/runner/data.py +0 -38
  69. cosmotech/coal/cosmotech_api/runner/datasets.py +0 -416
  70. cosmotech/coal/cosmotech_api/runner/download.py +0 -135
  71. cosmotech/coal/cosmotech_api/runner/metadata.py +0 -42
  72. cosmotech/coal/cosmotech_api/runner/parameters.py +0 -157
  73. cosmotech/coal/cosmotech_api/twin_data_layer.py +0 -512
  74. cosmotech/coal/cosmotech_api/workspace.py +0 -127
  75. cosmotech/coal/utils/postgresql.py +0 -236
  76. cosmotech/coal/utils/semver.py +0 -6
  77. cosmotech/csm_data/commands/api/rds_load_csv.py +0 -90
  78. cosmotech/csm_data/commands/api/rds_send_csv.py +0 -74
  79. cosmotech/csm_data/commands/api/rds_send_store.py +0 -74
  80. cosmotech/csm_data/commands/api/runtemplate_load_handler.py +0 -66
  81. cosmotech/csm_data/commands/api/tdl_load_files.py +0 -76
  82. cosmotech/csm_data/commands/api/tdl_send_files.py +0 -82
  83. cosmotech/orchestrator_plugins/csm-data/templates/api/rds_load_csv.json +0 -27
  84. cosmotech/orchestrator_plugins/csm-data/templates/api/rds_send_csv.json +0 -27
  85. cosmotech/orchestrator_plugins/csm-data/templates/api/rds_send_store.json +0 -27
  86. cosmotech/orchestrator_plugins/csm-data/templates/api/runtemplate_load_handler.json +0 -27
  87. cosmotech/orchestrator_plugins/csm-data/templates/api/tdl_load_files.json +0 -32
  88. cosmotech/orchestrator_plugins/csm-data/templates/api/tdl_send_files.json +0 -27
  89. cosmotech/translation/coal/en-US/coal/cosmotech_api/run_data.yml +0 -2
  90. cosmotech/translation/csm_data/en-US/csm_data/commands/api/rds_load_csv.yml +0 -13
  91. cosmotech/translation/csm_data/en-US/csm_data/commands/api/rds_send_csv.yml +0 -12
  92. cosmotech/translation/csm_data/en-US/csm_data/commands/api/rds_send_store.yml +0 -12
  93. cosmotech/translation/csm_data/en-US/csm_data/commands/api/tdl_load_files.yml +0 -14
  94. cosmotech/translation/csm_data/en-US/csm_data/commands/api/tdl_send_files.yml +0 -18
  95. {cosmotech_acceleration_library-1.1.0.dist-info → cosmotech_acceleration_library-2.0.0.dist-info}/WHEEL +0 -0
  96. {cosmotech_acceleration_library-1.1.0.dist-info → cosmotech_acceleration_library-2.0.0.dist-info}/entry_points.txt +0 -0
  97. {cosmotech_acceleration_library-1.1.0.dist-info → cosmotech_acceleration_library-2.0.0.dist-info}/licenses/LICENSE +0 -0
  98. {cosmotech_acceleration_library-1.1.0.dist-info → cosmotech_acceleration_library-2.0.0.dist-info}/top_level.txt +0 -0
@@ -15,9 +15,9 @@ uploading files to blob storage.
15
15
  import pathlib
16
16
 
17
17
  from azure.storage.blob import ContainerClient
18
+ from cosmotech.orchestrator.utils.translate import T
18
19
 
19
20
  from cosmotech.coal.utils.logger import LOGGER
20
- from cosmotech.orchestrator.utils.translate import T
21
21
 
22
22
 
23
23
  def upload_file(
@@ -65,10 +65,10 @@ def upload_folder(
65
65
  raise FileNotFoundError(T("coal.common.file_operations.not_found").format(source_folder=source_folder))
66
66
 
67
67
  if source_path.is_dir():
68
- _source_name = str(source_path)
68
+ # _source_name = str(source_path)
69
69
  for _file_path in source_path.glob("**/*" if recursive else "*"):
70
70
  if _file_path.is_file():
71
- _file_name = str(_file_path).removeprefix(_source_name).removeprefix("/")
71
+ # _file_name = str(_file_path).removeprefix(_source_name).removeprefix("/")
72
72
  upload_file(_file_path, blob_name, az_storage_sas_url, file_prefix)
73
73
  else:
74
74
  upload_file(source_path, blob_name, az_storage_sas_url, file_prefix)
@@ -10,31 +10,3 @@ Cosmotech API integration module.
10
10
 
11
11
  This module provides functions for interacting with the Cosmotech API.
12
12
  """
13
-
14
- # Re-export functions from the parameters module
15
- from cosmotech.coal.cosmotech_api.parameters import (
16
- write_parameters,
17
- )
18
-
19
- from cosmotech.coal.utils.semver import semver_of
20
-
21
- csm_version = semver_of("cosmotech_api")
22
- if csm_version.major < 5:
23
- # Re-export functions from the twin_data_layer module
24
- from cosmotech.coal.cosmotech_api.twin_data_layer import (
25
- get_dataset_id_from_runner,
26
- send_files_to_tdl,
27
- load_files_from_tdl,
28
- )
29
-
30
- # Re-export functions from the run_data module
31
- from cosmotech.coal.cosmotech_api.run_data import (
32
- send_csv_to_run_data,
33
- send_store_to_run_data,
34
- load_csv_from_run_data,
35
- )
36
-
37
- # Re-export functions from the run_template module
38
- from cosmotech.coal.cosmotech_api.run_template import (
39
- load_run_template_handlers,
40
- )
@@ -0,0 +1,14 @@
1
+ # Copyright (C) - 2023 - 2025 - Cosmo Tech
2
+ # This document and all information contained herein is the exclusive property -
3
+ # including all intellectual property rights pertaining thereto - of Cosmo Tech.
4
+ # Any use, reproduction, translation, broadcasting, transmission, distribution,
5
+ # etc., to any person is prohibited unless it has been previously and
6
+ # specifically authorized by written means by Cosmo Tech.
7
+
8
+ from cosmotech.coal.cosmotech_api.apis.dataset import DatasetApi
9
+ from cosmotech.coal.cosmotech_api.apis.meta import MetaApi
10
+ from cosmotech.coal.cosmotech_api.apis.organization import OrganizationApi
11
+ from cosmotech.coal.cosmotech_api.apis.run import RunApi
12
+ from cosmotech.coal.cosmotech_api.apis.runner import RunnerApi
13
+ from cosmotech.coal.cosmotech_api.apis.solution import SolutionApi
14
+ from cosmotech.coal.cosmotech_api.apis.workspace import WorkspaceApi
@@ -0,0 +1,103 @@
1
+ # Copyright (C) - 2023 - 2025 - Cosmo Tech
2
+ # This document and all information contained herein is the exclusive property -
3
+ # including all intellectual property rights pertaining thereto - of Cosmo Tech.
4
+ # Any use, reproduction, translation, broadcasting, transmission, distribution,
5
+ # etc., to any person is prohibited unless it has been previously and
6
+ # specifically authorized by written means by Cosmo Tech.
7
+ from pathlib import Path
8
+ from typing import Optional, Union
9
+
10
+ from cosmotech.orchestrator.utils.translate import T
11
+ from cosmotech_api import (
12
+ Dataset,
13
+ )
14
+ from cosmotech_api import DatasetApi as BaseDatasetApi
15
+ from cosmotech_api import (
16
+ DatasetCreateRequest,
17
+ DatasetPartCreateRequest,
18
+ DatasetPartTypeEnum,
19
+ )
20
+
21
+ from cosmotech.coal.cosmotech_api.objects.connection import Connection
22
+ from cosmotech.coal.utils.configuration import ENVIRONMENT_CONFIGURATION, Configuration
23
+ from cosmotech.coal.utils.logger import LOGGER
24
+
25
+
26
+ class DatasetApi(BaseDatasetApi, Connection):
27
+
28
+ def __init__(
29
+ self,
30
+ configuration: Configuration = ENVIRONMENT_CONFIGURATION,
31
+ ):
32
+ Connection.__init__(self, configuration)
33
+ BaseDatasetApi.__init__(self, self.api_client)
34
+
35
+ LOGGER.debug(T("coal.cosmotech_api.initialization.dataset_api_initialized"))
36
+
37
+ def download_dataset(self, dataset_id) -> Dataset:
38
+ dataset = self.get_dataset(
39
+ organization_id=self.configuration.cosmotech.organization_id,
40
+ workspace_id=self.configuration.cosmotech.workspace_id,
41
+ dataset_id=dataset_id,
42
+ )
43
+
44
+ dataset_dir = self.configuration.cosmotech.dataset_absolute_path
45
+ dataset_dir_path = Path(dataset_dir) / dataset_id
46
+ for part in dataset.parts:
47
+ part_file_path = dataset_dir_path / part.source_name
48
+ part_file_path.parent.mkdir(parents=True, exist_ok=True)
49
+ data_part = self.download_dataset_part(
50
+ organization_id=self.configuration.cosmotech.organization_id,
51
+ workspace_id=self.configuration.cosmotech.workspace_id,
52
+ dataset_id=dataset_id,
53
+ dataset_part_id=part.id,
54
+ )
55
+ with open(part_file_path, "wb") as binary_file:
56
+ binary_file.write(data_part)
57
+ LOGGER.debug(
58
+ T("coal.services.dataset.part_downloaded").format(part_name=part.source_name, file_path=part_file_path)
59
+ )
60
+ return dataset
61
+
62
+ @staticmethod
63
+ def path_to_parts(_path, part_type) -> list[tuple[str, Path, DatasetPartTypeEnum]]:
64
+ if (_path := Path(_path)).is_dir():
65
+ return list((str(_p.relative_to(_path)), _p, part_type) for _p in _path.rglob("*") if _p.is_file())
66
+ return list(((_path.name, _path, part_type),))
67
+
68
+ def upload_dataset(
69
+ self,
70
+ dataset_name: str,
71
+ as_files: Optional[list[Union[Path, str]]] = (),
72
+ as_db: Optional[list[Union[Path, str]]] = (),
73
+ ) -> Dataset:
74
+ _parts = list()
75
+
76
+ for _f in as_files:
77
+ _parts.extend(self.path_to_parts(_f, DatasetPartTypeEnum.FILE))
78
+
79
+ for _db in as_db:
80
+ _parts.extend(self.path_to_parts(_db, DatasetPartTypeEnum.DB))
81
+
82
+ d_request = DatasetCreateRequest(
83
+ name=dataset_name,
84
+ parts=list(
85
+ DatasetPartCreateRequest(
86
+ name=_p_name,
87
+ description=_p_name,
88
+ sourceName=_p_name,
89
+ type=_type,
90
+ )
91
+ for _p_name, _, _type in _parts
92
+ ),
93
+ )
94
+
95
+ d_ret = self.create_dataset(
96
+ self.configuration.cosmotech.organization_id,
97
+ self.configuration.cosmotech.workspace_id,
98
+ d_request,
99
+ files=list((_p[0], _p[1].open("rb").read()) for _p in _parts),
100
+ )
101
+
102
+ LOGGER.info(T("coal.services.dataset.dataset_created").format(dataset_id=d_ret.id))
103
+ return d_ret
@@ -0,0 +1,25 @@
1
+ # Copyright (C) - 2023 - 2025 - Cosmo Tech
2
+ # This document and all information contained herein is the exclusive property -
3
+ # including all intellectual property rights pertaining thereto - of Cosmo Tech.
4
+ # Any use, reproduction, translation, broadcasting, transmission, distribution,
5
+ # etc., to any person is prohibited unless it has been previously and
6
+ # specifically authorized by written means by Cosmo Tech.
7
+ from cosmotech.orchestrator.utils.translate import T
8
+ from cosmotech_api import MetaApi as BaseMetaApi
9
+
10
+ from cosmotech.coal.cosmotech_api.objects.connection import Connection
11
+ from cosmotech.coal.utils.configuration import ENVIRONMENT_CONFIGURATION, Configuration
12
+ from cosmotech.coal.utils.logger import LOGGER
13
+
14
+
15
+ class MetaApi(BaseMetaApi, Connection):
16
+
17
+ def __init__(
18
+ self,
19
+ configuration: Configuration = ENVIRONMENT_CONFIGURATION,
20
+ ):
21
+ Connection.__init__(self, configuration)
22
+
23
+ BaseMetaApi.__init__(self, self.api_client)
24
+
25
+ LOGGER.debug(T("coal.cosmotech_api.initialization.meta_api_initialized"))
@@ -0,0 +1,24 @@
1
+ # Copyright (C) - 2023 - 2025 - Cosmo Tech
2
+ # This document and all information contained herein is the exclusive property -
3
+ # including all intellectual property rights pertaining thereto - of Cosmo Tech.
4
+ # Any use, reproduction, translation, broadcasting, transmission, distribution,
5
+ # etc., to any person is prohibited unless it has been previously and
6
+ # specifically authorized by written means by Cosmo Tech.
7
+ from cosmotech.orchestrator.utils.translate import T
8
+ from cosmotech_api import OrganizationApi as BaseOrganizationApi
9
+
10
+ from cosmotech.coal.cosmotech_api.objects.connection import Connection
11
+ from cosmotech.coal.utils.configuration import ENVIRONMENT_CONFIGURATION, Configuration
12
+ from cosmotech.coal.utils.logger import LOGGER
13
+
14
+
15
+ class OrganizationApi(BaseOrganizationApi, Connection):
16
+
17
+ def __init__(
18
+ self,
19
+ configuration: Configuration = ENVIRONMENT_CONFIGURATION,
20
+ ):
21
+ Connection.__init__(self, configuration)
22
+ BaseOrganizationApi.__init__(self, self.api_client)
23
+
24
+ LOGGER.debug(T("coal.cosmotech_api.initialization.organization_api_initialized"))
@@ -0,0 +1,38 @@
1
+ # Copyright (C) - 2023 - 2025 - Cosmo Tech
2
+ # This document and all information contained herein is the exclusive property -
3
+ # including all intellectual property rights pertaining thereto - of Cosmo Tech.
4
+ # Any use, reproduction, translation, broadcasting, transmission, distribution,
5
+ # etc., to any person is prohibited unless it has been previously and
6
+ # specifically authorized by written means by Cosmo Tech.
7
+ from typing import Any, Optional
8
+
9
+ from cosmotech.orchestrator.utils.translate import T
10
+ from cosmotech_api import RunApi as BaseRunApi
11
+
12
+ from cosmotech.coal.cosmotech_api.objects.connection import Connection
13
+ from cosmotech.coal.utils.configuration import ENVIRONMENT_CONFIGURATION, Configuration
14
+ from cosmotech.coal.utils.logger import LOGGER
15
+
16
+
17
+ class RunApi(BaseRunApi, Connection):
18
+
19
+ def __init__(
20
+ self,
21
+ configuration: Configuration = ENVIRONMENT_CONFIGURATION,
22
+ ):
23
+ Connection.__init__(self, configuration)
24
+ BaseRunApi.__init__(self, self.api_client)
25
+
26
+ LOGGER.debug(T("coal.cosmotech_api.initialization.run_api_initialized"))
27
+
28
+ def get_run_metadata(
29
+ self,
30
+ organization_id: str,
31
+ workspace_id: str,
32
+ runner_id: str,
33
+ run_id: str,
34
+ include: Optional[list[str]] = None,
35
+ exclude: Optional[list[str]] = None,
36
+ ) -> dict[str, Any]:
37
+ run = self.get_run(organization_id, workspace_id, runner_id, run_id)
38
+ return run.model_dump(by_alias=True, exclude_none=True, include=include, exclude=exclude, mode="json")
@@ -0,0 +1,71 @@
1
+ # Copyright (C) - 2023 - 2025 - Cosmo Tech
2
+ # This document and all information contained herein is the exclusive property -
3
+ # including all intellectual property rights pertaining thereto - of Cosmo Tech.
4
+ # Any use, reproduction, translation, broadcasting, transmission, distribution,
5
+ # etc., to any person is prohibited unless it has been previously and
6
+ # specifically authorized by written means by Cosmo Tech.
7
+ from typing import Any, Optional
8
+
9
+ from cosmotech.orchestrator.utils.translate import T
10
+ from cosmotech_api import RunnerApi as BaseRunnerApi
11
+
12
+ from cosmotech.coal.cosmotech_api.apis.dataset import DatasetApi
13
+ from cosmotech.coal.cosmotech_api.objects.connection import Connection
14
+ from cosmotech.coal.cosmotech_api.objects.parameters import Parameters
15
+ from cosmotech.coal.utils.configuration import ENVIRONMENT_CONFIGURATION, Configuration
16
+ from cosmotech.coal.utils.logger import LOGGER
17
+
18
+
19
+ class RunnerApi(BaseRunnerApi, Connection):
20
+
21
+ def __init__(
22
+ self,
23
+ configuration: Configuration = ENVIRONMENT_CONFIGURATION,
24
+ ):
25
+ Connection.__init__(self, configuration)
26
+ BaseRunnerApi.__init__(self, self.api_client)
27
+
28
+ LOGGER.debug(T("coal.cosmotech_api.initialization.runner_api_initialized"))
29
+
30
+ def get_runner_metadata(
31
+ self,
32
+ organization_id: str,
33
+ workspace_id: str,
34
+ runner_id: str,
35
+ include: Optional[list[str]] = None,
36
+ exclude: Optional[list[str]] = None,
37
+ ) -> dict[str, Any]:
38
+ runner = self.get_runner(organization_id, workspace_id, runner_id)
39
+
40
+ return runner.model_dump(by_alias=True, exclude_none=True, include=include, exclude=exclude, mode="json")
41
+
42
+ def download_runner_data(
43
+ self,
44
+ organization_id: str,
45
+ workspace_id: str,
46
+ runner_id: str,
47
+ parameter_folder: str,
48
+ dataset_folder: Optional[str] = None,
49
+ ):
50
+ LOGGER.info(T("coal.cosmotech_api.runner.starting_download"))
51
+
52
+ # Get runner data
53
+ runner_data = self.get_runner(organization_id, workspace_id, runner_id)
54
+
55
+ # Skip if no parameters found
56
+ if not runner_data.parameters_values:
57
+ LOGGER.warning(T("coal.cosmotech_api.runner.no_parameters"))
58
+ else:
59
+ LOGGER.info(T("coal.cosmotech_api.runner.loaded_data"))
60
+ parameters = Parameters(runner_data)
61
+ parameters.write_parameters_to_json(parameter_folder)
62
+
63
+ # Download datasets if requested
64
+ if dataset_folder:
65
+ datasets_ids = runner_data.datasets.bases
66
+
67
+ if datasets_ids:
68
+ LOGGER.info(T("coal.cosmotech_api.runner.downloading_datasets").format(count=len(datasets_ids)))
69
+ ds_api = DatasetApi(self.configuration)
70
+ for dataset_id in datasets_ids:
71
+ ds_api.download_dataset(dataset_id)
@@ -0,0 +1,23 @@
1
+ # Copyright (C) - 2023 - 2025 - Cosmo Tech
2
+ # This document and all information contained herein is the exclusive property -
3
+ # including all intellectual property rights pertaining thereto - of Cosmo Tech.
4
+ # Any use, reproduction, translation, broadcasting, transmission, distribution,
5
+ # etc., to any person is prohibited unless it has been previously and
6
+ # specifically authorized by written means by Cosmo Tech.
7
+ from cosmotech.orchestrator.utils.translate import T
8
+ from cosmotech_api import SolutionApi as BaseSolutionApi
9
+
10
+ from cosmotech.coal.cosmotech_api.objects.connection import Connection
11
+ from cosmotech.coal.utils.configuration import ENVIRONMENT_CONFIGURATION, Configuration
12
+ from cosmotech.coal.utils.logger import LOGGER
13
+
14
+
15
+ class SolutionApi(BaseSolutionApi, Connection):
16
+ def __init__(
17
+ self,
18
+ configuration: Configuration = ENVIRONMENT_CONFIGURATION,
19
+ ):
20
+ Connection.__init__(self, configuration)
21
+ BaseSolutionApi.__init__(self, self.api_client)
22
+
23
+ LOGGER.debug(T("coal.cosmotech_api.initialization.solution_api_initialized"))
@@ -0,0 +1,108 @@
1
+ # Copyright (C) - 2023 - 2025 - Cosmo Tech
2
+ # This document and all information contained herein is the exclusive property -
3
+ # including all intellectual property rights pertaining thereto - of Cosmo Tech.
4
+ # Any use, reproduction, translation, broadcasting, transmission, distribution,
5
+ # etc., to any person is prohibited unless it has been previously and
6
+ # specifically authorized by written means by Cosmo Tech.
7
+ from pathlib import Path
8
+
9
+ from cosmotech.orchestrator.utils.translate import T
10
+ from cosmotech_api import ApiException
11
+ from cosmotech_api import WorkspaceApi as BaseWorkspaceApi
12
+
13
+ from cosmotech.coal.cosmotech_api.objects.connection import Connection
14
+ from cosmotech.coal.utils.configuration import ENVIRONMENT_CONFIGURATION, Configuration
15
+ from cosmotech.coal.utils.logger import LOGGER
16
+
17
+
18
+ class WorkspaceApi(BaseWorkspaceApi, Connection):
19
+
20
+ def __init__(
21
+ self,
22
+ configuration: Configuration = ENVIRONMENT_CONFIGURATION,
23
+ ):
24
+ Connection.__init__(self, configuration)
25
+ BaseWorkspaceApi.__init__(self, self.api_client)
26
+
27
+ LOGGER.debug(T("coal.cosmotech_api.initialization.workspace_api_initialized"))
28
+
29
+ def list_filtered_workspace_files(
30
+ self,
31
+ organization_id: str,
32
+ workspace_id: str,
33
+ file_prefix: str,
34
+ ) -> list[str]:
35
+ target_list = []
36
+ LOGGER.info(T("coal.cosmotech_api.workspace.target_is_folder"))
37
+ wsf = self.list_workspace_files(organization_id, workspace_id)
38
+ for workspace_file in wsf:
39
+ if workspace_file.file_name.startswith(file_prefix):
40
+ target_list.append(workspace_file.file_name)
41
+
42
+ if not target_list:
43
+ LOGGER.error(
44
+ T("coal.common.errors.data_no_workspace_files").format(
45
+ file_prefix=file_prefix, workspace_id=workspace_id
46
+ )
47
+ )
48
+ raise ValueError(
49
+ T("coal.common.errors.data_no_workspace_files").format(
50
+ file_prefix=file_prefix, workspace_id=workspace_id
51
+ )
52
+ )
53
+
54
+ return target_list
55
+
56
+ def download_workspace_file(
57
+ self,
58
+ organization_id: str,
59
+ workspace_id: str,
60
+ file_name: str,
61
+ target_dir: Path,
62
+ ) -> Path:
63
+ if target_dir.is_file():
64
+ raise ValueError(T("coal.common.file_operations.not_directory").format(target_dir=target_dir))
65
+
66
+ LOGGER.info(T("coal.cosmotech_api.workspace.loading_file").format(file_name=file_name))
67
+
68
+ _file_content = self.get_workspace_file(organization_id, workspace_id, file_name)
69
+
70
+ local_target_file = target_dir / file_name
71
+ local_target_file.parent.mkdir(parents=True, exist_ok=True)
72
+
73
+ with open(local_target_file, "wb") as _file:
74
+ _file.write(_file_content)
75
+
76
+ LOGGER.info(T("coal.cosmotech_api.workspace.file_loaded").format(file=local_target_file))
77
+
78
+ return local_target_file
79
+
80
+ def upload_workspace_file(
81
+ self,
82
+ organization_id: str,
83
+ workspace_id: str,
84
+ file_path: str,
85
+ workspace_path: str,
86
+ overwrite: bool = True,
87
+ ) -> str:
88
+ target_file = Path(file_path)
89
+ if not target_file.exists():
90
+ LOGGER.error(T("coal.common.file_operations.not_exists").format(file_path=file_path))
91
+ raise ValueError(T("coal.common.file_operations.not_exists").format(file_path=file_path))
92
+ if not target_file.is_file():
93
+ LOGGER.error(T("coal.common.file_operations.not_single_file").format(file_path=file_path))
94
+ raise ValueError(T("coal.common.file_operations.not_single_file").format(file_path=file_path))
95
+
96
+ destination = workspace_path + target_file.name if workspace_path.endswith("/") else workspace_path
97
+
98
+ LOGGER.info(T("coal.cosmotech_api.workspace.sending_to_api").format(destination=destination))
99
+ try:
100
+ _file = self.create_workspace_file(
101
+ organization_id, workspace_id, file_path, overwrite, destination=destination
102
+ )
103
+ except ApiException as e:
104
+ LOGGER.error(T("coal.common.file_operations.already_exists").format(csv_path=destination))
105
+ raise e
106
+
107
+ LOGGER.info(T("coal.cosmotech_api.workspace.file_sent").format(file=_file.file_name))
108
+ return _file.file_name
@@ -0,0 +1,9 @@
1
+ # Copyright (C) - 2023 - 2025 - Cosmo Tech
2
+ # This document and all information contained herein is the exclusive property -
3
+ # including all intellectual property rights pertaining thereto - of Cosmo Tech.
4
+ # Any use, reproduction, translation, broadcasting, transmission, distribution,
5
+ # etc., to any person is prohibited unless it has been previously and
6
+ # specifically authorized by written means by Cosmo Tech.
7
+
8
+ from cosmotech.coal.cosmotech_api.objects.connection import Connection
9
+ from cosmotech.coal.cosmotech_api.objects.parameters import Parameters
@@ -0,0 +1,125 @@
1
+ # Copyright (C) - 2023 - 2025 - Cosmo Tech
2
+ # This document and all information contained herein is the exclusive property -
3
+ # including all intellectual property rights pertaining thereto - of Cosmo Tech.
4
+ # Any use, reproduction, translation, broadcasting, transmission, distribution,
5
+ # etc., to any person is prohibited unless it has been previously and
6
+ # specifically authorized by written means by Cosmo Tech.
7
+
8
+ # Copyright (C) - 2023 - 2025 - Cosmo Tech
9
+ # This document and all information contained herein is the exclusive property -
10
+ # including all intellectual property rights pertaining thereto - of Cosmo Tech.
11
+ # Any use, reproduction, translation, broadcasting, transmission, distribution,
12
+ # etc., to any person is prohibited unless it has been previously and
13
+ # specifically authorized by written means by Cosmo Tech.
14
+ import os
15
+ import pathlib
16
+
17
+ import cosmotech_api
18
+ from cosmotech.orchestrator.utils.translate import T
19
+ from cosmotech_api import ApiClient
20
+
21
+ from cosmotech.coal.utils.configuration import ENVIRONMENT_CONFIGURATION, Configuration
22
+ from cosmotech.coal.utils.logger import LOGGER
23
+
24
+
25
+ class Connection:
26
+ configuration: Configuration
27
+ api_client: ApiClient
28
+ api_type: str
29
+
30
+ # TODO :
31
+ # Replace use of environment variable by configuration usage
32
+ __api_env_keys = {"CSM_API_KEY", "CSM_API_URL"}
33
+ __azure_env_keys = {
34
+ "AZURE_CLIENT_ID",
35
+ "AZURE_CLIENT_SECRET",
36
+ "AZURE_TENANT_ID",
37
+ "CSM_API_URL",
38
+ "CSM_API_SCOPE",
39
+ }
40
+ __keycloak_env_keys = {
41
+ "IDP_TENANT_ID",
42
+ "IDP_CLIENT_ID",
43
+ "IDP_CLIENT_SECRET",
44
+ "IDP_BASE_URL",
45
+ "CSM_API_URL",
46
+ }
47
+
48
+ def __init__(
49
+ self,
50
+ configuration: Configuration = ENVIRONMENT_CONFIGURATION,
51
+ ):
52
+ self.configuration = configuration
53
+ self.api_client, self.api_type = self.get_api_client()
54
+
55
+ def get_api_client(self) -> (cosmotech_api.ApiClient, str):
56
+ existing_keys = set(os.environ.keys())
57
+ missing_azure_keys = self.__azure_env_keys - existing_keys
58
+ missing_api_keys = self.__api_env_keys - existing_keys
59
+ missing_keycloak_keys = self.__keycloak_env_keys - existing_keys
60
+
61
+ if all((missing_api_keys, missing_azure_keys, missing_keycloak_keys)):
62
+ LOGGER.error(T("coal.common.errors.no_env_vars"))
63
+ LOGGER.error(T("coal.cosmotech_api.connection.existing_sets"))
64
+ LOGGER.error(
65
+ T("coal.cosmotech_api.connection.azure_connection").format(keys=", ".join(self.__azure_env_keys))
66
+ )
67
+ LOGGER.error(
68
+ T("coal.cosmotech_api.connection.api_key_connection").format(keys=", ".join(self.__api_env_keys))
69
+ )
70
+ LOGGER.error(
71
+ T("coal.cosmotech_api.connection.keycloak_connection").format(keys=", ".join(self.__keycloak_env_keys))
72
+ )
73
+ raise EnvironmentError(T("coal.common.errors.no_env_vars"))
74
+
75
+ if not missing_keycloak_keys:
76
+ LOGGER.debug(T("coal.cosmotech_api.connection.found_keycloak"))
77
+ from keycloak import KeycloakOpenID
78
+
79
+ server_url = os.environ.get("IDP_BASE_URL")
80
+ if server_url[-1] != "/":
81
+ server_url = server_url + "/"
82
+ keycloack_parameters = dict(
83
+ server_url=server_url,
84
+ client_id=os.environ.get("IDP_CLIENT_ID"),
85
+ realm_name=os.environ.get("IDP_TENANT_ID"),
86
+ client_secret_key=os.environ.get("IDP_CLIENT_SECRET"),
87
+ )
88
+ if (ca_cert_path := os.environ.get("IDP_CA_CERT")) and pathlib.Path(ca_cert_path).exists():
89
+ LOGGER.info(T("coal.cosmotech_api.connection.found_cert_authority"))
90
+ keycloack_parameters["verify"] = ca_cert_path
91
+ keycloak_openid = KeycloakOpenID(**keycloack_parameters)
92
+
93
+ access_token = keycloak_openid.token(grant_type="client_credentials")
94
+
95
+ configuration = cosmotech_api.Configuration(
96
+ host=os.environ.get("CSM_API_URL"),
97
+ access_token=access_token["access_token"],
98
+ )
99
+ return cosmotech_api.ApiClient(configuration), "Keycloak Connection"
100
+
101
+ if not missing_api_keys:
102
+ LOGGER.debug(T("coal.cosmotech_api.connection.found_api_key"))
103
+ configuration = cosmotech_api.Configuration(
104
+ host=os.environ.get("CSM_API_URL"),
105
+ )
106
+ return (
107
+ cosmotech_api.ApiClient(
108
+ configuration,
109
+ os.environ.get("CSM_API_KEY_HEADER", "X-CSM-API-KEY"),
110
+ os.environ.get("CSM_API_KEY"),
111
+ ),
112
+ "Cosmo Tech API Key",
113
+ )
114
+
115
+ if not missing_azure_keys:
116
+ LOGGER.debug(T("coal.cosmotech_api.connection.found_azure"))
117
+ from azure.identity import EnvironmentCredential
118
+
119
+ credentials = EnvironmentCredential()
120
+ token = credentials.get_token(os.environ.get("CSM_API_SCOPE"))
121
+
122
+ configuration = cosmotech_api.Configuration(host=os.environ.get("CSM_API_URL"), access_token=token.token)
123
+ return cosmotech_api.ApiClient(configuration), "Azure Entra Connection"
124
+
125
+ raise EnvironmentError(T("coal.common.errors.no_valid_connection"))