|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
3 | 3 | import asyncio |
4 | | -import configparser |
5 | | -import copy |
6 | 4 | import inspect |
7 | | -import json |
8 | 5 | import logging |
9 | | -import os |
10 | | -import shutil |
11 | | -from functools import lru_cache, partial |
12 | 6 | from pathlib import Path |
13 | 7 | from queue import Queue |
14 | 8 | from threading import Thread |
15 | | -from typing import Awaitable, Callable, Dict, List, Optional, Tuple, Union |
16 | | -from urllib.parse import ParseResult, urlparse, urlunparse |
| 9 | +from typing import Awaitable, Callable, Optional |
17 | 10 | from uuid import uuid4 |
18 | 11 |
|
19 | | -import requests |
20 | 12 | from werkzeug.utils import secure_filename |
21 | 13 |
|
22 | | -from murfey.util.models import Visit |
23 | | - |
24 | 14 | logger = logging.getLogger("murfey.util") |
25 | 15 |
|
26 | 16 |
|
27 | | -def read_config() -> configparser.ConfigParser: |
28 | | - config = configparser.ConfigParser() |
29 | | - try: |
30 | | - mcch = os.environ.get("MURFEY_CLIENT_CONFIG_HOME") |
31 | | - murfey_client_config_home = Path(mcch) if mcch else Path.home() |
32 | | - with open(murfey_client_config_home / ".murfey") as configfile: |
33 | | - config.read_file(configfile) |
34 | | - except FileNotFoundError: |
35 | | - logger.warning( |
36 | | - f"Murfey client configuration file {murfey_client_config_home / '.murfey'} not found" |
37 | | - ) |
38 | | - if "Murfey" not in config: |
39 | | - config["Murfey"] = {} |
40 | | - return config |
41 | | - |
42 | | - |
43 | | -@lru_cache(maxsize=1) |
44 | | -def get_machine_config_client( |
45 | | - url: str, instrument_name: str = "", demo: bool = False |
46 | | -) -> dict: |
47 | | - _instrument_name: str | None = instrument_name or os.getenv("BEAMLINE") |
48 | | - if not _instrument_name: |
49 | | - return {} |
50 | | - return requests.get(f"{url}/instruments/{_instrument_name}/machine").json() |
51 | | - |
52 | | - |
53 | | -def authorised_requests() -> Tuple[Callable, Callable, Callable, Callable]: |
54 | | - token = read_config()["Murfey"].get("token", "") |
55 | | - _get = partial(requests.get, headers={"Authorization": f"Bearer {token}"}) |
56 | | - _post = partial(requests.post, headers={"Authorization": f"Bearer {token}"}) |
57 | | - _put = partial(requests.put, headers={"Authorization": f"Bearer {token}"}) |
58 | | - _delete = partial(requests.delete, headers={"Authorization": f"Bearer {token}"}) |
59 | | - return _get, _post, _put, _delete |
60 | | - |
61 | | - |
62 | | -requests.get, requests.post, requests.put, requests.delete = authorised_requests() |
63 | | - |
64 | | - |
65 | 17 | def sanitise(in_string: str) -> str: |
66 | 18 | return in_string.replace("\r\n", "").replace("\n", "") |
67 | 19 |
|
@@ -113,106 +65,6 @@ def posix_path(path: Path) -> str: |
113 | 65 | return str(path) |
114 | 66 |
|
115 | 67 |
|
116 | | -def _get_visit_list(api_base: ParseResult, instrument_name: str): |
117 | | - get_visits_url = api_base._replace( |
118 | | - path=f"/instruments/{instrument_name}/visits_raw" |
119 | | - ) |
120 | | - server_reply = requests.get(get_visits_url.geturl()) |
121 | | - if server_reply.status_code != 200: |
122 | | - raise ValueError(f"Server unreachable ({server_reply.status_code})") |
123 | | - return [Visit.parse_obj(v) for v in server_reply.json()] |
124 | | - |
125 | | - |
126 | | -def capture_post(url: str, json: dict | list = {}) -> requests.Response | None: |
127 | | - try: |
128 | | - response = requests.post(url, json=json) |
129 | | - except Exception as e: |
130 | | - logger.error(f"Exception encountered in post to {url}: {e}") |
131 | | - response = requests.Response() |
132 | | - if response.status_code != 200: |
133 | | - logger.warning( |
134 | | - f"Response to post to {url} with data {json} had status code " |
135 | | - f"{response.status_code}. The reason given was {response.reason}" |
136 | | - ) |
137 | | - split_url = urlparse(url) |
138 | | - client_config = read_config() |
139 | | - failure_url = urlunparse( |
140 | | - split_url._replace( |
141 | | - path=f"/instruments/{client_config['Murfey']['instrument_name']}/failed_client_post" |
142 | | - ) |
143 | | - ) |
144 | | - try: |
145 | | - resend_response = requests.post( |
146 | | - failure_url, json={"url": url, "data": json} |
147 | | - ) |
148 | | - except Exception as e: |
149 | | - logger.error(f"Exception encountered in post to {failure_url}: {e}") |
150 | | - resend_response = requests.Response() |
151 | | - if resend_response.status_code != 200: |
152 | | - logger.warning( |
153 | | - f"Response to post to {failure_url} failed with {resend_response.reason}" |
154 | | - ) |
155 | | - |
156 | | - return response |
157 | | - |
158 | | - |
159 | | -def capture_get(url: str) -> requests.Response | None: |
160 | | - try: |
161 | | - response = requests.get(url) |
162 | | - except Exception as e: |
163 | | - logger.error(f"Exception encountered in get from {url}: {e}") |
164 | | - response = None |
165 | | - if response and response.status_code != 200: |
166 | | - logger.warning( |
167 | | - f"Response to get from {url} had status code {response.status_code}. " |
168 | | - f"The reason given was {response.reason}" |
169 | | - ) |
170 | | - return response |
171 | | - |
172 | | - |
173 | | -def set_default_acquisition_output( |
174 | | - new_output_dir: Path, |
175 | | - software_settings_output_directories: Dict[str, List[str]], |
176 | | - safe: bool = True, |
177 | | -): |
178 | | - for p, keys in software_settings_output_directories.items(): |
179 | | - if safe: |
180 | | - settings_copy_path = Path(p) |
181 | | - settings_copy_path = settings_copy_path.parent / ( |
182 | | - "_murfey_" + settings_copy_path.name |
183 | | - ) |
184 | | - shutil.copy(p, str(settings_copy_path)) |
185 | | - with open(p, "r") as for_parsing: |
186 | | - settings = json.load(for_parsing) |
187 | | - # for safety |
188 | | - settings_copy = copy.deepcopy(settings) |
189 | | - |
190 | | - def _set(d: dict, keys_list: List[str], value: str) -> dict: |
191 | | - if len(keys_list) > 1: |
192 | | - tmp_value: Union[dict, str] = _set( |
193 | | - d[keys_list[0]], keys_list[1:], value |
194 | | - ) |
195 | | - else: |
196 | | - tmp_value = value |
197 | | - return {_k: tmp_value if _k == keys_list[0] else _v for _k, _v in d.items()} |
198 | | - |
199 | | - settings_copy = _set(settings_copy, keys, str(new_output_dir)) |
200 | | - |
201 | | - def _check_dict_structure(d1: dict, d2: dict) -> bool: |
202 | | - if set(d1.keys()) != set(d2.keys()): |
203 | | - return False |
204 | | - for k in d1.keys(): |
205 | | - if isinstance(d1[k], dict): |
206 | | - if not isinstance(d2[k], dict): |
207 | | - return False |
208 | | - _check_dict_structure(d1[k], d2[k]) |
209 | | - return True |
210 | | - |
211 | | - if _check_dict_structure(settings, settings_copy): |
212 | | - with open(p, "w") as sf: |
213 | | - json.dump(settings_copy, sf) |
214 | | - |
215 | | - |
216 | 68 | class Observer: |
217 | 69 | """ |
218 | 70 | A helper class implementing the observer pattern supporting both |
|
0 commit comments