das-setup-helper 0.1.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 (34) hide show
  1. das_setup_helper/__init__.py +3 -0
  2. das_setup_helper/data/__init__.py +0 -0
  3. das_setup_helper/data/fs/__init__.py +0 -0
  4. das_setup_helper/data/fs/base.py +72 -0
  5. das_setup_helper/data/fs/local.py +16 -0
  6. das_setup_helper/data/fs/s3.py +12 -0
  7. das_setup_helper/data/fs/wihp_api.py +46 -0
  8. das_setup_helper/data/io.py +131 -0
  9. das_setup_helper/pipelines/__init__.py +0 -0
  10. das_setup_helper/pipelines/create_acquisitions.py +44 -0
  11. das_setup_helper/pipelines/setup_crawler.py +86 -0
  12. das_setup_helper/pipelines/stop_acquisitions.py +46 -0
  13. das_setup_helper/shared/__init__.py +0 -0
  14. das_setup_helper/shared/connectors/__init__.py +0 -0
  15. das_setup_helper/shared/connectors/base.py +233 -0
  16. das_setup_helper/shared/connectors/local.py +167 -0
  17. das_setup_helper/shared/connectors/s3connector.py +243 -0
  18. das_setup_helper/shared/connectors/wihp_api.py +1230 -0
  19. das_setup_helper/shared/constant/__init__.py +0 -0
  20. das_setup_helper/shared/constant/general.py +7 -0
  21. das_setup_helper/shared/constant/s3.py +37 -0
  22. das_setup_helper/shared/constant/sources.py +45 -0
  23. das_setup_helper/shared/constant/wihp_api.py +123 -0
  24. das_setup_helper/shared/context.py +107 -0
  25. das_setup_helper/shared/exceptions/__init__.py +0 -0
  26. das_setup_helper/shared/exceptions/definitions.py +61 -0
  27. das_setup_helper/shared/logger.py +45 -0
  28. das_setup_helper/shared/utils.py +172 -0
  29. das_setup_helper-0.1.0.dist-info/METADATA +298 -0
  30. das_setup_helper-0.1.0.dist-info/RECORD +34 -0
  31. das_setup_helper-0.1.0.dist-info/WHEEL +5 -0
  32. das_setup_helper-0.1.0.dist-info/entry_points.txt +4 -0
  33. das_setup_helper-0.1.0.dist-info/licenses/LICENSE +287 -0
  34. das_setup_helper-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,3 @@
