diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0a8342e..c4efc2a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: rev: 5.10.1 hooks: - id: isort - exclude: ".*(.fits|.fts|.fit|.txt|.csv)$" + exclude: ".*(.fits|.fts|.fit|.txt|.csv|__init__.py)$" - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.3.0 hooks: @@ -34,7 +34,7 @@ repos: - id: check-yaml - id: debug-statements - repo: https://github.com/pre-commit/mirrors-mypy - rev: 'v0.961' + rev: 'v0.971' hooks: - id: mypy additional_dependencies: [types-requests==2.28.0] diff --git a/hvpy/__init__.py b/hvpy/__init__.py index 1e28c0c..ef3dc1e 100644 --- a/hvpy/__init__.py +++ b/hvpy/__init__.py @@ -1,3 +1,3 @@ -from .facade import * # NOQA -from .io import set_api_url +from .facade import * +from .config import set_api_url from .version import __version__ diff --git a/hvpy/api_groups/jpeg2000/tests/test_get_jp2_header.py b/hvpy/api_groups/jpeg2000/tests/test_get_jp2_header.py index 38381e7..5c0d289 100644 --- a/hvpy/api_groups/jpeg2000/tests/test_get_jp2_header.py +++ b/hvpy/api_groups/jpeg2000/tests/test_get_jp2_header.py @@ -1,8 +1,5 @@ -import os - import pytest -import hvpy from hvpy import getJP2Header from hvpy.api_groups.jpeg2000.get_jp2_header import getJP2HeaderInputParameters @@ -26,17 +23,3 @@ def test_error_handling(): def test_url_property(): params = getJP2HeaderInputParameters(id=9838343) assert params.url == "https://api.helioviewer.org/v2/getJP2Header/" - - -def test_set_api_url(): - params = getJP2HeaderInputParameters(id=9838343) - assert params.url == "https://api.helioviewer.org/v2/getJP2Header/" - - os.environ["HELIOVIEWER_API_URL"] = "https://localhost:3000/" - params = getJP2HeaderInputParameters(id=9838343) - assert params.url == "https://localhost:3000/getJP2Header/" - - hvpy.set_api_url("https://api.beta.helioviewer.org/") - params = getJP2HeaderInputParameters(id=9838343) - assert params.url == "https://api.beta.helioviewer.org/getJP2Header/" - hvpy.set_api_url("https://api.helioviewer.org/v2/") diff --git a/hvpy/config.py b/hvpy/config.py new file mode 100644 index 0000000..492d436 --- /dev/null +++ b/hvpy/config.py @@ -0,0 +1,33 @@ +from pydantic import BaseSettings, Field + +__all__ = ["LiveSettings", "set_api_url", "get_api_url"] + + +class Settings(BaseSettings): + api_url: str = Field("https://api.helioviewer.org/v2/", env="HELIOVIEWER_API_URL") + + +def get_api_url() -> str: + """ + Returns the API URL. + """ + from hvpy.config import LiveSettings + + return LiveSettings.api_url + + +def set_api_url(url: str) -> None: + """ + Sets the API URL. + + Parameters + ---------- + url : str + Base API URL. + """ + from hvpy.config import LiveSettings + + LiveSettings.api_url = url + + +LiveSettings = Settings() diff --git a/hvpy/conftest.py b/hvpy/conftest.py new file mode 100644 index 0000000..8070f3f --- /dev/null +++ b/hvpy/conftest.py @@ -0,0 +1,23 @@ +import os + +import pytest + + +class SetEnv: + def __init__(self): + self.envars = set() + + def set(self, name, value): + self.envars.add(name) + os.environ[name] = value + + def clear(self): + for n in self.envars: + os.environ.pop(n) + + +@pytest.fixture +def env(): + setenv = SetEnv() + yield setenv + setenv.clear() diff --git a/hvpy/io.py b/hvpy/io.py index 3da2665..4b48767 100644 --- a/hvpy/io.py +++ b/hvpy/io.py @@ -1,13 +1,11 @@ -import os from enum import Enum, auto from typing import Any, Dict from pydantic import BaseModel -__all__ = ["HvpyParameters", "OutputType", "set_api_url"] +from hvpy.config import get_api_url - -_base_url = None +__all__ = ["HvpyParameters", "OutputType"] class OutputType(Enum): @@ -56,29 +54,4 @@ def url(self) -> str: """ Final API endpoint URL. """ - return get_api_url() + self.__class__.__name__[:-15] + "/" - - -def get_api_url() -> str: - """ - Returns the base API URL. - """ - if _base_url: - return _base_url - if "HELIOVIEWER_API_URL" in os.environ: - return os.environ["HELIOVIEWER_API_URL"] - return "https://api.helioviewer.org/v2/" - - -def set_api_url(url: str) -> None: - """ - Sets the base API URL. - - Parameters - ---------- - url : str - Base API URL. - """ - global _base_url - _base_url = url diff --git a/hvpy/tests/test_io.py b/hvpy/tests/test_io.py index deb0ec5..af6e2b7 100644 --- a/hvpy/tests/test_io.py +++ b/hvpy/tests/test_io.py @@ -1,3 +1,4 @@ +from hvpy import set_api_url from hvpy.io import HvpyParameters, OutputType @@ -9,3 +10,35 @@ def test_default_get_output_type_is_raw(): def test_url_property(): params = HvpyParameters() assert params.url == "https://api.helioviewer.org/v2//" + + +def test_set_url(): + # This is not safe if we ever decide to parallelize the tests. + params_first = HvpyParameters() + assert params_first.url == "https://api.helioviewer.org/v2//" + + set_api_url("https://api.beta.helioviewer.org/") + params_second = HvpyParameters() + assert params_second.url == "https://api.beta.helioviewer.org//" + assert params_first.url == params_second.url + + set_api_url("https://api.helioviewer.org/v2/") + + +def test_set_url_env(env): + env.set("HELIOVIEWER_API_URL", "https://fake_env_url/") + + # We need to instantiate a new Settings since the environmental variable + # is only read at init. Therefore using the live one in a test is tricky. + from hvpy.config import LiveSettings, Settings + + temp_config = Settings() + assert temp_config.api_url == "https://fake_env_url/" + assert temp_config.api_url != LiveSettings.api_url + + set_api_url("https://api.beta.helioviewer.org/") + params = HvpyParameters() + assert params.url == "https://api.beta.helioviewer.org//" + assert LiveSettings.api_url == "https://api.beta.helioviewer.org/" + + set_api_url("https://api.helioviewer.org/v2/") diff --git a/tox.ini b/tox.ini index 2e31e2c..5fefdaa 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{38,39,310}{,-online} + py{38,39,310} build_docs codestyle requires = @@ -12,7 +12,6 @@ isolated_build = true passenv = HOME WINDIR LC_ALL LC_CTYPE CC CI TRAVIS setenv = PYTEST_COMMAND = pytest -vvv -r a --pyargs hvpy --cov-report=xml --cov=hvpy --cov-config={toxinidir}/setup.cfg {toxinidir}/docs - HIDE_PARFIVE_PROGESS = True # Run the tests in a temporary directory to make sure that we don't import # the package from the source tree changedir = .tmp/{envname} @@ -25,8 +24,7 @@ extras = tests commands = pip freeze --all --no-input - !online: {env:PYTEST_COMMAND} {posargs} - online: {env:PYTEST_COMMAND} --remote-data=any {posargs} + {env:PYTEST_COMMAND} {posargs} [testenv:build_docs] changedir = docs