Coverage for /Users/rik/github/cgse/libs/cgse-common/src/egse/env.py: 26%

225 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-09-15 11:57 +0200

1""" 

2This module provides functionality to work with and check your environment variables. 

3 

4The module provides functions to get/set the location of the data storage, the configuration data, and the log files. 

5The locations are determined from the environment variables that are set for the project. 

6 

7Two important and mandatory environment variables are PROJECT and SITE_ID. The PROJECT environment variable is 

8used to construct the names of the other environment variables that are specific to the project. The SITE_ID 

9environment variable is used in the value that is returned for some the of project specific environment variables. 

10 

11Mandatory 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 

16The 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 

24Do not use the environment variables directly in your code, but use the functions provided by this module to get the 

25locations and settings. 

26 

27- `get_data_storage_location()`: returns the full path of the data storage location. 

28- `get_conf_data_location()`: returns the full path of the location of the configuration data. 

29- `get_conf_repo_location()`: returns the full path of the location of the configuration data repository. 

30- `get_log_file_location()`: returns the full path of the location of the log files. 

31- `get_local_settings()`: returns the fully qualified filename of the local settings YAML file. 

32 

33!!! warning 

34 

35 These environment variables shall not be changed outside the processes that use them and also not using the 

36 `os.environ` within the code. For the known environment variables, use the dedicated 'setters' that are provided 

37 by this module. If there is a need to change the environment variables, e.g. in unit tests, make sure to call the 

38 `egse.env.initialize()` to reset the proper state. 

39 

40""" 

41 

42from __future__ import annotations 

43 

44__all__ = [ 

45 "env_var", 

46 "get_conf_data_location", 

47 "get_conf_data_location_env_name", 

48 "get_conf_repo_location", 

49 "get_conf_repo_location_env_name", 

50 "get_data_storage_location", 

51 "get_data_storage_location_env_name", 

52 "get_local_settings_path", 

53 "get_local_settings_env_name", 

54 "get_log_file_location", 

55 "get_log_file_location_env_name", 

56 "get_project_name", 

57 "get_site_id", 

58 "set_conf_data_location", 

59 "set_conf_repo_location", 

60 "set_data_storage_location", 

61 "set_local_settings", 

62 "set_log_file_location", 

63] 

64 

65import contextlib 

66import os 

67import warnings 

68from pathlib import Path 

69 

70from egse.log import logger 

71from egse.system import all_logging_disabled 

72from egse.system import get_caller_info 

73from egse.system import ignore_m_warning 

74 

75from rich.console import Console 

76 

77console = Console(width=100) 

78 

79# Every project shall have a PROJECT and a SITE_ID environment variable set. This variable will be used to 

80# create the other environment variables that are specific to the project. 

81 

82MANDATORY_ENVIRONMENT_VARIABLES = [ 

83 "PROJECT", 

84 "SITE_ID", 

85] 

86 

87# The environment variables that are known to be used by the project. These environment variables shall be set 

88# as ${PROJECT}_<variable name>, e.g. PLATO_DATA_STORAGE_LOCATION. For each of these variables, there is a 

89# corresponding function that will return the value of the environment variable. The environment variable is not 

90# mandatory and if not set, a LookupError will be raised. 

91 

92KNOWN_PROJECT_ENVIRONMENT_VARIABLES = [ 

93 "DATA_STORAGE_LOCATION", 

94 "CONF_DATA_LOCATION", 

95 "CONF_REPO_LOCATION", 

96 "LOG_FILE_LOCATION", 

97 "LOCAL_SETTINGS", 

98] 

99 

100 

101def initialize(): 

102 """ 

103 Initialize the environment variables that are required for the CGSE to function properly. 

104 This function will print a warning if any of the mandatory environment variables is not set. 

105 

106 This function is automatically called on import and can be called whenever the environment 

107 variables have been changed, e.g. in unit tests. 

108 """ 

109 

110 global _env 

111 

112 for name in MANDATORY_ENVIRONMENT_VARIABLES: 

113 try: 

114 _env.set(name, os.environ[name]) 

115 except KeyError: 

116 logger.warning( 

117 f"The environment variable {name} is not set. {name} is required to define the project settings and " 

118 f"environment variables. Please set the environment variable {name} before proceeding." 

119 ) 

