cgse-common 2025.0.4__py3-none-any.whl → 2025.0.6__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.
egse/setup.py CHANGED
@@ -120,6 +120,7 @@ import logging
120
120
  import os
121
121
  import re
122
122
  import textwrap
123
+ import warnings
123
124
  from functools import lru_cache
124
125
  from pathlib import Path
125
126
  from typing import Any
@@ -130,11 +131,14 @@ import rich
130
131
  import yaml
131
132
  from rich.tree import Tree
132
133
 
134
+ from egse.env import get_conf_data_location
133
135
  from egse.env import get_conf_repo_location
134
136
  from egse.env import get_conf_repo_location_env_name
135
137
  from egse.env import get_data_storage_location
138
+ from egse.env import has_conf_repo_location
139
+ from egse.env import print_env
136
140
  from egse.response import Failure
137
- from egse.env import get_conf_data_location
141
+ from egse.settings import read_configuration_file
138
142
  from egse.system import format_datetime
139
143
  from egse.system import sanity_check
140
144
  from egse.system import walk_dict_tree
@@ -218,8 +222,8 @@ def _load_yaml(resource_name: str):
218
222
  [in_dir, fn] = parts if len(parts) > 1 else [None, parts[0]]
219
223
  conf_location = get_conf_data_location()
220
224
  try:
221
- yaml_location = Path(conf_location) / in_dir / fn
222
- content = NavigableDict(Settings.load(filename=yaml_location, add_local_settings=False))
225
+ yaml_location = Path(conf_location) / in_dir
226
+ content = NavigableDict(Settings.load(location=yaml_location, filename=fn, add_local_settings=False))
223
227
  except (TypeError, SettingsError) as exc:
224
228
  raise ValueError(
225
229
  f"Couldn't load resource '{resource_name}' from default {conf_location=}") from exc
@@ -227,7 +231,11 @@ def _load_yaml(resource_name: str):
227
231
 
228
232
 
229
233
  def _load_pandas(resource_name: str, separator: str):
230
- """ Find and return the content of the given files as a pandas DataFrame object.
234
+ """
235
+ Find and return the content of the given file as a pandas DataFrame object.
236
+
237
+ The file is loaded relative from the location of the configuration data
238
+ as defined by `get_conf_data_location()`.
231
239
 
232
240
  Args:
233
241
  - resource_name: Filename, preceded by "pandas//".
@@ -336,7 +344,7 @@ class NavigableDict(dict):
336
344
 
337
345
  """
338
346
 
339
- def __init__(self, head: dict = None):
347
+ def __init__(self, head: dict = None, label: str = None):
340
348
  """
341
349
  Args:
342
350
  head (dict): the original dictionary
@@ -344,6 +352,7 @@ class NavigableDict(dict):
344
352
  head = head or {}
345
353
  super().__init__(head)
346
354
  self.__dict__["_memoized"] = {}
355
+ self.__dict__["_label"] = label
347
356
 
348
357
  # By agreement, we only want the keys to be set as attributes if all keys are strings.
349
358
  # That way we enforce that always all keys are navigable, or none.
@@ -572,7 +581,7 @@ class NavigableDict(dict):
572
581
  return msg
573
582
 
574
583
  def __rich__(self) -> Tree:
575
- tree = Tree("NavigableDict", guide_style="dim")
584
+ tree = Tree(self.__dict__["_label"] or "NavigableDict", guide_style="dim")
576
585
  walk_dict_tree(self, tree, text_style="dark grey")
577
586
  return tree
578
587
 
@@ -636,8 +645,8 @@ class Setup(NavigableDict):
636
645
  """The Setup class represents a version of the configuration of the test facility, the
637
646
  test setup and the Camera Under Test (CUT)."""
638
647
 
639
- def __init__(self, nav_dict: NavigableDict | dict = None):
640
- super().__init__(nav_dict or {})
648
+ def __init__(self, nav_dict: NavigableDict | dict = None, label: str = None):
649
+ super().__init__(nav_dict or {}, label=label)
641
650
 
642
651
  @staticmethod
643
652
  def from_dict(my_dict):
