From 644f0b40171ee70a939e3d0dddb17078598cf371 Mon Sep 17 00:00:00 2001 From: Tristan Dijkstra Date: Wed, 24 Jun 2026 15:41:38 +0300 Subject: [PATCH 1/5] add set_space_weather_path function --- CHANGELOG.md | 5 +++ docs/source/reference/index.rst | 1 + pymsis/__init__.py | 3 +- pymsis/utils.py | 55 +++++++++++++++++++++++++++++++-- tests/conftest.py | 4 ++- tests/test_utils.py | 27 ++++++++++++++++ 6 files changed, 90 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6a5e5b..daf05b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ All notable changes to this project will be documented in this file. at higher temporal resolutions. There can be step changes of more than 20% in some situations when going from hour 02:59 to 03:00 when new indices get used again on the 3-hourly boundaries. +- **ADDED** `pymsis.set_space_weather_path()` function. + - The function points pymsis to a custom space weather + file instead of the one bundled in the install location. + - The same path can be set at startup with the `PYMSIS_SPACE_WEATHER_PATH` + environment variable. - **CHANGED** `get_f107_ap()` returns arrays of the same shape as the input - Previously, when a scalar date was passed to the utility function, the `ap` values were 1d (7,) rather than of shape (1, 7) corresponding to diff --git a/docs/source/reference/index.rst b/docs/source/reference/index.rst index 07b0571..3338bdb 100644 --- a/docs/source/reference/index.rst +++ b/docs/source/reference/index.rst @@ -49,3 +49,4 @@ get the proper F10.7 and ap values to use for a specific date and time. utils.download_f107_ap utils.get_f107_ap + utils.set_space_weather_path diff --git a/pymsis/__init__.py b/pymsis/__init__.py index 1b92db7..6cfd9b3 100644 --- a/pymsis/__init__.py +++ b/pymsis/__init__.py @@ -3,8 +3,9 @@ import importlib.metadata from pymsis.msis import Variable, calculate +from pymsis.utils import set_space_weather_path __version__ = importlib.metadata.version("pymsis") -__all__ = ["Variable", "__version__", "calculate"] +__all__ = ["Variable", "__version__", "calculate", "set_space_weather_path"] diff --git a/pymsis/utils.py b/pymsis/utils.py index 2e55e3a..2e9e29f 100644 --- a/pymsis/utils.py +++ b/pymsis/utils.py @@ -1,5 +1,6 @@ """Utilities for obtaining input datasets.""" +import os import urllib.request import warnings from io import BytesIO @@ -13,9 +14,46 @@ _DATA_FNAME: str = "SW-All.csv" _F107_AP_URL: str = f"https://celestrak.org/SpaceData/{_DATA_FNAME}" -_F107_AP_PATH: Path = Path(pymsis.__file__).parent / _DATA_FNAME +_F107_AP_DEFAULT_PATH: Path = Path(pymsis.__file__).parent / _DATA_FNAME _DATA: dict[str, npt.NDArray] | None = None +_F107_AP_PATH: Path = Path( + os.environ.get("PYMSIS_SPACE_WEATHER_PATH", _F107_AP_DEFAULT_PATH) +) + + +def set_space_weather_path(path: str | Path) -> None: + """ + Set a custom path to retrieve the F10.7 and ap data from. + + By default, the data is retrieved from CelesTrak and stored inside the + installed package location. Retrieving the data from a custom path may + be useful if you are retrieving the data from a different source, if you + have a centralized location for the data, or would like to use custom data. + + Alternatively, you can set the environment variable ``PYMSIS_SPACE_WEATHER_PATH`` + to the desired path to achieve the same result and to avoid setting the space + weather path programmatically on each run. + + Setting a default and running `download_f107_ap()` will not download to + this custom path. + + Parameters + ---------- + path : str or Path + Path to the F10.7 and ap data file, retrieved from CelesTrak or elsewhere. + """ + if not Path(path).exists(): + raise FileNotFoundError( + f"Provided custom space weather path does not exist: {path}" + ) + + # set the global variable to the new path + globals()["_F107_AP_PATH"] = Path(path) + + # reset the global data + globals()["_DATA"] = None + def download_f107_ap() -> None: """ @@ -26,6 +64,9 @@ def download_f107_ap() -> None: This routine can be called to update the data as well if you would like to use newer data since the last time you downloaded the file. + If `set_space_weather_path()` has been called to set a custom path, the file will + still be downloaded to the default location and thus ignored by pymsis. + Notes ----- The default data provider is CelesTrak, which gets data from other @@ -44,13 +85,21 @@ def download_f107_ap() -> None: """ warnings.warn(f"Downloading ap and F10.7 data from {_F107_AP_URL}") req = urllib.request.urlopen(_F107_AP_URL) - with _F107_AP_PATH.open("wb") as f: + with _F107_AP_DEFAULT_PATH.open("wb") as f: f.write(req.read()) def _load_f107_ap_data() -> dict[str, npt.NDArray]: """Load data from disk, if it isn't present go out and download it first.""" - if not _F107_AP_PATH.exists(): + default_file_exists = _F107_AP_DEFAULT_PATH.exists() + custom_file_used = _F107_AP_PATH != _F107_AP_DEFAULT_PATH + + if custom_file_used and not _F107_AP_PATH.exists(): + raise FileNotFoundError( + f"Custom space weather path has been set but does not exist: {_F107_AP_PATH}" + ) + + if not custom_file_used and not default_file_exists: download_f107_ap() dtype = { diff --git a/tests/conftest.py b/tests/conftest.py index bbe64d9..bc58f36 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,8 +10,10 @@ def local_path(monkeypatch): # Update the data location to our test data test_file = Path(__file__).parent / "f107_ap_test_data.txt" # Monkeypatch the url and expected download location, so we aren't - # dependent on an internet connection. + # dependent on an internet connection. Patch both the active path and the + # default path so tests exercise the "default location" branch by default. monkeypatch.setattr(utils, "_F107_AP_PATH", test_file) + monkeypatch.setattr(utils, "_F107_AP_DEFAULT_PATH", test_file) return test_file diff --git a/tests/test_utils.py b/tests/test_utils.py index c70d388..f99fe02 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -7,7 +7,9 @@ def test_downloading(monkeypatch, tmp_path): tmp_file = tmp_path / "testfile.txt" + # download_f107_ap() always writes to the default location, so patch both monkeypatch.setattr(utils, "_F107_AP_PATH", tmp_file) + monkeypatch.setattr(utils, "_F107_AP_DEFAULT_PATH", tmp_file) # just be nice and make sure we are getting the monkeypatched local file assert utils._F107_AP_URL.startswith("file://") with pytest.warns(UserWarning, match="Downloading ap and F10.7"): @@ -27,7 +29,10 @@ def test_loading_data(monkeypatch, tmp_path): # Make sure a download warning is emitted if the file doesn't exist tmp_file = tmp_path / "testfile.txt" with monkeypatch.context() as m: + # Point both at the (missing) default location so the auto-download + # branch is exercised rather than the custom-path branch. m.setattr(utils, "_F107_AP_PATH", tmp_file) + m.setattr(utils, "_F107_AP_DEFAULT_PATH", tmp_file) assert not tmp_file.exists() with pytest.warns(UserWarning, match="Downloading ap and F10.7"): utils._load_f107_ap_data() @@ -167,3 +172,25 @@ def test_get_f107_ap_interpolate_exact_match(date): assert_allclose(f107_nointerp, f107_interp) assert_allclose(f107a_nointerp, f107a_interp) assert_array_equal(ap_nointerp, ap_interp) +def test_set_space_weather_path(monkeypatch, tmp_path): + custom_file = tmp_path / "custom_sw.csv" + custom_file.write_text("placeholder") + # Pretend some data was already cached so we can verify it gets reset + monkeypatch.setattr(utils, "_DATA", {"dummy": np.array([1])}) + + utils.set_space_weather_path(custom_file) + # Check if the path has been updated + assert utils._F107_AP_PATH == custom_file + # Check if the data has been reset. + assert utils._DATA is None + + # Setting a path that doesn't exist should raise + missing = tmp_path / "does_not_exist.csv" + with pytest.raises(FileNotFoundError, match="does not exist"): + utils.set_space_weather_path(missing) + + # A custom path may also be set via the environment variable without going + # through set_space_weather_path(), so loading must validate it too. + monkeypatch.setattr(utils, "_F107_AP_PATH", missing) + with pytest.raises(FileNotFoundError, match="Custom space weather path"): + utils._load_f107_ap_data() From 09780b89ea43a00e9cc6540e173e6a83dbd15e15 Mon Sep 17 00:00:00 2001 From: Tristan Dijkstra Date: Wed, 24 Jun 2026 18:17:16 +0300 Subject: [PATCH 2/5] run ruff --- pymsis/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pymsis/utils.py b/pymsis/utils.py index 2e9e29f..6edc677 100644 --- a/pymsis/utils.py +++ b/pymsis/utils.py @@ -96,7 +96,8 @@ def _load_f107_ap_data() -> dict[str, npt.NDArray]: if custom_file_used and not _F107_AP_PATH.exists(): raise FileNotFoundError( - f"Custom space weather path has been set but does not exist: {_F107_AP_PATH}" + f"""Custom space weather path has been set but does not exist: + {_F107_AP_PATH}""" ) if not custom_file_used and not default_file_exists: From 09d531b900df606a0afb79ee76b39de9026a0233 Mon Sep 17 00:00:00 2001 From: Tristan Dijkstra Date: Mon, 29 Jun 2026 13:24:41 +0300 Subject: [PATCH 3/5] update use of globals --- pymsis/utils.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pymsis/utils.py b/pymsis/utils.py index 6edc677..3af1531 100644 --- a/pymsis/utils.py +++ b/pymsis/utils.py @@ -48,11 +48,10 @@ def set_space_weather_path(path: str | Path) -> None: f"Provided custom space weather path does not exist: {path}" ) - # set the global variable to the new path - globals()["_F107_AP_PATH"] = Path(path) - - # reset the global data - globals()["_DATA"] = None + # update the global path and data variables + global _F107_AP_PATH, _DATA # noqa: PLW0603 + _F107_AP_PATH = Path(path) + _DATA = None def download_f107_ap() -> None: @@ -218,7 +217,8 @@ def _load_f107_ap_data() -> dict[str, npt.NDArray]: "f107a": f107a_data, "warn_data": warn_data, } - globals()["_DATA"] = data + global _DATA # noqa: PLW0603 + _DATA = data return data From 7c3d154236f9f36fbe00a4f28f3bd8439c684976 Mon Sep 17 00:00:00 2001 From: Tristan Dijkstra Date: Mon, 29 Jun 2026 13:50:18 +0300 Subject: [PATCH 4/5] Address PR feeback --- CHANGELOG.md | 2 +- docs/source/reference/index.rst | 2 +- pymsis/__init__.py | 4 ++-- pymsis/utils.py | 37 ++++++++++++++++++++++----------- tests/test_utils.py | 35 ++++++++++++++++++++++++------- 5 files changed, 57 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index daf05b7..335c4c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ All notable changes to this project will be documented in this file. at higher temporal resolutions. There can be step changes of more than 20% in some situations when going from hour 02:59 to 03:00 when new indices get used again on the 3-hourly boundaries. -- **ADDED** `pymsis.set_space_weather_path()` function. +- **ADDED** `pymsis.use_space_weather_file()` function. - The function points pymsis to a custom space weather file instead of the one bundled in the install location. - The same path can be set at startup with the `PYMSIS_SPACE_WEATHER_PATH` diff --git a/docs/source/reference/index.rst b/docs/source/reference/index.rst index 3338bdb..c600fdf 100644 --- a/docs/source/reference/index.rst +++ b/docs/source/reference/index.rst @@ -49,4 +49,4 @@ get the proper F10.7 and ap values to use for a specific date and time. utils.download_f107_ap utils.get_f107_ap - utils.set_space_weather_path + utils.use_space_weather_file diff --git a/pymsis/__init__.py b/pymsis/__init__.py index 6cfd9b3..f3379f5 100644 --- a/pymsis/__init__.py +++ b/pymsis/__init__.py @@ -3,9 +3,9 @@ import importlib.metadata from pymsis.msis import Variable, calculate -from pymsis.utils import set_space_weather_path +from pymsis.utils import use_space_weather_file __version__ = importlib.metadata.version("pymsis") -__all__ = ["Variable", "__version__", "calculate", "set_space_weather_path"] +__all__ = ["Variable", "__version__", "calculate", "use_space_weather_file"] diff --git a/pymsis/utils.py b/pymsis/utils.py index 3af1531..3e243d8 100644 --- a/pymsis/utils.py +++ b/pymsis/utils.py @@ -22,28 +22,34 @@ ) -def set_space_weather_path(path: str | Path) -> None: +def use_space_weather_file(path: str | Path | None = None) -> None: """ - Set a custom path to retrieve the F10.7 and ap data from. + Direct pymsis to use a custom file to retrieve the F10.7 and ap data from. + + The custom data file must follow the same (.csv) format as data retrieved from + Celestrak. The legacy (.txt) file format is not supported. By default, the data is retrieved from CelesTrak and stored inside the installed package location. Retrieving the data from a custom path may be useful if you are retrieving the data from a different source, if you have a centralized location for the data, or would like to use custom data. - Alternatively, you can set the environment variable ``PYMSIS_SPACE_WEATHER_PATH`` - to the desired path to achieve the same result and to avoid setting the space - weather path programmatically on each run. + Alternatively, the path can be set using the environment variable + ``PYMSIS_SPACE_WEATHER_PATH`` to the desired path to achieve the same result and + to avoid setting the space weather path programmatically on each run. Setting a default and running `download_f107_ap()` will not download to this custom path. Parameters ---------- - path : str or Path + path : str or Path or None Path to the F10.7 and ap data file, retrieved from CelesTrak or elsewhere. + If set to None, the space weather file downloaded from CelesTrak (stored in the + installed package location) will be used. """ - if not Path(path).exists(): + path = Path(path) if path is not None else _F107_AP_DEFAULT_PATH + if not path.is_file(): raise FileNotFoundError( f"Provided custom space weather path does not exist: {path}" ) @@ -63,7 +69,7 @@ def download_f107_ap() -> None: This routine can be called to update the data as well if you would like to use newer data since the last time you downloaded the file. - If `set_space_weather_path()` has been called to set a custom path, the file will + If `use_space_weather_file()` has been called to set a custom path, the file will still be downloaded to the default location and thus ignored by pymsis. Notes @@ -83,6 +89,13 @@ def download_f107_ap() -> None: Space Weather, https://doi.org/10.1029/2020SW002641 """ warnings.warn(f"Downloading ap and F10.7 data from {_F107_AP_URL}") + if _F107_AP_DEFAULT_PATH != _F107_AP_PATH: + warnings.warn( + "A custom space weather file has been set, but the downloaded file " + "will be stored in the default location and ignored. Unset the " + "custom path using `use_space_weather_file(None)` to use the " + "downloaded file." + ) req = urllib.request.urlopen(_F107_AP_URL) with _F107_AP_DEFAULT_PATH.open("wb") as f: f.write(req.read()) @@ -90,13 +103,13 @@ def download_f107_ap() -> None: def _load_f107_ap_data() -> dict[str, npt.NDArray]: """Load data from disk, if it isn't present go out and download it first.""" - default_file_exists = _F107_AP_DEFAULT_PATH.exists() + default_file_exists = _F107_AP_DEFAULT_PATH.is_file() custom_file_used = _F107_AP_PATH != _F107_AP_DEFAULT_PATH - if custom_file_used and not _F107_AP_PATH.exists(): + if custom_file_used and not _F107_AP_PATH.is_file(): raise FileNotFoundError( - f"""Custom space weather path has been set but does not exist: - {_F107_AP_PATH}""" + "Custom space weather file has been set but does not exist: " + f"{_F107_AP_PATH}" ) if not custom_file_used and not default_file_exists: diff --git a/tests/test_utils.py b/tests/test_utils.py index f99fe02..14f1573 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,3 +1,5 @@ +import importlib + import numpy as np import pytest from numpy.testing import assert_allclose, assert_array_equal @@ -172,13 +174,15 @@ def test_get_f107_ap_interpolate_exact_match(date): assert_allclose(f107_nointerp, f107_interp) assert_allclose(f107a_nointerp, f107a_interp) assert_array_equal(ap_nointerp, ap_interp) -def test_set_space_weather_path(monkeypatch, tmp_path): + + +def test_use_space_weather_file(monkeypatch, tmp_path): custom_file = tmp_path / "custom_sw.csv" custom_file.write_text("placeholder") # Pretend some data was already cached so we can verify it gets reset monkeypatch.setattr(utils, "_DATA", {"dummy": np.array([1])}) - utils.set_space_weather_path(custom_file) + utils.use_space_weather_file(custom_file) # Check if the path has been updated assert utils._F107_AP_PATH == custom_file # Check if the data has been reset. @@ -187,10 +191,27 @@ def test_set_space_weather_path(monkeypatch, tmp_path): # Setting a path that doesn't exist should raise missing = tmp_path / "does_not_exist.csv" with pytest.raises(FileNotFoundError, match="does not exist"): - utils.set_space_weather_path(missing) + utils.use_space_weather_file(missing) + + # downloading should raise a warning that the file is ignored. + # Redirect the download to a throwaway path so we don't overwrite shared test data. + monkeypatch.setattr(utils, "_F107_AP_DEFAULT_PATH", tmp_path / "downloaded.csv") + with pytest.warns(UserWarning, match="A custom space weather file has been set"): + utils.download_f107_ap() + - # A custom path may also be set via the environment variable without going - # through set_space_weather_path(), so loading must validate it too. - monkeypatch.setattr(utils, "_F107_AP_PATH", missing) - with pytest.raises(FileNotFoundError, match="Custom space weather path"): +def test_space_weather_env_variable(monkeypatch, tmp_path): + # check if setting space weather path via env variable works + custom_file = tmp_path / "custom_sw.csv" + custom_file.write_text("placeholder") + monkeypatch.setenv("PYMSIS_SPACE_WEATHER_PATH", str(custom_file)) + importlib.reload(utils) + + assert utils._F107_AP_PATH == custom_file + + # Loading the data must validate that the file exists. + missing = tmp_path / "does_not_exist.csv" + monkeypatch.setenv("PYMSIS_SPACE_WEATHER_PATH", str(missing)) + importlib.reload(utils) + with pytest.raises(FileNotFoundError, match="Custom space weather file"): utils._load_f107_ap_data() From e0e09d31b8f91e4805a40db78ce7b3d79b9330e7 Mon Sep 17 00:00:00 2001 From: Tristan Dijkstra Date: Tue, 7 Jul 2026 14:43:55 +0300 Subject: [PATCH 5/5] Change wording for space weather path --- CHANGELOG.md | 2 +- pymsis/utils.py | 50 ++++++++++++++++++++++----------------------- tests/conftest.py | 4 ++-- tests/test_utils.py | 22 ++++++++++---------- 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 335c4c8..b103560 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ All notable changes to this project will be documented in this file. - **ADDED** `pymsis.use_space_weather_file()` function. - The function points pymsis to a custom space weather file instead of the one bundled in the install location. - - The same path can be set at startup with the `PYMSIS_SPACE_WEATHER_PATH` + - The same file path can be set at startup with the `PYMSIS_SPACE_WEATHER_FILE` environment variable. - **CHANGED** `get_f107_ap()` returns arrays of the same shape as the input - Previously, when a scalar date was passed to the utility function, the diff --git a/pymsis/utils.py b/pymsis/utils.py index 3e243d8..342e017 100644 --- a/pymsis/utils.py +++ b/pymsis/utils.py @@ -14,15 +14,15 @@ _DATA_FNAME: str = "SW-All.csv" _F107_AP_URL: str = f"https://celestrak.org/SpaceData/{_DATA_FNAME}" -_F107_AP_DEFAULT_PATH: Path = Path(pymsis.__file__).parent / _DATA_FNAME +_F107_AP_DEFAULT_FILE: Path = Path(pymsis.__file__).parent / _DATA_FNAME _DATA: dict[str, npt.NDArray] | None = None -_F107_AP_PATH: Path = Path( - os.environ.get("PYMSIS_SPACE_WEATHER_PATH", _F107_AP_DEFAULT_PATH) +_F107_AP_FILE: Path = Path( + os.environ.get("PYMSIS_SPACE_WEATHER_FILE", _F107_AP_DEFAULT_FILE) ) -def use_space_weather_file(path: str | Path | None = None) -> None: +def use_space_weather_file(file: str | Path | None = None) -> None: """ Direct pymsis to use a custom file to retrieve the F10.7 and ap data from. @@ -30,33 +30,33 @@ def use_space_weather_file(path: str | Path | None = None) -> None: Celestrak. The legacy (.txt) file format is not supported. By default, the data is retrieved from CelesTrak and stored inside the - installed package location. Retrieving the data from a custom path may + installed package location. Retrieving the data from a custom file path may be useful if you are retrieving the data from a different source, if you have a centralized location for the data, or would like to use custom data. - Alternatively, the path can be set using the environment variable - ``PYMSIS_SPACE_WEATHER_PATH`` to the desired path to achieve the same result and - to avoid setting the space weather path programmatically on each run. + Alternatively, the file path can be set using the environment variable + ``PYMSIS_SPACE_WEATHER_FILE`` to achieve the same result and + to avoid setting the space weather file path programmatically on each run. Setting a default and running `download_f107_ap()` will not download to - this custom path. + this custom file path. Parameters ---------- - path : str or Path or None + file : str or Path or None Path to the F10.7 and ap data file, retrieved from CelesTrak or elsewhere. If set to None, the space weather file downloaded from CelesTrak (stored in the installed package location) will be used. """ - path = Path(path) if path is not None else _F107_AP_DEFAULT_PATH - if not path.is_file(): + file = Path(file) if file is not None else _F107_AP_DEFAULT_FILE + if not file.is_file(): raise FileNotFoundError( - f"Provided custom space weather path does not exist: {path}" + f"Provided custom space weather file does not exist: {file}" ) # update the global path and data variables - global _F107_AP_PATH, _DATA # noqa: PLW0603 - _F107_AP_PATH = Path(path) + global _F107_AP_FILE, _DATA # noqa: PLW0603 + _F107_AP_FILE = Path(file) _DATA = None @@ -69,8 +69,8 @@ def download_f107_ap() -> None: This routine can be called to update the data as well if you would like to use newer data since the last time you downloaded the file. - If `use_space_weather_file()` has been called to set a custom path, the file will - still be downloaded to the default location and thus ignored by pymsis. + If `use_space_weather_file()` has been called to set a custom file path, the file + will still be downloaded to the default location and thus ignored by pymsis. Notes ----- @@ -89,27 +89,27 @@ def download_f107_ap() -> None: Space Weather, https://doi.org/10.1029/2020SW002641 """ warnings.warn(f"Downloading ap and F10.7 data from {_F107_AP_URL}") - if _F107_AP_DEFAULT_PATH != _F107_AP_PATH: + if _F107_AP_DEFAULT_FILE != _F107_AP_FILE: warnings.warn( "A custom space weather file has been set, but the downloaded file " "will be stored in the default location and ignored. Unset the " - "custom path using `use_space_weather_file(None)` to use the " + "custom file path using `use_space_weather_file(None)` to use the " "downloaded file." ) req = urllib.request.urlopen(_F107_AP_URL) - with _F107_AP_DEFAULT_PATH.open("wb") as f: + with _F107_AP_DEFAULT_FILE.open("wb") as f: f.write(req.read()) def _load_f107_ap_data() -> dict[str, npt.NDArray]: """Load data from disk, if it isn't present go out and download it first.""" - default_file_exists = _F107_AP_DEFAULT_PATH.is_file() - custom_file_used = _F107_AP_PATH != _F107_AP_DEFAULT_PATH + default_file_exists = _F107_AP_DEFAULT_FILE.is_file() + custom_file_used = _F107_AP_FILE != _F107_AP_DEFAULT_FILE - if custom_file_used and not _F107_AP_PATH.is_file(): + if custom_file_used and not _F107_AP_FILE.is_file(): raise FileNotFoundError( "Custom space weather file has been set but does not exist: " - f"{_F107_AP_PATH}" + f"{_F107_AP_FILE}" ) if not custom_file_used and not default_file_exists: @@ -152,7 +152,7 @@ def _load_f107_ap_data() -> dict[str, npt.NDArray]: # Use a buffer to read in and load so we can quickly get rid of # the extra "PRD" lines at the end of the file (unknown length # so we can't just go back in line lengths) - with _F107_AP_PATH.open() as fin: + with _F107_AP_FILE.open() as fin: with BytesIO() as fout: for line in fin: if "PRM" in line: diff --git a/tests/conftest.py b/tests/conftest.py index bc58f36..044bdb5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -12,8 +12,8 @@ def local_path(monkeypatch): # Monkeypatch the url and expected download location, so we aren't # dependent on an internet connection. Patch both the active path and the # default path so tests exercise the "default location" branch by default. - monkeypatch.setattr(utils, "_F107_AP_PATH", test_file) - monkeypatch.setattr(utils, "_F107_AP_DEFAULT_PATH", test_file) + monkeypatch.setattr(utils, "_F107_AP_FILE", test_file) + monkeypatch.setattr(utils, "_F107_AP_DEFAULT_FILE", test_file) return test_file diff --git a/tests/test_utils.py b/tests/test_utils.py index 14f1573..a9ef39a 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -10,8 +10,8 @@ def test_downloading(monkeypatch, tmp_path): tmp_file = tmp_path / "testfile.txt" # download_f107_ap() always writes to the default location, so patch both - monkeypatch.setattr(utils, "_F107_AP_PATH", tmp_file) - monkeypatch.setattr(utils, "_F107_AP_DEFAULT_PATH", tmp_file) + monkeypatch.setattr(utils, "_F107_AP_FILE", tmp_file) + monkeypatch.setattr(utils, "_F107_AP_DEFAULT_FILE", tmp_file) # just be nice and make sure we are getting the monkeypatched local file assert utils._F107_AP_URL.startswith("file://") with pytest.warns(UserWarning, match="Downloading ap and F10.7"): @@ -19,7 +19,7 @@ def test_downloading(monkeypatch, tmp_path): assert tmp_file.exists() with ( open(tmp_file, "rb") as f_downloaded, - open(utils._F107_AP_PATH, "rb") as f_expected, + open(utils._F107_AP_FILE, "rb") as f_expected, ): assert f_downloaded.read() == f_expected.read() @@ -33,8 +33,8 @@ def test_loading_data(monkeypatch, tmp_path): with monkeypatch.context() as m: # Point both at the (missing) default location so the auto-download # branch is exercised rather than the custom-path branch. - m.setattr(utils, "_F107_AP_PATH", tmp_file) - m.setattr(utils, "_F107_AP_DEFAULT_PATH", tmp_file) + m.setattr(utils, "_F107_AP_FILE", tmp_file) + m.setattr(utils, "_F107_AP_DEFAULT_FILE", tmp_file) assert not tmp_file.exists() with pytest.warns(UserWarning, match="Downloading ap and F10.7"): utils._load_f107_ap_data() @@ -184,7 +184,7 @@ def test_use_space_weather_file(monkeypatch, tmp_path): utils.use_space_weather_file(custom_file) # Check if the path has been updated - assert utils._F107_AP_PATH == custom_file + assert utils._F107_AP_FILE == custom_file # Check if the data has been reset. assert utils._DATA is None @@ -195,23 +195,23 @@ def test_use_space_weather_file(monkeypatch, tmp_path): # downloading should raise a warning that the file is ignored. # Redirect the download to a throwaway path so we don't overwrite shared test data. - monkeypatch.setattr(utils, "_F107_AP_DEFAULT_PATH", tmp_path / "downloaded.csv") + monkeypatch.setattr(utils, "_F107_AP_DEFAULT_FILE", tmp_path / "downloaded.csv") with pytest.warns(UserWarning, match="A custom space weather file has been set"): utils.download_f107_ap() def test_space_weather_env_variable(monkeypatch, tmp_path): - # check if setting space weather path via env variable works + # check if setting space weather file via env variable works custom_file = tmp_path / "custom_sw.csv" custom_file.write_text("placeholder") - monkeypatch.setenv("PYMSIS_SPACE_WEATHER_PATH", str(custom_file)) + monkeypatch.setenv("PYMSIS_SPACE_WEATHER_FILE", str(custom_file)) importlib.reload(utils) - assert utils._F107_AP_PATH == custom_file + assert utils._F107_AP_FILE == custom_file # Loading the data must validate that the file exists. missing = tmp_path / "does_not_exist.csv" - monkeypatch.setenv("PYMSIS_SPACE_WEATHER_PATH", str(missing)) + monkeypatch.setenv("PYMSIS_SPACE_WEATHER_FILE", str(missing)) importlib.reload(utils) with pytest.raises(FileNotFoundError, match="Custom space weather file"): utils._load_f107_ap_data()