120 _env.set(name, NoValue()) 

121 

122 project = _env.get("PROJECT") 

123 

124 for gen_var_name in KNOWN_PROJECT_ENVIRONMENT_VARIABLES: 

125 env_var = f"{project}_{gen_var_name}" 

126 _env.set(gen_var_name, os.environ.get(env_var, NoValue())) 

127 

128 

129class _Env: 

130 """Internal class that keeps track of the environment variables.""" 

131 

132 def __init__(self): 

133 self._env = {} 

134 

135 def set(self, key, value): 

136 if value is None: 136 ↛ 137line 136 didn't jump to line 137 because the condition on line 136 was never true

137 if key in self._env: 

138 del self._env[key] 

139 else: 

140 self._env[key] = value 

141 

142 def get(self, key) -> str: 

143 return self._env.get(key, NoValue()) 

144 

145 def __rich__(self): 

146 return self._env 

147 

148 

149_env = _Env() 

150 

151 

152class NoValue: 

153 """ 

154 Represents a no value object, an environment variable that was not set. 

155 

156 The truth value of this object is always False, and it is equal to any other NoValue object. 

157 """ 

158 

159 def __eq__(self, other): 

160 if isinstance(other, NoValue): 

161 return True 

162 return False 

163 

164 def __bool__(self): 

165 return False 

166 

167 def __repr__(self): 

168 return f"{self.__class__.__name__}" 

169 

170 

171# The module needs to be initialized before it can be used. 

172initialize() 

173 

174 

175def _check_no_value(var_name, value): 

176 """Raise a ValueError when the value for the variable is NoValue.""" 

177 if value == NoValue(): 

178 project = _env.get("PROJECT") 

179 env_name = var_name if var_name in ("PROJECT", "SITE_ID") else f"{project}_{var_name}" 

180 raise ValueError( 

181 f"The environment variable {env_name} is not set. Please set the environment variable before proceeding." 

182 ) 

183 

184 

185def set_default_environment( 

186 project: str, 

187 site_id: str, 

188 data_storage_location: str | Path, 

189 conf_data_location: str | Path | None = None, 

190 conf_repo_location: str | Path | None = None, 

191 log_file_location: str | Path | None = None, 

192 local_settings: str | Path | None = None, 

193): 

194 set_project_name(project) 

195 set_site_id(site_id) 

196 set_data_storage_location(data_storage_location) 

197 set_conf_data_location(conf_data_location) 

198 set_conf_repo_location(conf_repo_location) 

199 set_log_file_location(log_file_location) 

200 set_local_settings(local_settings) 

201 

202 

203def get_project_name() -> str: 

204 """Get the PROJECT name. Return None when the PROJECT is not set.""" 

205 return _env.get("PROJECT") or None 

206 

207 

208def set_project_name(name: str): 

209 """Set the environment variable PROJECT and its internal representation.""" 

210 os.environ["PROJECT"] = name 

211 _env.set("PROJECT", name) 

212 

213 

214def get_site_id() -> str: 

215 """Get the SITE_ID. Return None if the SITE_ID is not set.""" 

216 return _env.get("SITE_ID") or None 

217 

218 

219def set_site_id(name: str): 

220 """Set the environment variable SITE_ID and its internal representation.""" 

221 os.environ["SITE_ID"] = name 

222 _env.set("SITE_ID", name) 

223 

224 

225def get_data_storage_location_env_name() -> str: 

226 """Returns the name of the environment variable for the project.""" 

227 project = _env.get("PROJECT") 

228 return f"{project}_DATA_STORAGE_LOCATION" 

229 

230 

231def set_data_storage_location(location: str | Path | None): 

232 """ 

233 Sets the environment variable and the internal representation to the given value. 

234 

235 Warning: 

236 Issues a warning when the given location doesn't exist. 

237 """ 

238 env_name = get_data_storage_location_env_name() 

239 

240 if location is None: 

241 if env_name in os.environ: 

242 del os.environ[env_name] 

243 _env.set("DATA_STORAGE_LOCATION", None) 

244 return 

245 

246 if not Path(location).exists(): 

247 warnings.warn(f"The location you provided for the environment variable {env_name} doesn't exist: {location}.") 

248 

249 os.environ[env_name] = str(location) 