@@ -651,7 +660,7 @@ class Setup(NavigableDict):
651
660
  >>> assert setup["ID"] == setup.ID == "my-setup-001"
652
661
 
653
662
  """
654
- return Setup(my_dict)
663
+ return Setup(my_dict, label="Setup")
655
664
 
656
665
  @staticmethod
657
666
  def from_yaml_string(yaml_content: str = None):
@@ -674,27 +683,36 @@ class Setup(NavigableDict):
674
683
  if "Setup" in setup_dict:
675
684
  setup_dict = setup_dict["Setup"]
676
685
 
677
- return Setup(setup_dict)
686
+ return Setup(setup_dict, label="Setup")
678
687
 
679
688
  @staticmethod
680
689
  @lru_cache
681
- def from_yaml_file(filename: Union[str, Path] = None):
690
+ def from_yaml_file(filename: Union[str, Path] = None, add_local_settings: bool = True):
682
691
  """Loads a Setup from the given YAML file.
683
692
 
684
693
  Args:
685
694
  filename (str): the path of the YAML file to be loaded
695
+ add_local_settings (bool): if local settings shall be loaded and override the settings from the YAML file.
686
696
 
687
697
  Returns:
688
698
  a Setup that was loaded from the given location.
689
699
  """
690
- from egse.settings import Settings
691
700
 
692
701
  if not filename:
693
702
  raise ValueError("Invalid argument to function: No filename or None given.")
694
703
 
695
- setup_dict = Settings.load("Setup", filename=filename, force=True)
704
+ # MODULE_LOGGER.info(f"Loading {filename}...")
705
+
706
+ setup_dict = read_configuration_file(filename, force=True)
707
+ if setup_dict == {}:
708
+ warnings.warn(f"Empty Setup file: {filename!s}")
709
+
710
+ try:
711
+ setup_dict = setup_dict["Setup"]
712
+ except KeyError:
713
+ warnings.warn(f"Setup file doesn't have a 'Setup' group: {filename!s}")
696
714
 
697
- setup = Setup(setup_dict)
715
+ setup = Setup(setup_dict, label="Setup")
698
716
  setup.set_private_attribute("_filename", filename)
699
717
  if setup_id := _parse_filename_for_setup_id(str(filename)):
700
718
  setup.set_private_attribute("_setup_id", setup_id)
@@ -911,18 +929,15 @@ def get_setup(setup_id: int = None):
911
929
 
912
930
  def _check_conditions_for_get_path_of_setup_file(site_id: str) -> Path:
913
931
  """
914
- Check some pre-conditions that need to be met before we try to determine the file path for
915
- the requested Setup file.
932
+ Check some pre-conditions that need to be met before we try to determine the
933
+ file path for the requested Setup file.
916
934
 
917
935
  The following checks are performed:
918
936
 
919
- * if the environment variable 'PLATO_CONF_REPO_LOCATION' is set
920
-
937
+ * if the environment variable '{PROJECT}_CONF_REPO_LOCATION' is set
921
938
  * if the directory specified in the env variable actually exists
922
-
923
939
  * if the folder with the Setups exists for the given site_id
924
940
 
925
-
926
941
  Args:
927
942
  site_id (str): the name of the test house
928
943
 
@@ -939,9 +954,12 @@ def _check_conditions_for_get_path_of_setup_file(site_id: str) -> Path:
939
954
 
940
955
  if not (repo_location := get_conf_repo_location()):
941
956
  raise LookupError(
942
- f"Environment variable doesn't exist, please define {repo_location_env} and try again."
957
+ f"Environment variable doesn't exist or points to an invalid location, please (re-)define"
958
+ f" {repo_location_env} and try again."
943
959
  )
944
960
 
961
+ print_env()
962
+
945
963
  repo_location = Path(repo_location)
946
964
  setup_location = repo_location / 'data' / site_id / 'conf'
947
965
 
@@ -962,11 +980,13 @@ def _check_conditions_for_get_path_of_setup_file(site_id: str) -> Path:
962
980
 
963
981
  def get_path_of_setup_file(setup_id: int, site_id: str) -> Path:
964
982
  """
965
- Returns the Path to the last Setup file for the given site_id. The last Setup file is the file
966
- with the largest setup_id number.
983
+ Returns the Path to the last Setup file for the given site_id. The last Setup
984
+ file is the file with the largest setup_id number.
967
985
 
968
- This function needs the environment variable <PROJECT>_CONF_REPO_LOCATION to be defined as the
969
- location of the repository with configuration data on your disk.
986
+ This function needs the environment variable <PROJECT>_CONF_REPO_LOCATION to
987
+ be defined as the location of the repository with configuration data on your
988
+ disk. If the repo is not defined, the configuration data location will be used
989
+ instead.
970
990
 
971
991
  Args:
972
992
  setup_id (int): the identifier for the requested Setup
@@ -984,7 +1004,10 @@ def get_path_of_setup_file(setup_id: int, site_id: str) -> Path:
984
1004
 
985
1005
  """
986
1006
 
987
- setup_location = _check_conditions_for_get_path_of_setup_file(site_id)
1007
+ if not has_conf_repo_location():
1008
+ setup_location = Path(get_conf_data_location(site_id))
1009
+ else:
1010
+ setup_location = _check_conditions_for_get_path_of_setup_file(site_id)
988
1011
 
989
1012
  if setup_id:
990
1013
  files = list(setup_location.glob(f'SETUP_{site_id}_{setup_id:05d}_*.yaml'))
egse/system.py CHANGED
@@ -28,6 +28,7 @@ import socket
28
28
  import subprocess # For executing a shell command
29
29
  import sys
30
30
  import time
31
+ import warnings
31
32
  from collections import namedtuple
32
33
  from contextlib import contextmanager
33
34
  from pathlib import Path
@@ -512,6 +513,9 @@ class AttributeDict(dict):
512
513
  return self.__class__.__name__ + f"({{{sub_msg}{', ...' if len(self) > count else ''}}})"
513
514
 
514
515
 
516
+ attrdict = AttributeDict
517
+
518
+
515
519
  def walk_dict_tree(dictionary: dict, tree: Tree, text_style: str = "green"):
516
520
  for k, v in dictionary.items():
517
521
  if isinstance(v, dict):
@@ -931,22 +935,23 @@ def env_var(**kwargs):
931
935
 
932
936
  """
933
937
  saved_env = {}
934
- try:
935
- for k, v in kwargs.items():
936
- saved_env[k] = os.environ.get(k)
937
- if v is None:
938
- if k in os.environ:
939
- del os.environ[k]
940
- else:
941
- os.environ[k] = v
942
- yield
943
- finally:
944
- for k, v in saved_env.items():
945
- if v is None:
946
- if k in os.environ:
947
- del os.environ[k]
948
- else:
949
- os.environ[k] = v
938
+
939
+ for k, v in kwargs.items():
940
+ saved_env[k] = os.environ.get(k)
941
+ if v is None:
942
+ if k in os.environ:
943
+ del os.environ[k]
944
+ else:
945
+ os.environ[k] = v
946
+
947
+ yield
948
+
949
+ for k, v in saved_env.items():
950
+ if v is None:
951
+ if k in os.environ:
952
+ del os.environ[k]
953
+ else:
954
+ os.environ[k] = v
950
955
 
951
956
 
952
957
  def filter_by_attr(elements: Iterable, **attrs) -> List:
@@ -1120,7 +1125,7 @@ def is_namespace(module) -> bool:
1120
1125
  return False
1121
1126
 
1122
1127
 
1123
- def get_package_location(module) -> List[Path]:
1128
+ def get_package_location(module: str) -> List[Path]:
1124
1129
  """
1125
1130
  Retrieves the file system locations associated with a Python package.
1126
1131
 
@@ -1153,6 +1158,7 @@ def get_package_location(module) -> List[Path]:
1153
1158
  try:
1154
1159
  module = importlib.import_module(module)
1155
1160
  except TypeError:
1161
+ warnings.warn(f"The module is not found or is not valid: {module_name}.")
1156
1162
  return []
1157
1163
 
1158
1164
  if is_namespace(module):
@@ -1,2 +0,0 @@
1
- [cgse.version]
2
- cgse-common = egse