cgse-core 2025.0.3__tar.gz → 2025.0.5__tar.gz

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 (22) hide show
  1. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/PKG-INFO +1 -5
  2. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/pyproject.toml +17 -4
  3. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/src/egse/confman/__init__.py +47 -26
  4. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/src/egse/confman/confman_cs.py +7 -10
  5. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/src/egse/logger/log_cs.py +2 -2
  6. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/src/egse/procman/__init__.py +7 -2
  7. cgse_core-2025.0.5/src/egse/settings.yaml +32 -0
  8. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/src/egse/storage/__init__.py +12 -11
  9. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/src/egse/storage/storage_cs.py +4 -4
  10. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/.envrc.disabled +0 -0
  11. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/.gitignore +0 -0
  12. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/README.md +0 -0
  13. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/src/egse/confman/__main__.py +0 -0
  14. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/src/egse/confman/confman.yaml +0 -0
  15. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/src/egse/logger/__init__.py +0 -0
  16. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/src/egse/logger/__main__.py +0 -0
  17. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/src/egse/procman/procman.yaml +0 -0
  18. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/src/egse/procman/procman_cs.py +0 -0
  19. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/src/egse/storage/__main__.py +0 -0
  20. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/src/egse/storage/persistence.py +0 -0
  21. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/src/egse/storage/storage.yaml +0 -0
  22. {cgse_core-2025.0.3 → cgse_core-2025.0.5}/src/scripts/cgse.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cgse-core
3
- Version: 2025.0.3
3
+ Version: 2025.0.5
4
4
  Summary: Core services for the CGSE framework
5
5
  Author-email: Rik Huygen <rik.huygen@kuleuven.be>, Sara Regibo <sara.regibo@kuleuven.be>
6
6
  License-Expression: MIT
@@ -13,10 +13,6 @@ Requires-Dist: gitpython>=3.1.44
13
13
  Requires-Dist: prometheus-client>=0.21.1
14
14
  Requires-Dist: pyzmq==23.2.1
15
15
  Requires-Dist: rich>=13.9.4
16
- Provides-Extra: dev
17
- Requires-Dist: pytest; extra == 'dev'
18
- Requires-Dist: pytest-cov; extra == 'dev'
19
- Requires-Dist: pytest-mock; extra == 'dev'
20
16
  Description-Content-Type: text/markdown
21
17
 
22
18
  # The core services for the CGSE platform
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cgse-core"
3
- version = "2025.0.3"
3
+ version = "2025.0.5"
4
4
  description = "Core services for the CGSE framework"