250 _env.set("DATA_STORAGE_LOCATION", str(location)) 

251 

252 

253def get_data_storage_location(site_id: str = None) -> str: 

254 """ 

255 Returns the full path of the data storage location for the given site_id. 

256 

257 If the site_id is None, it is determined from the environment variable SITE_ID. 

258 

259 If the `${PROJECT}_DATA_STORAGE_LOCATION` environment variable does not end with 

260 the site_id, the site_id will be appended to the path on return. That means 

261 the actual data storage location will always be site specific. 

262 

263 Note: 

264 when you specify the `site_id` as an argument, it takes precedence 

265 over the SITE_ID environment variable. 

266 

267 Args: 

268 site_id: the site identifier (to be used instead of the SITE_ID environment variable) 

269 

270 Returns: 

271 The full path of data storage location as a string. 

272 

273 Raises: 

274 ValueError: when the SITE_ID or the ${PROJECT}_DATA_STORAGE_LOCATION is not set. 

275 """ 

276 global _env 

277 

278 project = _env.get("PROJECT") 

279 _check_no_value("PROJECT", project) 

280 

281 site_id = site_id or _env.get("SITE_ID") 

282 _check_no_value("SITE_ID", site_id) 

283 

284 data_root = _env.get("DATA_STORAGE_LOCATION") 

285 _check_no_value("DATA_STORAGE_LOCATION", data_root) 

286 

287 data_root = data_root.rstrip("/") 

288 

289 return data_root if data_root.endswith(site_id) else f"{data_root}/{site_id}" 

290 

291 

292def get_conf_data_location_env_name() -> str: 

293 """Returns the name of the environment variable for the project.""" 

294 project = _env.get("PROJECT") 

295 return f"{project}_CONF_DATA_LOCATION" 

296 

297 

298def set_conf_data_location(location: str | Path | None): 

299 """ 

300 Sets the environment variable and the internal representation to the given value. 

301 

302 Warning: 

303 Issues a warning when the given location doesn't exist. 

304 """ 

305 

306 env_name = get_conf_data_location_env_name() 

307 

308 if location is None: 

309 if env_name in os.environ: 

310 del os.environ[env_name] 

311 _env.set("CONF_DATA_LOCATION", None) 

312 return 

313 

314 if not Path(location).exists(): 

315 warnings.warn(f"The location you provided for the environment variable {env_name} doesn't exist: {location}.") 

316 

317 os.environ[env_name] = location 

318 _env.set("CONF_DATA_LOCATION", location) 

319 

320 

321def get_conf_data_location(site_id: str = None) -> str: 

322 """ 

323 Returns the full path of the location of the configuration data for the site id. 

324 

325 If the site_id is None, it is determined from the environment variable SITE_ID. 

326 

327 When the `${PROJECT}_CONF_DATA_LOCATION` environment variable is not set, the configuration data 

328 location will be the `${PROJECT}_DATA_STORAGE_LOCATION + '/conf'`. 

329 

330 Args: 

331 site_id: the site identifier (to be used instead of the SITE_ID environment variable) 

332 

333 Returns: 

334 The full path of location of the configuration data as a string. 

335 

336 Raises: 

337 ValueError: when the SITE_ID or the `${PROJECT}_DATA_STORAGE_LOCATION` is not set. 

338 """ 

339 

340 conf_data_root = _env.get("CONF_DATA_LOCATION") 

341 

342 if not conf_data_root: 

343 try: 

344 data_root = get_data_storage_location(site_id=site_id) 

345 except ValueError: 

346 raise ValueError( 

347 f"Could not determine the location of the configuration files. " 

348 f"The environment variable {get_conf_data_location_env_name()} is not set and also the " 

349 f"data storage location is unknown." 

350 ) 

351 

352 data_root = data_root.rstrip("/") 

353 conf_data_root = f"{data_root}/conf" 

354 

355 return conf_data_root 

356 

357 

358def get_log_file_location_env_name(): 

359 """Returns the name of the environment variable for the project.""" 

360 project = _env.get("PROJECT") 

361 return f"{project}_LOG_FILE_LOCATION" 

362 

363 

364def set_log_file_location(location: str | Path | None): 

