cgse-common 2023.1.5__py3-none-any.whl → 2024.1.5__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.
- {cgse_common-2023.1.5.dist-info → cgse_common-2024.1.5.dist-info}/METADATA +28 -25
- cgse_common-2024.1.5.dist-info/RECORD +36 -0
- {cgse_common-2023.1.5.dist-info → cgse_common-2024.1.5.dist-info}/WHEEL +1 -1
- cgse_common-2024.1.5.dist-info/entry_points.txt +2 -0
- egse/bits.py +266 -41
- egse/calibration.py +250 -0
- egse/command.py +10 -29
- egse/config.py +17 -12
- egse/control.py +0 -81
- egse/decorators.py +8 -8
- egse/device.py +3 -1
- egse/env.py +443 -112
- egse/hk.py +794 -0
- egse/metrics.py +106 -0
- egse/resource.py +70 -2
- egse/response.py +101 -0
- egse/settings.py +33 -31
- egse/settings.yaml +0 -974
- egse/setup.py +116 -81
- egse/system.py +32 -13
- cgse_common-2023.1.5.dist-info/RECORD +0 -32
- cgse_common-2023.1.5.dist-info/entry_points.txt +0 -3
egse/env.py
CHANGED
|
@@ -1,139 +1,440 @@
|
|
|
1
1
|
"""
|
|
2
|
-
This module provides functionality to work with and check your
|
|
3
|
-
"""
|
|
4
|
-
from pathlib import Path
|
|
2
|
+
This module provides functionality to work with and check your environment variables.
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
from
|
|
4
|
+
The module provides functions to get/set the location of the data storage, the configuration data, and the log files.
|
|
5
|
+
The locations are determined from the environment variables that are set for the project.
|
|
6
|
+
|
|
7
|
+
Two important and mandatory environment variables are PROJECT and SITE_ID. The PROJECT environment variable is
|
|
8
|
+
used to construct the names of the other environment variables that are specific to the project. The SITE_ID
|
|
9
|
+
environment variable is used in the value that is returned for some the of project specific environment variables.
|
|
10
|
+
|
|
11
|
+
Mandatory environment variables:
|
|
12
|
+
|
|
13
|
+
- PROJECT: the name of the project, e.g. PLATO, ARIEL. [shall be UPPER case]
|
|
14
|
+
- SITE_ID: the site identifier, e.g. the lab name or organisation acronym. [shall be UPPER case]
|
|
15
|
+
|
|
16
|
+
The following environment variables are used by the project:
|
|
17
|
+
|
|
18
|
+
- <PROJECT>_DATA_STORAGE_LOCATION: the root of the data storage location.
|
|
19
|
+
- <PROJECT>_CONF_DATA_LOCATION: the location of the configuration data.
|
|
20
|
+
- <PROJECT>_CONF_REPO_LOCATION: the location of the configuration data GitHub repository.
|
|
21
|
+
- <PROJECT>_LOG_FILE_LOCATION: the location of the log files.
|
|
22
|
+
- <PROJECT>_LOCAL_SETTINGS: the YAML file that contains site specific local settings.
|
|
23
|
+
|
|
24
|
+
Do not use the environment variables directly, but use the functions provided by this module to get the locations.
|
|
8
25
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
ENV_PLATO_LOG_DATA = "PLATO_LOG_FILE_LOCATION"
|
|
15
|
-
ENV_PLATO_LOCAL_SETTINGS = "PLATO_LOCAL_SETTINGS"
|
|
26
|
+
- get_data_storage_location(): returns the full path of the data storage location.
|
|
27
|
+
- get_conf_data_location(): returns the full path of the location of the configuration data.
|
|
28
|
+
- get_conf_repo_location(): returns the full path of the location of the configuration data repository.
|
|
29
|
+
- get_log_file_location(): returns the full path of the location of the log files.
|
|
30
|
+
- get_local_settings(): returns the fully qualified filename of the local settings YAML file.
|
|
16
31
|
|
|
17
|
-
|
|
32
|
+
WARNING:
|
|
33
|
+
|
|
34
|
+
These environment variables shall not be changed outside the processes that use them and also not using the
|
|
35
|
+
`os.environ` within the code. For the known environment variables, use the dedicated 'setters' that are provided
|
|
36
|
+
by this module. If there is a need to change the environment variables, e.g. in unit tests, make sure to call the
|
|
37
|
+
`egse.env.initialize()` to reset the proper state.
|
|
38
|
+
|
|
39
|
+
"""
|
|
40
|
+
from __future__ import annotations
|
|
18
41
|
|
|
19
42
|
__all__ = [
|
|
20
43
|
"get_data_storage_location",
|
|
44
|
+
"set_data_storage_location",
|
|
45
|
+
"get_data_storage_location_env_name",
|
|
21
46
|
"get_conf_data_location",
|
|
47
|
+
"set_conf_data_location",
|
|
48
|
+
"get_conf_data_location_env_name",
|
|
49
|
+
"get_conf_repo_location",
|
|
50
|
+
"set_conf_repo_location",
|
|
51
|
+
"get_conf_repo_location_env_name",
|
|
22
52
|
"get_log_file_location",
|
|
23
|
-
|
|
53
|
+
"set_log_file_location",
|
|
54
|
+
"get_log_file_location_env_name",
|
|
55
|
+
"get_local_settings",
|
|
56
|
+
"set_local_settings",
|
|
57
|
+
"get_local_settings_env_name",
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
import os
|
|
61
|
+
import warnings
|
|
62
|
+
from pathlib import Path
|
|
63
|
+
|
|
64
|
+
from egse.system import all_logging_disabled
|
|
65
|
+
from egse.system import ignore_m_warning
|
|
66
|
+
|
|
67
|
+
# Every project shall have a PROJECT and a SITE_ID environment variable set. This variable will be used to
|
|
68
|
+
# create the other environment variables that are specific to the project.
|
|
69
|
+
|
|
70
|
+
MANDATORY_ENVIRONMENT_VARIABLES = [
|
|
71
|
+
"PROJECT",
|
|
72
|
+
"SITE_ID",
|
|
24
73
|
]
|
|
25
74
|
|
|
75
|
+
# The environment variables that are known to be used by the project. These environment variables shall be set
|
|
76
|
+
# as ${PROJECT}_<variable name>, e.g. PLATO_DATA_STORAGE_LOCATION. For each of these variables, there is a
|
|
77
|
+
# corresponding function that will return the value of the environment variable. The environment variable is not
|
|
78
|
+
# mandatory and if not set, a LookupError will be raised.
|
|
79
|
+
|
|
80
|
+
KNOWN_PROJECT_ENVIRONMENT_VARIABLES = [
|
|
81
|
+
"DATA_STORAGE_LOCATION",
|
|
82
|
+
"CONF_DATA_LOCATION",
|
|
83
|
+
"CONF_REPO_LOCATION",
|
|
84
|
+
"LOG_FILE_LOCATION",
|
|
85
|
+
"LOCAL_SETTINGS",
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def initialize():
|
|
90
|
+
"""
|
|
91
|
+
Initialize the environment variables that are required for the CGSE to function properly.
|
|
92
|
+
This function will print a warning if any of the mandatory environment variables is not set.
|
|
93
|
+
|
|
94
|
+
This function is automatically called on import and can be called whenever the environment
|
|
95
|
+
variables have been changed, e.g. in unit tests.
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
global _env
|
|
99
|
+
|
|
100
|
+
for name in MANDATORY_ENVIRONMENT_VARIABLES:
|
|
101
|
+
try:
|
|
102
|
+
_env.set(name, os.environ[name])
|
|
103
|
+
except KeyError:
|
|
104
|
+
warnings.warn(
|
|
105
|
+
f"The environment variable {name} is not set. {name} is required to define the project settings and "
|
|
106
|
+
f"environment variables. Please set the environment variable {name} before proceeding."
|
|
107
|
+
)
|
|
108
|
+
_env.set(name, NoValue())
|
|
109
|
+
|
|
110
|
+
project = _env.get("PROJECT")
|
|
111
|
+
|
|
112
|
+
for gen_var_name in KNOWN_PROJECT_ENVIRONMENT_VARIABLES:
|
|
113
|
+
env_var = f"{project}_{gen_var_name}"
|
|
114
|
+
_env.set(gen_var_name, os.environ.get(env_var, NoValue()))
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class _Env:
|
|
118
|
+
"""Internal class that keeps track of the environment variables."""
|
|
119
|
+
|
|
120
|
+
def __init__(self):
|
|
121
|
+
self._env = {}
|
|
122
|
+
|
|
123
|
+
def set(self, key, value):
|
|
124
|
+
self._env[key] = value
|
|
125
|
+
|
|
126
|
+
def get(self, key) -> str:
|
|
127
|
+
return self._env.get(key, NoValue())
|
|
26
128
|
|
|
27
|
-
|
|
129
|
+
|
|
130
|
+
_env = _Env()
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class NoValue:
|
|
134
|
+
"""
|
|
135
|
+
Represents a no value object, an environment variable that was not set.
|
|
136
|
+
|
|
137
|
+
The truth value of this object is always False, and it is equal to any other NoValue object.
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
def __eq__(self, other):
|
|
141
|
+
if isinstance(other, NoValue):
|
|
142
|
+
return True
|
|
143
|
+
return False
|
|
144
|
+
|
|
145
|
+
def __bool__(self):
|
|
146
|
+
return False
|
|
147
|
+
|
|
148
|
+
def __repr__(self):
|
|
149
|
+
return f"{self.__class__.__name__}"
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
# The module needs to be initialized before it can be used.
|
|
153
|
+
initialize()
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def _check_no_value(var_name, value):
|
|
157
|
+
"""Raise a ValueError when the value for the variable is NoValue."""
|
|
158
|
+
if value == NoValue():
|
|
159
|
+
project = _env.get("PROJECT")
|
|
160
|
+
env_name = var_name if var_name == "SITE_ID" else f"{project}_{var_name}"
|
|
161
|
+
raise ValueError(
|
|
162
|
+
f"The environment variable {env_name} is not set. "
|
|
163
|
+
f"Please set the environment variable before proceeding."
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def get_data_storage_location_env_name() -> str:
|
|
168
|
+
"""Returns the name of the environment variable for the project."""
|
|
169
|
+
project = _env.get("PROJECT")
|
|
170
|
+
return f"{project}_DATA_STORAGE_LOCATION"
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def set_data_storage_location(location: str | Path):
|
|
174
|
+
"""
|
|
175
|
+
Sets the environment variable and the internal representation to the given value.
|
|
176
|
+
|
|
177
|
+
Warnings:
|
|
178
|
+
Issues a warning when the given location doesn't exist.
|
|
28
179
|
"""
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
180
|
+
env_name = get_data_storage_location_env_name()
|
|
181
|
+
|
|
182
|
+
# Check if location exists and is readable
|
|
183
|
+
if not Path(location).exists():
|
|
184
|
+
warnings.warn(
|
|
185
|
+
f"The location you provided for the environment variable {env_name} doesn't exist: {location}."
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
os.environ[env_name] = location
|
|
189
|
+
_env.set('DATA_STORAGE_LOCATION', location)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def get_data_storage_location(site_id: str = None) -> str:
|
|
193
|
+
"""
|
|
194
|
+
Returns the full path of the data storage location for the given site_id.
|
|
195
|
+
|
|
196
|
+
If the site_id is None, it is determined from the environment variable SITE_ID.
|
|
197
|
+
|
|
198
|
+
If the ${PROJECT}_DATA_STORAGE_LOCATION environment variable does not end with
|
|
199
|
+
the site_id, the site_id will be appended to the path on return. That means
|
|
200
|
+
the actual data storage location will always be site specific.
|
|
32
201
|
|
|
33
202
|
Note: when you specify the `site_id` as an argument, it takes precedence
|
|
34
|
-
over the
|
|
203
|
+
over the SITE_ID environment variable.
|
|
35
204
|
|
|
36
205
|
Args:
|
|
37
|
-
|
|
38
|
-
site_id: the site identifier (to be used instead of the site_id in the Setup)
|
|
206
|
+
site_id: the site identifier (to be used instead of the SITE_ID environment variable)
|
|
39
207
|
|
|
40
208
|
Returns:
|
|
41
209
|
The full path of data storage location as a string.
|
|
42
210
|
|
|
43
211
|
Raises:
|
|
44
|
-
A ValueError when
|
|
212
|
+
A ValueError when the SITE_ID or the ${PROJECT}_DATA_STORAGE_LOCATION is not set.
|
|
45
213
|
"""
|
|
214
|
+
global _env
|
|
46
215
|
|
|
47
|
-
|
|
216
|
+
site_id = site_id or _env.get("SITE_ID")
|
|
217
|
+
_check_no_value("SITE_ID", site_id)
|
|
48
218
|
|
|
49
|
-
|
|
219
|
+
data_root = _env.get("DATA_STORAGE_LOCATION")
|
|
220
|
+
_check_no_value("DATA_STORAGE_LOCATION", data_root)
|
|
50
221
|
|
|
51
|
-
|
|
222
|
+
data_root = data_root.rstrip('/')
|
|
52
223
|
|
|
53
|
-
if site_id
|
|
224
|
+
return data_root if data_root.endswith(site_id) else f"{data_root}/{site_id}"
|
|
54
225
|
|
|
55
|
-
from egse.setup import Setup
|
|
56
|
-
from egse.state import GlobalState
|
|
57
|
-
setup: Setup = setup or GlobalState.setup
|
|
58
226
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
227
|
+
def get_conf_data_location_env_name() -> str:
|
|
228
|
+
"""Returns the name of the environment variable for the project."""
|
|
229
|
+
project = _env.get("PROJECT")
|
|
230
|
+
return f"{project}_CONF_DATA_LOCATION"
|
|
63
231
|
|
|
64
|
-
site = setup.site_id
|
|
65
|
-
else:
|
|
66
|
-
site = site_id
|
|
67
232
|
|
|
68
|
-
|
|
69
|
-
|
|
233
|
+
def set_conf_data_location(location: str | Path):
|
|
234
|
+
"""
|
|
235
|
+
Sets the environment variable and the internal representation to the given value.
|
|
236
|
+
|
|
237
|
+
Warnings:
|
|
238
|
+
Issues a warning when the given location doesn't exist.
|
|
239
|
+
"""
|
|
240
|
+
|
|
241
|
+
env_name = get_conf_data_location_env_name()
|
|
70
242
|
|
|
71
|
-
|
|
243
|
+
# Check if location exists and is readable
|
|
244
|
+
if not Path(location).exists():
|
|
245
|
+
warnings.warn(
|
|
246
|
+
f"The location you provided for the environment variable {env_name} doesn't exist: {location}."
|
|
247
|
+
)
|
|
72
248
|
|
|
249
|
+
os.environ[env_name] = location
|
|
250
|
+
_env.set('CONF_DATA_LOCATION', location)
|
|
73
251
|
|
|
74
|
-
|
|
252
|
+
|
|
253
|
+
def get_conf_data_location(site_id: str = None) -> str:
|
|
75
254
|
"""
|
|
76
|
-
Returns the full path of the location of the
|
|
77
|
-
|
|
255
|
+
Returns the full path of the location of the configuration data for the Site.
|
|
256
|
+
|
|
257
|
+
If the site_id is None, it is determined from the environment variable SITE_ID.
|
|
258
|
+
|
|
259
|
+
When the ${PROJECT}_CONF_DATA_LOCATION environment variable is not set, the configuration data
|
|
260
|
+
location will be the ${PROJECT}_DATA_STORAGE_LOCATION + '/conf'.
|
|
78
261
|
|
|
79
262
|
Args:
|
|
80
|
-
|
|
263
|
+
site_id: the site identifier (to be used instead of the SITE_ID environment variable)
|
|
81
264
|
|
|
82
265
|
Returns:
|
|
83
|
-
The full path of location of the
|
|
266
|
+
The full path of location of the configuration data as a string.
|
|
84
267
|
|
|
85
268
|
Raises:
|
|
86
|
-
A ValueError when
|
|
269
|
+
A ValueError when the SITE_ID or the ${PROJECT}_DATA_STORAGE_LOCATION is not set.
|
|
270
|
+
"""
|
|
271
|
+
|
|
272
|
+
conf_data_root = _env.get("CONF_DATA_LOCATION")
|
|
273
|
+
|
|
274
|
+
if not conf_data_root:
|
|
275
|
+
try:
|
|
276
|
+
data_root = get_data_storage_location(site_id=site_id)
|
|
277
|
+
except ValueError:
|
|
278
|
+
raise ValueError(
|
|
279
|
+
f"Could not determine the location of the configuration files. "
|
|
280
|
+
f"The environment variable {get_conf_data_location_env_name()} is not set and also the "
|
|
281
|
+
f"data storage location is unknown."
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
data_root = data_root.rstrip('/')
|
|
285
|
+
conf_data_root = f"{data_root}/conf"
|
|
286
|
+
|
|
287
|
+
return conf_data_root
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def get_log_file_location_env_name():
|
|
291
|
+
"""Returns the name of the environment variable for the project."""
|
|
292
|
+
project = _env.get("PROJECT")
|
|
293
|
+
return f"{project}_LOG_FILE_LOCATION"
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def set_log_file_location(location: str | Path):
|
|
87
297
|
"""
|
|
298
|
+
Sets the environment variable and the internal representation to the given value.
|
|
299
|
+
|
|
300
|
+
Warnings:
|
|
301
|
+
Issues a warning when the given location doesn't exist.
|
|
302
|
+
"""
|
|
303
|
+
|
|
304
|
+
env_name = get_log_file_location_env_name()
|
|
88
305
|
|
|
89
|
-
|
|
306
|
+
# Check if location exists and is readable
|
|
307
|
+
if not Path(location).exists():
|
|
308
|
+
warnings.warn(
|
|
309
|
+
f"The location you provided for the environment variable {env_name} doesn't exist: {location}."
|
|
310
|
+
)
|
|
90
311
|
|
|
91
|
-
|
|
312
|
+
os.environ[env_name] = location
|
|
313
|
+
_env.set('LOG_FILE_LOCATION', location)
|
|
92
314
|
|
|
93
315
|
|
|
94
|
-
def get_log_file_location() -> str:
|
|
316
|
+
def get_log_file_location(site_id: str = None) -> str:
|
|
95
317
|
"""
|
|
96
318
|
Returns the full path of the location of the log files. The log file location is read from the environment
|
|
97
|
-
variable
|
|
98
|
-
setting that is subject to change.
|
|
319
|
+
variable ${PROJECT}_LOG_FILE_LOCATION. The location shall be independent of any setting that is subject to change.
|
|
99
320
|
|
|
100
321
|
If the environment variable is not set, a default log file location is created from the data storage location as
|
|
101
|
-
follows:
|
|
322
|
+
follows: <PROJECT>_DATA_STORAGE_LOCATION/<SITE_ID>/log.
|
|
323
|
+
|
|
324
|
+
Args:
|
|
325
|
+
site_id: the site identifier
|
|
102
326
|
|
|
103
327
|
Returns:
|
|
104
328
|
The full path of location of the log files as a string.
|
|
105
|
-
"""
|
|
106
329
|
|
|
107
|
-
|
|
108
|
-
|
|
330
|
+
Raises:
|
|
331
|
+
A ValueError when the SITE_ID or the ${PROJECT}_DATA_STORAGE_LOCATION is not set.
|
|
332
|
+
|
|
333
|
+
"""
|
|
109
334
|
|
|
110
|
-
|
|
335
|
+
log_data_root = _env.get("LOG_FILE_LOCATION")
|
|
111
336
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
337
|
+
if not log_data_root:
|
|
338
|
+
try:
|
|
339
|
+
data_root = get_data_storage_location(site_id=site_id)
|
|
340
|
+
except ValueError:
|
|
341
|
+
raise ValueError(
|
|
342
|
+
f"Could not determine the location of the log files. "
|
|
343
|
+
f"The environment variable {get_log_file_location_env_name()} is not set and also the "
|
|
344
|
+
f"data storage location is unknown."
|
|
345
|
+
)
|
|
116
346
|
data_root = data_root.rstrip('/')
|
|
347
|
+
log_data_root = f"{data_root}/log"
|
|
117
348
|
|
|
118
|
-
|
|
119
|
-
site = get_site_id()
|
|
349
|
+
return log_data_root
|
|
120
350
|
|
|
121
|
-
log_data_root = f"{data_root}/{site}/log"
|
|
122
351
|
|
|
123
|
-
|
|
352
|
+
def get_local_settings_env_name() -> str:
|
|
353
|
+
"""Returns the name of the environment variable for the project."""
|
|
354
|
+
project = _env.get("PROJECT")
|
|
355
|
+
return f"{project}_LOCAL_SETTINGS"
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def set_local_settings(path: str | Path):
|
|
359
|
+
"""
|
|
360
|
+
Sets the environment variable and the internal representation to the given value.
|
|
361
|
+
|
|
362
|
+
Warnings:
|
|
363
|
+
Issues a warning when the given path doesn't exist.
|
|
364
|
+
"""
|
|
365
|
+
|
|
366
|
+
env_name = get_local_settings_env_name()
|
|
367
|
+
|
|
368
|
+
# Check if location exists and is readable
|
|
369
|
+
if not Path(path).exists():
|
|
370
|
+
warnings.warn(
|
|
371
|
+
f"The location you provided for the environment variable {env_name} doesn't exist: {path}."
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
os.environ[env_name] = path
|
|
375
|
+
_env.set('LOCAL_SETTINGS', path)
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
def get_local_settings() -> str:
|
|
379
|
+
"""Returns the fully qualified filename of the local settings YAML file."""
|
|
380
|
+
|
|
381
|
+
local_settings = _env.get("LOCAL_SETTINGS")
|
|
382
|
+
|
|
383
|
+
if local_settings and not Path(local_settings).exists():
|
|
384
|
+
warnings.warn(
|
|
385
|
+
f"The local settings '{local_settings}' doesn't exist. As a result, "
|
|
386
|
+
f"the local settings for your project will not be loaded."
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
return local_settings or None
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def get_conf_repo_location_env_name() -> str:
|
|
393
|
+
"""Returns the name of the environment variable for the project."""
|
|
394
|
+
project = _env.get("PROJECT")
|
|
395
|
+
return f"{project}_CONF_REPO_LOCATION"
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
def get_conf_repo_location() -> str:
|
|
399
|
+
"""Returns the fully qualified name of the location of the repository with configuration and calibration data."""
|
|
400
|
+
|
|
401
|
+
location = _env.get("CONF_REPO_LOCATION")
|
|
402
|
+
|
|
403
|
+
if location and not Path(location).exists():
|
|
404
|
+
warnings.warn(f"The location of the configuration data repository doesn't exist: {location}.")
|
|
405
|
+
|
|
406
|
+
return location or None
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
def set_conf_repo_location(location: str):
|
|
410
|
+
"""
|
|
411
|
+
Sets the environment variable and the internal representation to the given value.
|
|
412
|
+
|
|
413
|
+
Warnings:
|
|
414
|
+
Issues a warning when the given location doesn't exist.
|
|
415
|
+
"""
|
|
416
|
+
|
|
417
|
+
env_name = get_conf_repo_location_env_name()
|
|
418
|
+
|
|
419
|
+
# Check if location exists and is readable
|
|
420
|
+
if not Path(location).exists():
|
|
421
|
+
warnings.warn(
|
|
422
|
+
f"The location you provided for the environment variable {env_name} doesn't exist: {location}."
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
os.environ[env_name] = location
|
|
426
|
+
_env.set('CONF_REPO_LOCATION', location)
|
|
124
427
|
|
|
125
428
|
|
|
126
429
|
ignore_m_warning('egse.env')
|
|
127
430
|
|
|
128
|
-
|
|
431
|
+
|
|
432
|
+
def main(args: list | None = None): # pragma: no cover
|
|
129
433
|
|
|
130
434
|
import argparse
|
|
131
|
-
import os
|
|
132
435
|
import sys
|
|
133
436
|
import rich
|
|
134
437
|
|
|
135
|
-
from egse.config import get_common_egse_root
|
|
136
|
-
|
|
137
438
|
parser = argparse.ArgumentParser()
|
|
138
439
|
parser.add_argument(
|
|
139
440
|
"--full",
|
|
@@ -147,14 +448,20 @@ if __name__ == "__main__":
|
|
|
147
448
|
action="store_true",
|
|
148
449
|
help="Print help on the environment variables and paths.",
|
|
149
450
|
)
|
|
451
|
+
parser.add_argument(
|
|
452
|
+
"--mkdir",
|
|
453
|
+
default=False,
|
|
454
|
+
action="store_true",
|
|
455
|
+
help="Create directory that doesn't exist.",
|
|
456
|
+
)
|
|
150
457
|
|
|
151
|
-
args = parser.parse_args()
|
|
458
|
+
args = parser.parse_args(args or [])
|
|
152
459
|
|
|
153
460
|
def check_env_dir(env_var: str):
|
|
154
461
|
|
|
155
|
-
value =
|
|
462
|
+
value = _env.get(env_var)
|
|
156
463
|
|
|
157
|
-
if value
|
|
464
|
+
if value == NoValue():
|
|
158
465
|
value = "[bold red]not set"
|
|
159
466
|
elif not value.startswith('/'):
|
|
160
467
|
value = f"[default]{value} [bold orange3](this is a relative path!)"
|
|
@@ -166,12 +473,11 @@ if __name__ == "__main__":
|
|
|
166
473
|
value = f"[default]{value}"
|
|
167
474
|
return value
|
|
168
475
|
|
|
169
|
-
|
|
170
476
|
def check_env_file(env_var: str):
|
|
171
477
|
|
|
172
|
-
value =
|
|
478
|
+
value = _env.get(env_var)
|
|
173
479
|
|
|
174
|
-
if value
|
|
480
|
+
if not value:
|
|
175
481
|
value = "[bold red]not set"
|
|
176
482
|
elif not os.path.exists(value):
|
|
177
483
|
value = f"[default]{value} [bold red](location doesn't exist!)"
|
|
@@ -181,48 +487,73 @@ if __name__ == "__main__":
|
|
|
181
487
|
|
|
182
488
|
rich.print("Environment variables:")
|
|
183
489
|
|
|
184
|
-
|
|
490
|
+
project = _env.get("PROJECT")
|
|
491
|
+
|
|
492
|
+
for var in MANDATORY_ENVIRONMENT_VARIABLES:
|
|
493
|
+
rich.print(f" {var} = {_env.get(var)}")
|
|
494
|
+
for var in KNOWN_PROJECT_ENVIRONMENT_VARIABLES:
|
|
185
495
|
if var.endswith("_SETTINGS"):
|
|
186
|
-
rich.print(f" {var} = {check_env_file(var)}")
|
|
496
|
+
rich.print(f" {project}_{var} = {check_env_file(var)}")
|
|
187
497
|
else:
|
|
188
|
-
rich.print(f" {var} = {check_env_dir(var)}")
|
|
498
|
+
rich.print(f" {project}_{var} = {check_env_dir(var)}")
|
|
189
499
|
|
|
190
500
|
rich.print()
|
|
191
501
|
rich.print("Generated locations and filenames")
|
|
192
502
|
|
|
193
503
|
with all_logging_disabled():
|
|
504
|
+
warnings.filterwarnings("ignore", category=UserWarning)
|
|
194
505
|
try:
|
|
195
|
-
rich.print(f" {
|
|
196
|
-
location = get_common_egse_root()
|
|
197
|
-
if not Path(location).exists():
|
|
198
|
-
rich.print("[red]ERROR: The generated Common-EGSE location doesn't exist![/]")
|
|
199
|
-
except ValueError as exc:
|
|
200
|
-
rich.print(f" get_common_egse_path() = [red]{exc}[/]")
|
|
201
|
-
|
|
202
|
-
try:
|
|
203
|
-
rich.print(f" {get_data_storage_location() = }", flush=True)
|
|
506
|
+
rich.print(f" {get_data_storage_location() = }", flush=True, end="")
|
|
204
507
|
location = get_data_storage_location()
|
|
205
508
|
if not Path(location).exists():
|
|
206
|
-
|
|
509
|
+
if args.mkdir:
|
|
510
|
+
rich.print(f" [green]⟶ Creating data storage location: {location}[/]")
|
|
511
|
+
Path(location).mkdir(parents=True)
|
|
512
|
+
else:
|
|
513
|
+
rich.print(" [red]⟶ ERROR: The data storage location doesn't exist![/]")
|
|
514
|
+
else:
|
|
515
|
+
rich.print()
|
|
207
516
|
except ValueError as exc:
|
|
208
517
|
rich.print(f" get_data_storage_location() = [red]{exc}[/]")
|
|
209
518
|
|
|
210
519
|
try:
|
|
211
|
-
rich.print(f" {get_conf_data_location() = }", flush=True)
|
|
520
|
+
rich.print(f" {get_conf_data_location() = }", flush=True, end="")
|
|
212
521
|
location = get_conf_data_location()
|
|
213
522
|
if not Path(location).exists():
|
|
214
|
-
|
|
523
|
+
if args.mkdir:
|
|
524
|
+
rich.print(f" [green]⟶ Creating configuration data location: {location}[/]")
|
|
525
|
+
Path(location).mkdir(parents=True)
|
|
526
|
+
else:
|
|
527
|
+
rich.print(" [red]⟶ ERROR: The configuration data location doesn't exist![/]")
|
|
528
|
+
else:
|
|
529
|
+
rich.print()
|
|
215
530
|
except ValueError as exc:
|
|
216
531
|
rich.print(f" get_conf_data_location() = [red]{exc}[/]")
|
|
217
532
|
|
|
218
533
|
try:
|
|
219
|
-
rich.print(f" {get_log_file_location() = }", flush=True)
|
|
534
|
+
rich.print(f" {get_log_file_location() = }", flush=True, end="")
|
|
220
535
|
location = get_log_file_location()
|
|
221
536
|
if not Path(location).exists():
|
|
222
|
-
|
|
537
|
+
if args.mkdir:
|
|
538
|
+
rich.print(f" [green]⟶ Creating log files location: {location}[/]")
|
|
539
|
+
Path(location).mkdir(parents=True)
|
|
540
|
+
else:
|
|
541
|
+
rich.print(" [red]⟶ ERROR: The log files location doesn't exist![/]")
|
|
542
|
+
else:
|
|
543
|
+
rich.print()
|
|
223
544
|
except ValueError as exc:
|
|
224
545
|
rich.print(f" get_log_file_location() = [red]{exc}[/]")
|
|
225
546
|
|
|
547
|
+
try:
|
|
548
|
+
rich.print(f" {get_local_settings() = }", flush=True, end="")
|
|
549
|
+
location = get_local_settings()
|
|
550
|
+
if location is None or not Path(location).exists():
|
|
551
|
+
rich.print(" [red]⟶ ERROR: The local settings file is not defined or doesn't exist![/]")
|
|
552
|
+
else:
|
|
553
|
+
rich.print()
|
|
554
|
+
except ValueError as exc:
|
|
555
|
+
rich.print(f" get_local_settings() = [red]{exc}[/]")
|
|
556
|
+
|
|
226
557
|
if args.full:
|
|
227
558
|
rich.print()
|
|
228
559
|
rich.print(f" PYTHONPATH=[default]{os.environ.get('PYTHONPATH')}")
|
|
@@ -233,43 +564,38 @@ if __name__ == "__main__":
|
|
|
233
564
|
path_msg = "\n ".join(os.environ.get("PATH").split(":"))
|
|
234
565
|
rich.print(f" PATH=[\n {path_msg}\n ]")
|
|
235
566
|
|
|
236
|
-
help_msg =
|
|
237
|
-
[bold]
|
|
238
|
-
This variable
|
|
239
|
-
project. Its value is usually '~/git/plato-common-egse' which is considered the default
|
|
240
|
-
location.
|
|
241
|
-
|
|
242
|
-
[bold]{ENV_PLATO_INSTALL}[/bold]:
|
|
243
|
-
This variable shall point to the location where the CGSE will be installed and is
|
|
567
|
+
help_msg = """
|
|
568
|
+
[bold]PROJECT_INSTALL_LOCATION[/bold]:
|
|
569
|
+
This variable shall point to the location where the CGSE will be installed and is
|
|
244
570
|
usually set to `/cgse`. The variable is used by the [blue]update_cgse[/blue] script.
|
|
245
571
|
|
|
246
|
-
[bold]
|
|
572
|
+
[bold]PROJECT_CONF_DATA_LOCATION[/bold]:
|
|
247
573
|
This directory is the root folder for all the Setups of the site, the site is part
|
|
248
574
|
of the name. By default, this directory is located in the overall data storage folder.
|
|
249
575
|
|
|
250
|
-
[bold]
|
|
251
|
-
This variable is the root of the working copy of the 'plato-cgse-conf' project.
|
|
576
|
+
[bold]PROJECT_CONF_REPO_LOCATION[/bold]:
|
|
577
|
+
This variable is the root of the working copy of the 'plato-cgse-conf' project.
|
|
252
578
|
The value is usually set to `~/git/plato-cgse-conf`.
|
|
253
579
|
|
|
254
|
-
[bold]
|
|
580
|
+
[bold]PROJECT_DATA_STORAGE_LOCATION[/bold]:
|
|
255
581
|
This directory contains all the data files from the control servers and other
|
|
256
|
-
components. This folder is the root folder for all data from all cameras and
|
|
257
|
-
all sites. Below this folder shall be a folder for each of the cameras and in
|
|
258
|
-
there a sub-folder for each of the sites where that camera was tested. The
|
|
582
|
+
components. This folder is the root folder for all data from all cameras and
|
|
583
|
+
all sites. Below this folder shall be a folder for each of the cameras and in
|
|
584
|
+
there a sub-folder for each of the sites where that camera was tested. The
|
|
259
585
|
hierarchy is therefore: `$PLATO_DATA_STORAGE_LOCATION/<camera name>/<site id>.
|
|
260
|
-
Each of those folder shall contain at least the sub-folder [blue]daily[/blue], and [blue]obs[/blue].
|
|
261
|
-
|
|
262
|
-
There is also a file called [blue]obsid-table-<site id>.txt[/blue] which is maintained by
|
|
586
|
+
Each of those folder shall contain at least the sub-folder [blue]daily[/blue], and [blue]obs[/blue].
|
|
587
|
+
|
|
588
|
+
There is also a file called [blue]obsid-table-<site id>.txt[/blue] which is maintained by
|
|
263
589
|
the configuration manager and contains information about the observations that
|
|
264
590
|
were run and the commands to start those observation.
|
|
265
591
|
|
|
266
|
-
[bold]
|
|
267
|
-
This directory contains the log files with all messages that were sent to the
|
|
592
|
+
[bold]PROJECT_LOG_FILE_LOCATION[/bold]:
|
|
593
|
+
This directory contains the log files with all messages that were sent to the
|
|
268
594
|
logger control server. The log files are rotated on a daily basis at midnight UTC.
|
|
269
595
|
By default, this directory is also located in the overall data storage folder.
|
|
270
596
|
|
|
271
|
-
[bold]
|
|
272
|
-
This file is used for local site-specific settings. When the environment
|
|
597
|
+
[bold]PROJECT_LOCAL_SETTINGS[/bold]:
|
|
598
|
+
This file is used for local site-specific settings. When the environment
|
|
273
599
|
variable is not set, no local settings will be loaded. By default, this variable
|
|
274
600
|
is assumed to be '/cgse/local_settings.yaml'.
|
|
275
601
|
"""
|
|
@@ -285,3 +611,8 @@ if __name__ == "__main__":
|
|
|
285
611
|
#
|
|
286
612
|
# PLATO_WORKDIR
|
|
287
613
|
# PLATO_COMMON_EGSE_PATH - YES
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
if __name__ == "__main__":
|
|
617
|
+
import sys
|
|
618
|
+
main(sys.argv[1:])
|