1
+ from das_setup_helper.shared.utils import set_environment_variables
2
+
3
+ set_environment_variables()
File without changes
File without changes
@@ -0,0 +1,72 @@
1
+ from typing import Protocol
2
+
3
+ from das_setup_helper.shared.context import Context
4
+
5
+
6
+ class IOManager(Protocol):
7
+ """
8
+ Protocol describing minimal IO operations over a single data source.
9
+
10
+ Methods
11
+ -------
12
+ read(acquisition_id_or_s3_path)
13
+ Reads data from the specified acquisition ID or S3 path.
14
+ """
15
+
16
+ def __init__(self): ...
17
+
18
+ def read(self, acquisition_id_or_s3_path): ...
19
+
20
+
21
+ class StorageIOManager:
22
+ """
23
+ Base class for storage-backed IOManagers (S3, local, …).
24
+
25
+ ``IOHandler`` uses ``isinstance(io, StorageIOManager)`` to dispatch
26
+ storage-related operations without being tied to a specific backend.
27
+ """
28
+
29
+ def __init__(self, context: Context):
30
+ self.context = context
31
+
32
+ def copy_file(self, file_path: str, new_file_path: str) -> None:
33
+ self.context.storage_connector.copy_file(file_path, new_file_path)
34
+
35
+ def get_crawler_configs(self) -> dict:
36
+ return self.context.storage_connector.get_crawler_configs()
37
+
38
+ def get_valid_wihp_config_to_create(self) -> list:
39
+ return self.context.storage_connector.get_wihp_sources_to_create()
40
+
41
+ def read(self, file_path: str):
42
+ return self.context.storage_connector.read(file_path)
43
+
44
+ def write(self, index_documents: list, file_path: str) -> bool:
45
+ return self.context.storage_connector.write_json(index_documents, file_path)
46
+
47
+ def save_acquisition_infos(self, acquisition_infos: dict) -> bool:
48
+ return self.context.storage_connector.save_acquisition_infos(acquisition_infos)
49
+
50
+ def save_crawler_info(
51
+ self,
52
+ sources_to_create,
53
+ duplicated_urls,
54
+ null_mne_names,
55
+ non_english_urls,
56
+ long_mne_names,
57
+ crawler_name: str,
58
+ crawler_id: str,
59
+ crawler_timestamp: str,
60
+ updated_sources=None,
61
+ ) -> bool:
62
+ return self.context.storage_connector.save_crawler_info(
63
+ sources_to_create,
64
+ duplicated_urls,
65
+ null_mne_names,
66
+ non_english_urls,
67
+ long_mne_names,
68
+ crawler_name,
69
+ crawler_id,
70
+ crawler_timestamp,
71
+ updated_sources,
72
+ )
@@ -0,0 +1,16 @@
1
+ """
2
+ IOManager implementation backed by the local filesystem.
3
+ """
4
+
5
+ from das_setup_helper.data.fs.base import StorageIOManager
6
+
7
+ __all__ = ["LocalIOManager"]
8
+
9
+
10
+ class LocalIOManager(StorageIOManager):
11
+ """
12
+ IOManager implementation backed by the local filesystem.
13
+
14
+ Delegates to context.storage_connector (LocalStorageConnector).
15
+ Drop-in replacement for S3IOManager when STORAGE_BACKEND=local.
16
+ """
@@ -0,0 +1,12 @@
1
+ from das_setup_helper.data.fs.base import StorageIOManager
2
+
3
+ __all__ = ["S3IOManager"]
4
+
5
+
6
+ class S3IOManager(StorageIOManager):
7
+ """
8
+ IOManager implementation backed by S3.
9
+
10
+ Provides the S3 operations needed by setup_crawler and create_acquisitions
11
+ pipelines: config loading, source validation, and result persistence.
12
+ """
@@ -0,0 +1,46 @@
1
+ from das_setup_helper.shared.context import Context
2
+
3
+ __all__ = ["WihpAPIIOManager"]
4
+
5
+
6
+ class WihpAPIIOManager:
7
+ """
8
+ IOManager implementation backed by the WIHP API.
9
+
10
+ Provides the crawler and acquisition lifecycle methods used by the
11
+ setup_crawler, create_acquisitions, and stop_acquisitions pipelines.
12
+ """
13
+
14
+ def __init__(self, context: Context):
15
+ self.context = context
16
+
17
+ def create_crawler(self, sources_to_create):
18
+ return self.context.wihp_api_connector.create_crawler_and_add_sources(
19
+ sources_to_create
20
+ )
21
+
22
+ def get_candidates_to_stopped(self) -> list:
23
+ return self.context.wihp_api_connector.get_candidates_acquisition_to_stopped()
24
+
25
+ def get_acquisition_status_counts(self, acquisition_id: str) -> list:
26
+ return self.context.wihp_api_connector.get_acquisition_status_counts(
27
+ acquisition_id
28
+ )
29
+
30
+ def select_acquisitions_to_stop_from_status_counts(
31
+ self,
32
+ acquisition_ids: list,
33
+ ) -> list:
34
+ return self.context.wihp_api_connector.select_acquisitions_to_stop_from_status_counts(
35
+ acquisition_ids,
36
+ )
37
+
38
+ def create_acquisitions(self, crawler_configs: dict) -> dict:
39
+ return self.context.wihp_api_connector.create_acquisitions(crawler_configs)
40
+
41
+ def stop_non_discovered_acquisition(
42
+ self, running_acquisitions_to_stop: list
43
+ ) -> None:
44
+ self.context.wihp_api_connector.stop_acquisitions(
45
+ running_acquisitions_to_stop,
46
+ )
@@ -0,0 +1,131 @@
1
+ import logging
2
+
3
+ from das_setup_helper.data.fs.base import IOManager, StorageIOManager
4
+ from das_setup_helper.data.fs.wihp_api import WihpAPIIOManager
5
+ from das_setup_helper.shared.context import Context
6
+ from das_setup_helper.shared.logger import setup_logger
7
+
8
+ logger = setup_logger("io", logging.DEBUG)
9
+
10
+
11
+ class IOHandler:
12
+ """
13
+ Facade that routes I/O operations to the appropriate IOManager.
14
+
15
+ Only the methods required by the three public pipelines are exposed:
16
+
17
+ * setup_crawler — create_crawler, get_validated_config,
18
+ save_crawler_info
19
+ * create_acquisitions — get_crawler_configs, create_acquisitions,
20
+ save_acquisition_infos
21
+ * stop_acquisitions — get_candidates_to_stopped,
22
+ get_acquisition_status_counts,
23
+ select_acquisitions_to_stop_from_status_counts,
24
+ select_acquisitions_to_stop,
25
+ stop_non_discovered_acquisition
26
+ """
27
+
28
+ def __init__(self, context: Context, io_manager: IOManager):
29
+ self.context = context
30
+ self.io = io_manager
31
+
32
+ # ------------------------------------------------------------------ #
33
+ # setup_crawler pipeline #
34
+ # ------------------------------------------------------------------ #
35
+
36
+ def create_crawler(self, sources_to_create):
37
+ if not isinstance(self.io, WihpAPIIOManager):
38
+ msg = "Only WihpAPIIOManager supports create_crawler."
39
+ raise NotImplementedError(msg)
40
+ return self.io.create_crawler(sources_to_create)
41
+
42
+ def get_validated_config(self):
43
+ if not isinstance(self.io, StorageIOManager):
44
+ msg = "Only a StorageIOManager supports get_validated_config."
45
+ raise NotImplementedError(msg)
46
+ return self.io.get_valid_wihp_config_to_create()
47
+
48
+ def save_crawler_info(
49
+ self,
50
+ sources_to_create,
51
+ duplicated_urls,
52
+ null_mne_names,
53
+ non_english_urls,
54
+ long_mne_names,
55
+ crawler_name: str,
56
+ crawler_id: str,
57
+ crawler_timestamp: str,
58
+ updated_sources=None,
59
+ ):
60
+ if not isinstance(self.io, StorageIOManager):
61
+ msg = "Only a StorageIOManager supports save_crawler_info."
62
+ raise NotImplementedError(msg)
63
+ self.io.save_crawler_info(
64
+ sources_to_create,
65
+ duplicated_urls,
66
+ null_mne_names,
67
+ non_english_urls,
68
+ long_mne_names,
69
+ crawler_name,
70
+ crawler_id,
71
+ crawler_timestamp,
72
+ updated_sources,
73
+ )
74
+
75
+ # ------------------------------------------------------------------ #
76
+ # create_acquisitions pipeline #
77
+ # ------------------------------------------------------------------ #
78
+
79
+ def get_crawler_configs(self) -> dict:
80
+ if not isinstance(self.io, StorageIOManager):
81
+ msg = "Only a StorageIOManager supports get_crawler_configs."
82
+ raise NotImplementedError(msg)
83
+ return self.io.get_crawler_configs()
84
+
85
+ def create_acquisitions(self, crawler_configs: dict) -> dict:
86
+ if not isinstance(self.io, WihpAPIIOManager):
87
+ msg = "Only WihpAPIIOManager supports create_acquisitions."
88
+ raise NotImplementedError(msg)
89
+ return self.io.create_acquisitions(crawler_configs)
90
+
91
+ def save_acquisition_infos(self, acquisition_infos: dict):
92
+ if not isinstance(self.io, StorageIOManager):
93
+ msg = "Only a StorageIOManager supports save_acquisition_infos."
94
+ raise NotImplementedError(msg)
95
+ self.io.save_acquisition_infos(acquisition_infos)
96
+
97
+ # ------------------------------------------------------------------ #
98
+ # stop_acquisitions pipeline #
99
+ # ------------------------------------------------------------------ #
100
+
101
+ def get_candidates_to_stopped(self) -> list:
102
+ if not isinstance(self.io, WihpAPIIOManager):
103
+ msg = "Only WihpAPIIOManager supports get_candidates_to_stopped."
104
+ raise NotImplementedError(msg)
105
+ return self.io.get_candidates_to_stopped()
106
+
107
+ def get_acquisition_status_counts(self, acquisition_id: str) -> list:
108
+ if not isinstance(self.io, WihpAPIIOManager):
109
+ msg = "Only WihpAPIIOManager supports get_acquisition_status_counts."
110
+ raise NotImplementedError(msg)
111
+ return self.io.get_acquisition_status_counts(acquisition_id)
112
+
113
+ def select_acquisitions_to_stop_from_status_counts(
114
+ self,
115
+ acquisition_ids: list,
116
+ ) -> list:
117
+ if not isinstance(self.io, WihpAPIIOManager):
118
+ msg = (
119
+ "Only WihpAPIIOManager supports "
120
+ "select_acquisitions_to_stop_from_status_counts."
121
+ )
122
+ raise NotImplementedError(msg)
123
+ return self.io.select_acquisitions_to_stop_from_status_counts(
124
+ acquisition_ids,
125
+ )
126
+
127
+ def stop_non_discovered_acquisition(self, running_acquisitions_to_stop: list):
128
+ if not isinstance(self.io, WihpAPIIOManager):
129
+ msg = "Only WihpAPIIOManager supports stop_non_discovered_acquisition."
130
+ raise NotImplementedError(msg)
131
+ self.io.stop_non_discovered_acquisition(running_acquisitions_to_stop)
File without changes
@@ -0,0 +1,44 @@
1
+ import asyncio
2
+ import logging
3
+
4
+ from das_setup_helper.data.fs.s3 import S3IOManager
5
+ from das_setup_helper.data.fs.wihp_api import WihpAPIIOManager
6
+ from das_setup_helper.data.io import IOHandler
7
+ from das_setup_helper.shared.context import Context
8
+ from das_setup_helper.shared.logger import setup_logger
9
+
10
+ logger = setup_logger("create_acquisitions", logging.DEBUG)
11
+
12
+
13
+ async def create_and_trigger_acquisitions():
14
+ """
15
+ Create and trigger new acquisitions in WIHP.
16
+
17
+ Retrieves crawler configurations from S3, creates new acquisitions in WIHP
18
+ via the API, saves the acquisition information back to S3, and returns the
19
+ acquisition details.
20
+
21
+ Returns:
22
+ dict: Acquisition information keyed by acquisition ID.
23
+ """
24
+ logger.info("Triggering new acquisitions under WIHP")
25
+ context = Context()
26
+
27
+ s3 = IOHandler(context, S3IOManager(context))
28
+ crawler_configs = s3.get_crawler_configs()
29
+
30
+ wihp_api = IOHandler(context, WihpAPIIOManager(context))
31
+ acquisition_infos = wihp_api.create_acquisitions(crawler_configs)
32
+
33
+ s3.save_acquisition_infos(acquisition_infos)
34
+ logger.info(f"New acquisitions triggered under WIHP:\n{acquisition_infos}")
35
+
36
+ return acquisition_infos
37
+
38
+
39
+ def main():
40
+ asyncio.run(create_and_trigger_acquisitions())
41
+
42
+
43
+ if __name__ == "__main__":
44
+ main()
@@ -0,0 +1,86 @@
1
+ import asyncio
2
+ import logging
3
+
4
+ from das_setup_helper.data.fs.s3 import S3IOManager
5
+ from das_setup_helper.data.fs.wihp_api import WihpAPIIOManager
6
+ from das_setup_helper.data.io import IOHandler
7
+ from das_setup_helper.shared.constant.s3 import (
8
+ CRAWLER_INFO_ID_KEY,
9
+ CRAWLER_INFO_NAME_KEY,
10
+ CRAWLER_INFO_TIMESTAMP_KEY,
11
+ )
12
+ from das_setup_helper.shared.context import Context
13
+ from das_setup_helper.shared.logger import setup_logger
14
+
15
+ __all__ = ["create_crawler"]
16
+
17
+ logger = setup_logger("setup_crawler", logging.DEBUG)
18
+
19
+
20
+ async def create_crawler():
21
+ """
22
+ Create a new crawler in WIHP.
23
+
24
+ Retrieves validated sources from S3, creates a new crawler in WIHP,
25
+ saves the crawler information back to S3, and returns the crawler details.
26
+
27
+ Returns:
28
+ dict | None: Crawler name, ID, and timestamp, or None if no
29
+ sources found.
30
+ """
31
+ logger.info("Creating a new crawler in WIHP")
32
+ context = Context()
33
+
34
+ s3 = IOHandler(context, S3IOManager(context))
35
+ (
36
+ sources_to_create,
37
+ duplicated_urls,
38
+ null_mne_names,
39
+ non_english_urls,
40
+ long_mne_names,
41
+ ) = s3.get_validated_config()
42
+
43
+ if sources_to_create is None:
44
+ logger.info("No new sources found to create. Exiting crawler creation process.")
45
+ return None
46
+
47
+ wihp_api = IOHandler(context, WihpAPIIOManager(context))
48
+ (
49
+ crawler_name,
50
+ crawler_id,
51
+ crawler_timestamp,
52
+ updated_sources,
53
+ ) = wihp_api.create_crawler(
54
+ sources_to_create,
55
+ )
56
+
57
+ s3.save_crawler_info(
58
+ sources_to_create,
59
+ duplicated_urls,
60
+ null_mne_names,
61
+ non_english_urls,
62
+ long_mne_names,
63
+ crawler_name,
64
+ crawler_id,
65
+ crawler_timestamp,
66
+ updated_sources,
67
+ )
68
+
69
+ crawler_infos = {
70
+ CRAWLER_INFO_NAME_KEY: crawler_name,
71
+ CRAWLER_INFO_ID_KEY: crawler_id,
72
+ CRAWLER_INFO_TIMESTAMP_KEY: crawler_timestamp,
73
+ }
74
+ logger.info(
75
+ f"New Crawler created in WIHP — name: {crawler_name}, "
76
+ f"id: {crawler_id}, timestamp: {crawler_timestamp}"
77
+ )
78
+ return crawler_infos
79
+
80
+
81
+ def main():
82
+ asyncio.run(create_crawler())
83
+
84
+
85
+ if __name__ == "__main__":
86
+ main()
@@ -0,0 +1,46 @@
1
+ import asyncio
2
+ import logging
3
+
4
+ from das_setup_helper.data.fs.wihp_api import WihpAPIIOManager
5
+ from das_setup_helper.data.io import IOHandler
6
+ from das_setup_helper.shared.context import Context
7
+ from das_setup_helper.shared.logger import setup_logger
8
+
9
+ __all__ = ["stopped_acquisitions"]
10
+
11
+ logger = setup_logger("stop_acquisitions", logging.DEBUG)
12
+
13
+
14
+ async def stopped_acquisitions():
15
+ """
16
+ Stop running acquisitions that have a non-DISCOVERED index status.
17
+
18
+ Retrieves running acquisition candidates from the WIHP API, selects those
19
+ whose DAS stats have no discovered URLs, then calls the stop endpoint.
20
+ """
21
+ logger.info("Starting job to stop acquisitions with none 'DISCOVERED' status")
22
+ context = Context()
23
+
24
+ wihp_api = IOHandler(context, WihpAPIIOManager(context))
25
+ running_acquisitions_candidate_to_stop = wihp_api.get_candidates_to_stopped()
26
+
27
+ if not running_acquisitions_candidate_to_stop:
28
+ logger.info("No running acquisitions found to inspect.")
29
+ return
30
+
31
+ running_acquisitions_to_stop = (
32
+ wihp_api.select_acquisitions_to_stop_from_status_counts(
33
+ running_acquisitions_candidate_to_stop,
34
+ )
35
+ )
36
+
37
+ wihp_api.stop_non_discovered_acquisition(running_acquisitions_to_stop)
38
+ logger.info("Succeeded in stopping acquisitions with none 'DISCOVERED' status")
39
+
40
+
41
+ def main():
42
+ asyncio.run(stopped_acquisitions())
43
+
44
+
45
+ if __name__ == "__main__":
46
+ main()
File without changes
File without changes