365 """ 

366 Sets the environment variable and the internal representation to the given value. 

367 

368 Warning: 

369 Issues a warning when the given location doesn't exist. 

370 """ 

371 

372 env_name = get_log_file_location_env_name() 

373 

374 if location is None: 

375 if env_name in os.environ: 

376 del os.environ[env_name] 

377 _env.set("LOG_FILE_LOCATION", None) 

378 return 

379 

380 if not Path(location).exists(): 

381 warnings.warn(f"The location you provided for the environment variable {env_name} doesn't exist: {location}.") 

382 

383 os.environ[env_name] = location 

384 _env.set("LOG_FILE_LOCATION", location) 

385 

386 

387def get_log_file_location(site_id: str = None) -> str: 

388 """ 

389 Returns the full path of the location of the log files. The log file location is read from the environment 

390 variable `${PROJECT}_LOG_FILE_LOCATION`. The location shall be independent of any setting that is subject to change. 

391 

392 If the environment variable is not set, a default log file location is created from the data storage location as 

393 follows: `<PROJECT>_DATA_STORAGE_LOCATION/<SITE_ID>/log`. 

394 

395 Args: 

396 site_id: the site identifier 

397 

398 Returns: 

399 The full path of location of the log files as a string. 

400 

401 Raises: 

402 ValueError: when the SITE_ID or the ${PROJECT}_DATA_STORAGE_LOCATION is not set. 

403 

404 """ 

405 

406 log_data_root = _env.get("LOG_FILE_LOCATION") 

407 

408 if not log_data_root: 

409 try: 

410 data_root = get_data_storage_location(site_id=site_id) 

411 except ValueError: 

412 raise ValueError( 

413 f"Could not determine the location of the log files. " 

414 f"The environment variable {get_log_file_location_env_name()} is not set and also the " 

415 f"data storage location is unknown." 

416 ) 

417 data_root = data_root.rstrip("/") 

418 log_data_root = f"{data_root}/log" 

419 

420 return log_data_root 

421 

422 

423def get_local_settings_env_name() -> str: 

424 """Returns the name of the environment variable for the project.""" 

425 project = _env.get("PROJECT") 

426 return f"{project}_LOCAL_SETTINGS" 

427 

428 

429def set_local_settings(path: str | Path | None): 

430 """ 

431 Sets the environment variable and the internal representation to the given value. 

432 

433 When the path is set to None, the environment variable will be unset. 

434 

435 Warning: 

436 Issues a warning when the given path doesn't exist. 

437 """ 

438 

439 env_name = get_local_settings_env_name() 

440 

441 if path is None: 

442 if env_name in os.environ: 

443 del os.environ[env_name] 

444 _env.set("LOCAL_SETTINGS", None) 

445 return 

446 

447 if not Path(path).exists(): 

448 warnings.warn(f"The location you provided for the environment variable {env_name} doesn't exist: {path}.") 

449 

450 os.environ[env_name] = path 

451 _env.set("LOCAL_SETTINGS", path) 

452 

453 

454def get_local_settings_path() -> str or None: 

455 """ 

456 Returns the fully qualified filename of the local settings YAML file. When the local settings environment 

457 variable is not defined or is an empty string, None is returned. 

458 

459 Warning: 

460 The function will generate a warning when 

461 

462 - When the local settings environment variable is not defined, or 

463 - when the path defined by the environment variable doesn't exist. 

464 """ 

465 

466 local_settings = _env.get("LOCAL_SETTINGS") 

467 

468 if not local_settings: 468 ↛ 469line 468 didn't jump to line 469 because the condition on line 468 was never true

469 warnings.warn( 

470 f"The local settings environment variable '{get_local_settings_env_name()}' " 

471 f"is not defined or is an empty string." 

472 ) 

473 return None 

474 

475 if not Path(local_settings).exists(): 475 ↛ 476line 475 didn't jump to line 476 because the condition on line 475 was never true

476 warnings.warn( 

477 f"The local settings path '{local_settings}' doesn't exist. As a result, " 

478 f"the local settings for your project will not be loaded." 

479 ) 

480 

481 return local_settings 

482 

483 

484def has_conf_repo_location() -> bool: 

485 location = _env.get("CONF_REPO_LOCATION") 

486 return True if location in (None, NoValue) else False 

487 

488 