5
5
  authors = [
6
6
  {name = "Rik Huygen", email = "rik.huygen@kuleuven.be"},
@@ -25,9 +25,6 @@ dependencies = [
25
25
  "rich>=13.9.4",
26
26
  ]
27
27
 
28
- [project.optional-dependencies]
29
- dev = ["pytest", "pytest-mock", "pytest-cov"]
30
-
31
28
  [project.scripts]
32
29
  log_cs = 'egse.logger.log_cs:cli'
33
30
  sm_cs = 'egse.storage.storage_cs:cli'
@@ -39,6 +36,21 @@ cgse = 'scripts.cgse:cli'
39
36
  [project.entry-points."cgse.version"]
40
37
  cgse-core = 'egse'
41
38
 
39
+ [tool.pytest.ini_options]
40
+ pythonpath = "src"
41
+ testpaths = ["tests"]
42
+ addopts = "-ra --cov --cov-report html"
43
+ filterwarnings = [
44
+ "ignore::DeprecationWarning"
45
+ ]
46
+
47
+ [tool.coverage.run]
48
+ omit = [
49
+ "tests/*",
50
+ "*/cgse-common/*",
51
+ "conftest.py",
52
+ ]
53
+
42
54
  [tool.hatch.build.targets.sdist]
43
55
  exclude = [
44
56
  "/tests",
@@ -62,5 +74,6 @@ build-backend = "hatchling.build"
62
74
  [dependency-groups]
63
75
  dev = [
64
76
  "pytest>=8.3.4",
77
+ "pytest-cov>=6.0.0",
65
78
  "ruff>=0.9.0",
66
79
  ]
@@ -128,18 +128,21 @@ from egse.command import ClientServerCommand
128
128
  from egse.command import stringify_function_call
129
129
  from egse.config import find_file
130
130
  from egse.config import find_files
131
- from egse.config import get_common_egse_root
132
131
  from egse.control import ControlServer
133
- from egse.control import Failure
134
- from egse.control import Response
135
- from egse.control import Success
136
132
  from egse.control import is_control_server_active
137
133
  from egse.decorators import dynamic_interface
138
134
  from egse.decorators import static_vars
135
+ from egse.env import get_conf_data_location
136
+ from egse.env import get_conf_repo_location
137
+ from egse.env import get_project_name
138
+ from egse.env import get_site_id
139
139
  from egse.exceptions import InternalError
140
140
  from egse.obsid import ObservationIdentifier
141
141
  from egse.protocol import CommandProtocol
142
142
  from egse.proxy import Proxy
143
+ from egse.response import Failure
144
+ from egse.response import Response
145
+ from egse.response import Success
143
146
  from egse.settings import Settings
144
147
  from egse.settings import SettingsError
145
148
  from egse.setup import Setup
@@ -147,17 +150,17 @@ from egse.setup import load_last_setup_id
147
150
  from egse.setup import save_last_setup_id
148
151
  from egse.system import filter_by_attr
149
152
  from egse.system import format_datetime
150
- from egse.system import replace_environment_variable
151
153
  from egse.version import VERSION
152
154
  from egse.zmq_ser import bind_address
153
155
  from egse.zmq_ser import connect_address
154
156
 
155
157
  LOGGER = logging.getLogger(__name__)
156
158
 
159
+ HERE = Path(__file__).parent
160
+
157
161
  CTRL_SETTINGS = Settings.load("Configuration Manager Control Server")
158
- SITE = Settings.load("SITE")
159
- COMMAND_SETTINGS = Settings.load(filename="confman.yaml")
160
- REPO = Settings.load("REPO")
162
+ SITE_ID = get_site_id()
163
+ COMMAND_SETTINGS = Settings.load(location=HERE, filename="confman.yaml")
161
164
 
162
165
  CM_SETUP_ID = Gauge("CM_SETUP_ID", 'Setup ID')
163
166
  CM_TEST_ID = Gauge("CM_TEST_ID", 'Test ID')
@@ -174,14 +177,14 @@ def _push_setup_to_repo(filename: str, commit_msg: str) -> Failure | Success:
174
177
  None.
175
178
  """
176
179
 
177
- repo_workdir = REPO.CGSE_CONF
178
- repo_workdir = replace_environment_variable(repo_workdir)
180
+ repo_workdir = get_conf_repo_location()
181
+
179
182
  if repo_workdir is None:
180
183
  msg = textwrap.dedent(
181
- """\
182
- Couldn't determine the repository location for cgse-conf.
184
+ f"""\
185
+ Couldn't determine the repository location for configuration data.
183
186
 
184
- Check if the environment variable 'CGSE_CONF_REPO_LOCATION' is set
187
+ Check if the environment variable '{get_project_name()}_CONF_REPO_LOCATION' is set and valid
185
188
  before starting the configuration manager.
186
189
  """
187
190
  )
@@ -285,8 +288,14 @@ def _populate_cached_setup_info():
285
288
 
286
289
  LOGGER.info("Populating cache with Setup Info.")
287
290
 
288
- location = replace_environment_variable(CTRL_SETTINGS.FILE_STORAGE_LOCATION)
289
- data_conf_location = Path(location) if location else get_common_egse_root()
291
+ location = get_conf_data_location()
292
+ if location:
293
+ data_conf_location = Path(location)
294
+ else:
295
+ raise ValueError(
296
+ "Couldn't determine location of the configuration data with 'get_conf_data_location()'. "
297
+ "Check if the environment is properly defined."
298
+ )
290
299
 
291
300
  setup_info = {}
292
301
 
@@ -550,8 +559,13 @@ class ConfigurationManagerController(ConfigurationManagerInterface):
550
559
 
551
560
  # Find the location for the configuration data
552
561
 
553
- location = replace_environment_variable(CTRL_SETTINGS.FILE_STORAGE_LOCATION)
554
- self._data_conf_location = Path(location) if location else get_common_egse_root()
562
+ location = get_conf_data_location()
563
+ if location:
564
+ self._data_conf_location = Path(location)
565
+ else:
566
+ raise ValueError(
567
+ "The location for the configuration data is not defined. Please check your environment."
568
+ )
555
569
 
556
570
  # Populate the cache with information from the available Setups. This will also load each
557
571
  # Setup and cache them with the lru_cache decorator. Since this takes about 5s for 100
@@ -590,7 +604,7 @@ class ConfigurationManagerController(ConfigurationManagerInterface):
590
604
  last_obsid = self._storage.read({"origin": "obsid", "select": "last_line"})
591
605
  last_obsid = last_obsid.return_code if isinstance(last_obsid, Success) else None
592
606
 
593
- self._obsid = create_obsid(last_obsid, SITE.ID, self._setup_id)
607
+ self._obsid = create_obsid(last_obsid, SITE_ID, self._setup_id)
594
608
 
595
609
  if self._storage:
596
610
  response = self._storage.start_observation(self._obsid, self._sut_name)
@@ -696,14 +710,14 @@ class ConfigurationManagerController(ConfigurationManagerInterface):
696
710
 
697
711
  setup_files = list(
698
712
  find_files(
699
- pattern=f"SETUP_{SITE.ID}_{setup_id:05d}_*.yaml", root=self._data_conf_location
713
+ pattern=f"SETUP_{SITE_ID}_{setup_id:05d}_*.yaml", root=self._data_conf_location
700
714
  )
701
715
  )
702
716
 
703
717
  if len(setup_files) != 1:
704
718
  LOGGER.error(
705
719
  msg := f"Expected to find just one Setup YAML file, found {len(setup_files)}. "
706
- f"[{SITE.ID = }, {setup_id = }, data_conf_location={self._data_conf_location}]"
720
+ f"[{SITE_ID = }, {setup_id = }, data_conf_location={self._data_conf_location}]"
707
721
  )
708
722
  return Failure("Loading Setup", InternalError(msg))
709
723
 
@@ -745,7 +759,7 @@ class ConfigurationManagerController(ConfigurationManagerInterface):
745
759
 
746
760
  setup_files = list(
747
761
  find_files(
748
- pattern=f"SETUP_{SITE.ID}_{setup_id:05d}_*.yaml", root=self._data_conf_location
762
+ pattern=f"SETUP_{SITE_ID}_{setup_id:05d}_*.yaml", root=self._data_conf_location
749
763
  )
750
764
  )
751
765
 
@@ -786,7 +800,7 @@ class ConfigurationManagerController(ConfigurationManagerInterface):
786
800
  The Site identifier as a string.
787
801
  """
788
802
 
789
- return SITE.ID
803
+ return SITE_ID
790
804
 
791
805
  def reload_setups(self):
792
806
  """
@@ -839,7 +853,7 @@ class ConfigurationManagerController(ConfigurationManagerInterface):
839
853
  try:
840
854
  setup_id = int(rc.return_code[-1].split(maxsplit=3)[2])
841
855
  setup_file = find_file(
842
- name=f"SETUP_{SITE.ID}_{setup_id:05d}_*.yaml", root=self._data_conf_location
856
+ name=f"SETUP_{SITE_ID}_{setup_id:05d}_*.yaml", root=self._data_conf_location
843
857
  )
844
858
  setup = Setup.from_yaml_file(setup_file)
845
859
  except (IndexError, SettingsError):
@@ -867,7 +881,7 @@ class ConfigurationManagerController(ConfigurationManagerInterface):
867
881
 
868
882
  setup_id = self.get_next_setup_id_for_site(site)
869
883
 
870
- filename = _construct_filename(SITE.ID, setup_id)
884
+ filename = _construct_filename(SITE_ID, setup_id)
871
885
 
872
886
  if not hasattr(setup, "history"):
873
887
  setup.history = {}
@@ -876,6 +890,12 @@ class ConfigurationManagerController(ConfigurationManagerInterface):
876
890
  setup.set_private_attribute("_setup_id", setup_id)
877
891
  setup.to_yaml_file(self._data_conf_location / filename)
878
892
 
893
+ # No repository is defined. This should not break, but a warning is in place.
894
+ # The warnings are issued by the get_conf_repo_location() function.
895
+
896
+ if get_conf_repo_location() is None:
897
+ return
898
+
879
899
  try:
880
900
  rc = _push_setup_to_repo(filename, description)
881
901
  if isinstance(rc, Failure):
@@ -896,12 +916,13 @@ class ConfigurationManagerController(ConfigurationManagerInterface):
896
916
  return setup
897
917
 
898
918
  def get_next_setup_id_for_site(self, site: str) -> int:
899
- """Return the next available Setup ID for the given Site.
919
+ """
920
+ Return the next available Setup ID for the given Site.
900
921
 
901
922
  Args:
902
923
  site (str): site identification, e.g. CSL, SRON, ...
903
924
  """
904
- site = site or SITE.ID
925
+ site = site or SITE_ID
905
926
  files = sorted(find_files(pattern=f"SETUP_{site}_*.yaml", root=self._data_conf_location))
906
927
  last_file = files[-1]
907
928
  setup_id = last_file.name.split("_")[2]
@@ -16,15 +16,15 @@ from pathlib import Path
16
16
  import click
17
17
  import rich
18
18
  import zmq
19
- from egse.control import ControlServer
20
- from egse.control import Response
21
- from egse.process import SubProcess
22
- from egse.settings import Settings
23
- from egse.system import replace_environment_variable
24
19
  from prometheus_client import start_http_server
25
20
 
26
21
  from egse.confman import ConfigurationManagerProtocol
27
22
  from egse.confman import ConfigurationManagerProxy
23
+ from egse.control import ControlServer
24
+ from egse.env import get_conf_data_location
25
+ from egse.process import SubProcess
26
+ from egse.response import Response
27
+ from egse.settings import Settings
28
28
 
29
29
  # Use explicit name here otherwise the logger will probably be called __main__
30
30
 
@@ -205,14 +205,11 @@ def check_prerequisites():
205
205
 
206
206
  # We need a proper location for storing the configuration data.
207
207
 
208
- location = CTRL_SETTINGS.FILE_STORAGE_LOCATION
209
- location = replace_environment_variable(location)
208
+ location = get_conf_data_location()
210
209
 
211
210
  if not location:
212
211
  raise RuntimeError(
213
- "The environment variable referenced in the Settings.yaml file for the "
214
- "FILE_STORAGE_LOCATION of the Configuration Manager does not exist, please set "
215
- "the environment variable."
212
+ "The location for the configuration data is not defined. Please check your environment."
216
213
  )
217
214
 
218
215
  location = Path(location)
@@ -119,9 +119,9 @@ def start():
119
119
  stream_handler = StreamHandler()
120
120
  stream_handler.setFormatter(logging.Formatter(fmt=LOG_FORMAT_STREAM))
121
121
 
122
- # Log records are also sent to the cutelog listening server
122
+ # Log records are also sent to the textualog listening server
123
123
 
124
- socket_handler = SocketHandler(CTRL_SETTINGS.CUTELOG_IP_ADDRESS, CTRL_SETTINGS.CUTELOG_LISTENING_PORT)
124
+ socket_handler = SocketHandler(CTRL_SETTINGS.TEXTUALOG_IP_ADDRESS, CTRL_SETTINGS.TEXTUALOG_LISTENING_PORT)
125
125
  socket_handler.setFormatter(file_formatter)
126
126
 
127
127
  context = zmq.Context()
@@ -7,11 +7,14 @@ import pickle
7
7
  import time
8
8
 
9
9
  import sys
10
+ from pathlib import Path
11
+
10
12
  import zmq
11
13
 
12
14
  from egse.command import ClientServerCommand
13
15
  from egse.confman import ConfigurationManagerProxy
14
- from egse.control import ControlServer, Success, Failure
16
+ from egse.control import ControlServer
17
+ from egse.response import Success, Failure
15
18
  from egse.decorators import dynamic_interface
16
19
  from egse.dpu import fitsgen
17
20
  from egse.dpu.dpu_cs import is_dpu_cs_active
@@ -29,8 +32,10 @@ from egse.system import format_datetime
29
32
  from egse.zmq_ser import bind_address
30
33
  from egse.zmq_ser import connect_address
31
34
 
35
+ HERE = Path(__file__).parent
36
+
32
37
  CTRL_SETTINGS = Settings.load("Process Manager Control Server")
33
- COMMAND_SETTINGS = Settings.load(filename="procman.yaml")
38
+ COMMAND_SETTINGS = Settings.load(location=HERE, filename="procman.yaml")
34
39
 
35
40
  LOGGER = logging.getLogger(__name__)
36
41
 
@@ -0,0 +1,32 @@
1
+ Logging Control Server: # LOG_CS
2
+
3
+ PROTOCOL: tcp
4
+ HOSTNAME: localhost # The hostname that client shall connect to, e.g. pleiad01 @ KU Leuven
5
+ LOGGING_PORT: 7000
6
+ COMMANDING_PORT: 7001
7
+ METRICS_PORT: 7003 # The HTTP port where Prometheus will connect to for retrieving metrics
8
+ MAX_NR_LOG_FILES: 20 # The maximum number of log files that will be maintained in a roll-over
9
+ MAX_SIZE_LOG_FILES: 20 # The maximum size one log file can become
10
+ TEXTUALOG_IP_ADDRESS: 127.0.0.1 # The IP address of the textualog listening server
11
+ TEXTUALOG_LISTENING_PORT: 19996 # The port number on which the textualog server is listening
12
+
13
+ Configuration Manager Control Server: # CM_CS
14
+
15
+ PROTOCOL: tcp
16
+ HOSTNAME: localhost # The hostname that client shall connect to, e.g. pleiad01 @ KU Leuven
17
+ COMMANDING_PORT: 6000 # The port on which the controller listens to commands - REQ-REP
18
+ MONITORING_PORT: 6001 # The port on which the controller sends periodic status information of the device - PUB-SUB
19
+ SERVICE_PORT: 6002 # The port on which the controller listens for configuration and administration - REQ-REP
20
+ METRICS_PORT: 6003 # The HTTP port where Prometheus will connect to for retrieving metrics
21
+ DELAY: 1 # The delay time between publishing status information [seconds]
22
+ STORAGE_MNEMONIC: CM # The mnemonic to be used in the filename storing the housekeeping data
23
+
24
+ Storage Control Server: # SM_CS
25
+
26
+ PROTOCOL: tcp
27
+ HOSTNAME: localhost # The hostname that client shall connect to, e.g. pleiad01 @ KU Leuven
28
+ COMMANDING_PORT: 6100 # The port on which the controller listens to commands - REQ-REP
29
+ MONITORING_PORT: 6101 # The port on which the controller sends periodic status information of the device - PUB-SUB
30
+ SERVICE_PORT: 6102 # The port on which the controller listens for configuration and administration - REQ-REP
31
+ METRICS_PORT: 6103 # The HTTP port where Prometheus will connect to for retrieving metrics
32
+ DELAY: 1 # The delay time between publishing status information [seconds]
@@ -112,9 +112,10 @@ from egse.bits import humanize_bytes
112
112
  from egse.command import ClientServerCommand
113
113
  from egse.config import find_files
114
114
  from egse.control import ControlServer
115
- from egse.control import Failure
116
- from egse.control import Response
117
- from egse.control import Success
115
+ from egse.env import get_site_id
116
+ from egse.response import Failure
117
+ from egse.response import Response
118
+ from egse.response import Success
118
119
  from egse.control import is_control_server_active
119
120
  from egse.decorators import dynamic_interface
120
121
  from egse.env import get_data_storage_location
@@ -132,11 +133,11 @@ from egse.zmq_ser import connect_address
132
133
 
133
134
  logger = logging.getLogger(__name__)
134
135
 
136
+ HERE = Path(__file__).parent
137
+
135
138
  CTRL_SETTINGS = Settings.load("Storage Control Server")
136
- SITE = Settings.load("SITE")
137
- COMMAND_SETTINGS = Settings.load(filename="storage.yaml")
138
- DEVICE_SETTINGS = Settings.load(filename="storage.yaml")
139
- CCD_SETTINGS = Settings.load("CCD")
139
+ SITE_ID = get_site_id()
140
+ DEVICE_SETTINGS = COMMAND_SETTINGS = Settings.load(location=HERE, filename="storage.yaml")
140
141
 
141
142
  __all__ = [
142
143
  "is_storage_manager_active",
@@ -543,7 +544,7 @@ def _construct_filename(
543
544
  The full path to the file as a `PurePath`.
544
545
  """
545
546
 
546
- site_id = site_id or SITE.ID
547
+ site_id = site_id or SITE_ID
547
548
  location = location or get_data_storage_location(site_id=site_id)
548
549
 
549
550
  if obsid:
@@ -854,7 +855,7 @@ class StorageController(StorageInterface):
854
855
  self._registry.register(item["origin"], item)
855
856
 
856
857
  if "filename" in item:
857
- location = Path(get_data_storage_location(site_id=SITE.ID))
858
+ location = Path(get_data_storage_location(site_id=SITE_ID))
858
859
  filename = location / item["filename"]
859
860
  else:
860
861
  filename = _construct_filename(item["origin"], item["persistence_class"].extension,
@@ -972,7 +973,7 @@ class StorageController(StorageInterface):
972
973
  )
973
974
 
974
975
  def get_storage_location(self):
975
- return get_data_storage_location(site_id=SITE.ID)
976
+ return get_data_storage_location(site_id=SITE_ID)
976
977
 
977
978
  def get_filenames(self, item: dict) -> List[Path]:
978
979
  registered_item = self._registry.get(item["origin"])
@@ -995,7 +996,7 @@ class StorageController(StorageInterface):
995
996
 
996
997
  def get_disk_usage(self):
997
998
 
998
- location = Path(get_data_storage_location(site_id=SITE.ID))
999
+ location = Path(get_data_storage_location(site_id=SITE_ID))
999
1000
  total, used, free = shutil.disk_usage(location)
1000
1001
  return total, used, free
1001
1002
 
@@ -20,6 +20,7 @@ from pytz import utc
20
20
  from egse.bits import humanize_bytes
21
21
  from egse.control import ControlServer
22
22
  from egse.env import get_data_storage_location
23
+ from egse.env import get_site_id
23
24
  from egse.process import SubProcess
24
25
  from egse.settings import Settings
25
26
  from egse.storage import StorageProtocol
@@ -33,7 +34,7 @@ from egse.system import replace_environment_variable
33
34
  logger = logging.getLogger("egse.storage.storage_cs")
34
35
 
35
36
  CTRL_SETTINGS = Settings.load("Storage Control Server")
36
- SITE = Settings.load("SITE")
37
+ SITE_ID = get_site_id()
37
38
 
38
39
 
39
40
  class StorageControlServer(ControlServer):
@@ -159,12 +160,11 @@ def check_prerequisites():
159
160
  # We need a proper location for storing the data, this directory shall contain
160
161
  # two subfolders: 'daily' and 'obs'.
161
162
 
162
- location = get_data_storage_location(site_id=SITE.ID)
163
+ location = get_data_storage_location(site_id=SITE_ID)
163
164
 
164
165
  if not location:
165
166
  raise RuntimeError(
166
- "The environment variable referenced in the Settings.yaml file for the "
167
- "FILE_STORAGE_LOCATION does not exist, please set the environment variable."
167
+ "The data storage location is not defined. Please check your environment."
168
168
  )
169
169
 
170
170
  location = Path(location)
File without changes
File without changes