489def get_conf_repo_location_env_name() -> str: 

490 """Returns the name of the environment variable for the project.""" 

491 project = _env.get("PROJECT") 

492 return f"{project}_CONF_REPO_LOCATION" 

493 

494 

495def get_conf_repo_location() -> str | None: 

496 """ 

497 Returns the fully qualified name of the location of the repository with 

498 configuration and calibration data. 

499 

500 Returns None if no environment variable was defined or if the location doesn't exist. 

501 In both cases a Warning is issued. 

502 """ 

503 

504 location = _env.get("CONF_REPO_LOCATION") 

505 

506 if location in (None, NoValue()): 

507 warnings.warn( 

508 f"The environment variable for the configuration data repository is " 

509 f"not defined ({get_conf_repo_location_env_name()})." 

510 ) 

511 return None 

512 

513 if not Path(location).exists(): 

514 warnings.warn(f"The location of the configuration data repository doesn't exist: {location}.") 

515 return None 

516 

517 return location 

518 

519 

520def set_conf_repo_location(location: str | Path | None): 

521 """ 

522 Sets the environment variable and the internal representation to the given value. 

523 

524 When the location is None, the environment variable will be unset and its internal 

525 representation will be NoValue(). 

526 

527 Warning: 

528 Issues a warning when the given location doesn't exist. 

529 """ 

530 

531 env_name = get_conf_repo_location_env_name() 

532 

533 if location is None: 

534 if env_name in os.environ: 

535 del os.environ[env_name] 

536 _env.set("CONF_REPO_LOCATION", None) 

537 return 

538 

539 if not Path(location).exists(): 

540 warnings.warn(f"The location you provided for the environment variable {env_name} doesn't exist: {location}.") 

541 

542 os.environ[env_name] = location 

543 _env.set("CONF_REPO_LOCATION", location) 

544 

545 

546def print_env(): 

547 """ 

548 Prints out the mandatory and known environment variables at the time of the 

549 function call. The function and lineno is also printed for information. 

550 """ 

551 col_width = 30 

552 

553 console = Console(width=200) 

554 

555 with warnings.catch_warnings(): 

556 warnings.simplefilter("ignore") 

557 caller_info = get_caller_info(level=2) 

558 console.print(f"[b]Environment as in {caller_info.filename}:{caller_info.lineno}[/]") 

559 console.print(f" {'PROJECT':{col_width}s}: {get_project_name()}") 

560 console.print(f" {'SITE_ID':{col_width}s}: {get_site_id()}") 

561 console.print(f" {get_data_storage_location_env_name():{col_width}s}: {get_data_storage_location()}") 

562 console.print(f" {get_log_file_location_env_name():{col_width}s}: {get_log_file_location()}") 

563 console.print(f" {get_conf_data_location_env_name():{col_width}s}: {get_conf_data_location()}") 

564 console.print(f" {get_conf_repo_location_env_name():{col_width}s}: {get_conf_repo_location()}") 

565 console.print(f" {get_local_settings_env_name():{col_width}s}: {get_local_settings_path()}") 

566 

567 

568@contextlib.contextmanager 

569def env_var(**kwargs: str | int | float | bool | None): 

570 """ 

571 Context manager to run some code that need alternate settings for environment variables. 

572 This will automatically initialize the CGSE environment upon entry and re-initialize upon exit. 

573 

574 Note: 

575 This context manager is different from the one in `egse.system` because of the CGSE environment changes. 

576 

577 Args: 

578 **kwargs: dictionary with environment variables that are needed 

579 

580 Example: 

581 ```python 

582 from egse.env import env_var 

583 with env_var(PLATO_DATA_STORAGE_LOCATION="/Users/rik/data"): 

584 # do stuff that needs these alternate setting 

585 ... 

586 ``` 

587 

588 """ 

589 saved_env = {} 

590 

591 for k, v in kwargs.items(): 

592 saved_env[k] = os.environ.get(k) 

593 if v is None: 

594 if k in os.environ: 

595 del os.environ[k] 

596 else: 

597 os.environ[k] = v 

598 

599 initialize() 

600 

601 yield 

602 

603 for k, v in saved_env.items(): 

604 if v is None: 

605 if k in os.environ: 

606 del os.environ[k] 

607 else: 

608 os.environ[k] = v 

609 

610 initialize() 

611 

612 

613def main(args: list | None = None): # pragma: no cover 

614 import argparse 

615 import sys 

616 import rich 

617 

618 parser = argparse.ArgumentParser() 

619 parser.add_argument( 

620 "--full", 

621 default=False, 

622 action="store_true", 

623 help="Print a full report on environment variables and paths.", 

624 ) 

625 parser.add_argument( 

626 "--doc", 

627 default=False, 

628 action="store_true", 

629 help="Print help on the environment variables and paths.", 

630 ) 

631 parser.add_argument( 

632 "--mkdir", 

633 default=False, 

634 action="store_true", 

635 help="Create directory that doesn't exist.", 

636 ) 

637 

638 args = parser.parse_args(args or []) 

639 

640 def check_env_dir(env_var: str): 

641 value = _env.get(env_var) 

642 

643 if value == NoValue(): 

644 value = "[bold red]not set" 

645 elif not value.startswith("/"): 

646 value = f"[default]{value} [bold orange3](this is a relative path!)" 

647 elif not os.path.exists(value): 

648 value = f"[default]{value} [bold red](location doesn't exist!)" 

649 elif not os.path.isdir(value): 

650 value = f"[default]{value} [bold red](location is not a directory!)" 

651 else: 

652 value = f"[default]{value}" 

653 return value 

654 

655 def check_env_file(env_var: str): 

656 value = _env.get(env_var) 

657 

658 if not value: 

659 value = "[bold red]not set" 

660 elif not os.path.exists(value): 

661 value = f"[default]{value} [bold red](location doesn't exist!)" 

662 else: 

663 value = f"[default]{value}" 

664 return value 

665 

666 rich.print("Environment variables:") 

667 

668 project = _env.get("PROJECT") 

669 

670 for var in MANDATORY_ENVIRONMENT_VARIABLES: 

671 rich.print(f" {var} = {_env.get(var)}") 

672 for var in KNOWN_PROJECT_ENVIRONMENT_VARIABLES: 

673 if var.endswith("_SETTINGS"): 

674 rich.print(f" {project}_{var} = {check_env_file(var)}") 

675 else: 

676 rich.print(f" {project}_{var} = {check_env_dir(var)}") 

677 

678 rich.print() 

679 rich.print("Generated locations and filenames") 

680 

681 with all_logging_disabled(): 

682 warnings.filterwarnings("ignore", category=UserWarning) 

683 try: 

684 rich.print(f" {get_data_storage_location() = }", flush=True, end="") 

685 location = get_data_storage_location() 

686 if not Path(location).exists(): 

687 if args.mkdir: 

688 rich.print(f" [green]⟶ Creating data storage location: {location} (+ daily + obs)[/]") 

689 Path(location).mkdir(parents=True) 

690 (Path(location) / "daily").mkdir() 

691 (Path(location) / "obs").mkdir() 

692 else: 

693 rich.print(" [red]⟶ ERROR: The data storage location doesn't exist![/]") 

694 else: 

695 rich.print() 

696 except ValueError as exc: 

697 rich.print(f" get_data_storage_location() = [red]{exc}[/]") 

698 

699 try: 

700 rich.print(f" {get_conf_data_location() = }", flush=True, end="") 

701 location = get_conf_data_location() 

702 if not Path(location).exists(): 

703 if args.mkdir: 

704 rich.print(f" [green]⟶ Creating configuration data location: {location}[/]") 

705 Path(location).mkdir(parents=True) 

706 else: 

707 rich.print(" [red]⟶ ERROR: The configuration data location doesn't exist![/]") 

708 else: 

709 rich.print() 

710 except ValueError as exc: 

711 rich.print(f" get_conf_data_location() = [red]{exc}[/]") 

712 

713 try: 

714 rich.print(f" {get_conf_repo_location() = }", flush=True, end="") 

715 location = get_conf_repo_location() 

716 if location is None or not Path(location).exists(): 

717 rich.print(" [red]⟶ ERROR: The configuration repository location doesn't exist![/]") 

718 else: 

719 rich.print() 

720 except ValueError as exc: 

721 rich.print(f" get_conf_repo_location() = [red]{exc}[/]") 

722 

723 try: 

724 rich.print(f" {get_log_file_location() = }", flush=True, end="") 

725 location = get_log_file_location() 

726 if not Path(location).exists(): 

727 if args.mkdir: 

728 rich.print(f" [green]⟶ Creating log files location: {location}[/]") 

729 Path(location).mkdir(parents=True) 

730 else: 

731 rich.print(" [red]⟶ ERROR: The log files location doesn't exist![/]") 

732 else: 

733 rich.print() 

734 except ValueError as exc: 

735 rich.print(f" get_log_file_location() = [red]{exc}[/]") 

736 

737 try: 

738 rich.print(f" {get_local_settings_path() = }", flush=True, end="") 

739 location = get_local_settings_path() 

740 if location is None or not Path(location).exists(): 

741 rich.print(" [red]⟶ ERROR: The local settings file is not defined or doesn't exist![/]") 

742 else: 

743 rich.print() 

744 except ValueError as exc: 

745 rich.print(f" get_local_settings() = [red]{exc}[/]") 

746 

747 if args.full: 

748 rich.print() 

749 rich.print(f" PYTHONPATH=[default]{os.environ.get('PYTHONPATH')}") 

750 rich.print(f" PYTHONSTARTUP=[default]{os.environ.get('PYTHONSTARTUP')}") 

751 rich.print() 

752 python_path_msg = "\n ".join(sys.path) 

753 rich.print(f" sys.path=[\n {python_path_msg}\n ]") 

754 path_msg = "\n ".join(os.environ.get("PATH").split(":")) 

755 rich.print(f" PATH=[\n {path_msg}\n ]") 

756 

757 help_msg = """ 

758[bold]PROJECT_INSTALL_LOCATION[/bold]: 

759 This variable shall point to the location where the CGSE will be installed and is 

760 usually set to `/cgse`. The variable is used by the [blue]update_cgse[/blue] script. 

761 

762[bold]PROJECT_CONF_DATA_LOCATION[/bold]: 

763 This directory is the root folder for all the Setups of the site, the site is part 

764 of the name. By default, this directory is located in the overall data storage folder. 

765 

766[bold]PROJECT_CONF_REPO_LOCATION[/bold]: 

767 This variable is the root of the working copy of the 'plato-cgse-conf' project. 

768 The value is usually set to `~/git/plato-cgse-conf`. 

769 

770[bold]PROJECT_DATA_STORAGE_LOCATION[/bold]: 

771 This directory contains all the data files from the control servers and other 

772 components. This folder is the root folder for all data from all cameras and 

773 all sites. Below this folder shall be a folder for each of the cameras and in 

774 there a sub-folder for each of the sites where that camera was tested. The 

775 hierarchy is therefore: `$PLATO_DATA_STORAGE_LOCATION/<camera name>/<site id>. 

776 Each of those folder shall contain at least the sub-folder [blue]daily[/blue], and [blue]obs[/blue]. 

777 

778 There is also a file called [blue]obsid-table-<site id>.txt[/blue] which is maintained by 

779 the configuration manager and contains information about the observations that 

780 were run and the commands to start those observation. 

781 

782[bold]PROJECT_LOG_FILE_LOCATION[/bold]: 

783 This directory contains the log files with all messages that were sent to the 

784 logger control server. The log files are rotated on a daily basis at midnight UTC. 

785 By default, this directory is also located in the overall data storage folder. 

786 

787[bold]PROJECT_LOCAL_SETTINGS[/bold]: 

788 This file is used for local site-specific settings. When the environment 

789 variable is not set, no local settings will be loaded. By default, this variable 

790 is assumed to be '/cgse/local_settings.yaml'. 

791""" 

792 

793 if args.doc: 

794 rich.print(help_msg) 

795 

796 if not args.full: 

797 rich.print() 

798 rich.print("use the '--full' flag to get a more detailed report, '--doc' for help on the variables.") 

799 

800 # Do we still use these environment variables? 

801 # 

802 # PLATO_WORKDIR 

803 # PLATO_COMMON_EGSE_PATH - YES 

804 

805 

806ignore_m_warning("egse.env") 

807 

808 

809if __name__ == "__main__": 809 ↛ 810line 809 didn't jump to line 810 because the condition on line 809 was never true

810 import sys 

811 

812 main(sys.argv[1:])