diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..e9a761a --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,33 @@ +name: Docs Build Check + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + docs: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.11"] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install sphinx sphinx-rtd-theme myst-parser + + - name: Build docs + run: | + cd docs + make html diff --git a/.gitignore b/.gitignore index a12902b..690ce09 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ build/ +docs/_build/ .venv/ .vscode/ *.egg-info/ diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..fa988b3 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,10 @@ +version: 2 + +sphinx: + configuration: docs/conf.py + +python: + install: + - requirements: requirements.txt + - method: pip + path: . diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..1fbc44e --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,21 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= -j auto +SPHINXBUILD ?= sphinx-build +SPHINXPROJ = RivRetrieve-Python +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for SPHINXOPTS. +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/api.rst b/docs/api.rst new file mode 100644 index 0000000..1e89b34 --- /dev/null +++ b/docs/api.rst @@ -0,0 +1,24 @@ +API Reference +============= + +.. automodule:: rivretrieve + :members: + +.. toctree:: + :maxdepth: 1 + :caption: Fetchers: + + fetchers/australia + fetchers/brazil + fetchers/canada + fetchers/chile + fetchers/czech + fetchers/france + fetchers/japan + fetchers/poland + fetchers/portugal + fetchers/slovenia + fetchers/southafrica + fetchers/uk_ea + fetchers/uk_nrfa + fetchers/usa diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..4c68239 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,71 @@ +import os +import re +import sys + +sys.path.insert(0, os.path.abspath("../")) + +project = "RivRetrieve-Python" +copyright = "2025, Frederik Kratzert" +author = "Frederik Kratzert" +release = "0.1.0" + +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.napoleon", + "sphinx.ext.viewcode", + "sphinx_rtd_theme", + "myst_parser", +] + +templates_path = ["_templates"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + +html_theme = "sphinx_rtd_theme" +html_static_path = ["_static"] + +source_suffix = { + ".rst": "restructuredtext", + ".md": "markdown", +} + +autodoc_default_options = { + "members": True, + "inherited-members": True, + "undoc-members": True, + "show-inheritance": True, +} + + +from rivretrieve import constants + + +def autodoc_process_docstring(app, what, name, obj, options, lines): + if not lines: + return + + new_lines = [] + + for line in lines: + matches = re.findall(r"constants\.([A-Z_]+)", line) + + for match in matches: + if hasattr(constants, match): + const_val = getattr(constants, match) + + line = line.replace(f"constants.{match}", f"'{const_val}'") + + new_lines.append(line) + + lines[:] = new_lines + + +def autodoc_skip_member(app, what, name, obj, skip, options): + # Skip class attributes that are all uppercase (likely constants) + if what == "class" and name.isupper() and not callable(obj): + return True + return skip + + +def setup(app): + app.connect("autodoc-process-docstring", autodoc_process_docstring) + app.connect("autodoc-skip-member", autodoc_skip_member) diff --git a/docs/fetchers/australia.rst b/docs/fetchers/australia.rst new file mode 100644 index 0000000..f762eb7 --- /dev/null +++ b/docs/fetchers/australia.rst @@ -0,0 +1,5 @@ +Australia Fetcher +================= + +.. automodule:: rivretrieve.australia + :members: diff --git a/docs/fetchers/brazil.rst b/docs/fetchers/brazil.rst new file mode 100644 index 0000000..c909db1 --- /dev/null +++ b/docs/fetchers/brazil.rst @@ -0,0 +1,5 @@ +Brazil Fetcher +============== + +.. automodule:: rivretrieve.brazil + :members: diff --git a/docs/fetchers/canada.rst b/docs/fetchers/canada.rst new file mode 100644 index 0000000..0041724 --- /dev/null +++ b/docs/fetchers/canada.rst @@ -0,0 +1,5 @@ +Canada Fetcher +============== + +.. automodule:: rivretrieve.canada + :members: diff --git a/docs/fetchers/chile.rst b/docs/fetchers/chile.rst new file mode 100644 index 0000000..d4ac13f --- /dev/null +++ b/docs/fetchers/chile.rst @@ -0,0 +1,5 @@ +Chile Fetcher +============= + +.. automodule:: rivretrieve.chile + :members: diff --git a/docs/fetchers/czech.rst b/docs/fetchers/czech.rst new file mode 100644 index 0000000..c2e20b1 --- /dev/null +++ b/docs/fetchers/czech.rst @@ -0,0 +1,5 @@ +Czech Fetcher +============= + +.. automodule:: rivretrieve.czech + :members: diff --git a/docs/fetchers/france.rst b/docs/fetchers/france.rst new file mode 100644 index 0000000..a29fddb --- /dev/null +++ b/docs/fetchers/france.rst @@ -0,0 +1,5 @@ +France Fetcher +============== + +.. automodule:: rivretrieve.france + :members: diff --git a/docs/fetchers/japan.rst b/docs/fetchers/japan.rst new file mode 100644 index 0000000..ea568d1 --- /dev/null +++ b/docs/fetchers/japan.rst @@ -0,0 +1,5 @@ +Japan Fetcher +============= + +.. automodule:: rivretrieve.japan + :members: diff --git a/docs/fetchers/poland.rst b/docs/fetchers/poland.rst new file mode 100644 index 0000000..c5f41d5 --- /dev/null +++ b/docs/fetchers/poland.rst @@ -0,0 +1,5 @@ +Poland Fetcher +============== + +.. automodule:: rivretrieve.poland + :members: diff --git a/docs/fetchers/portugal.rst b/docs/fetchers/portugal.rst new file mode 100644 index 0000000..a32c674 --- /dev/null +++ b/docs/fetchers/portugal.rst @@ -0,0 +1,5 @@ +Portugal Fetcher +================ + +.. automodule:: rivretrieve.portugal + :members: diff --git a/docs/fetchers/slovenia.rst b/docs/fetchers/slovenia.rst new file mode 100644 index 0000000..dafd23f --- /dev/null +++ b/docs/fetchers/slovenia.rst @@ -0,0 +1,5 @@ +Slovenia Fetcher +================ + +.. automodule:: rivretrieve.slovenia + :members: diff --git a/docs/fetchers/southafrica.rst b/docs/fetchers/southafrica.rst new file mode 100644 index 0000000..b845b98 --- /dev/null +++ b/docs/fetchers/southafrica.rst @@ -0,0 +1,5 @@ +South Africa Fetcher +==================== + +.. automodule:: rivretrieve.southafrica + :members: diff --git a/docs/fetchers/uk_ea.rst b/docs/fetchers/uk_ea.rst new file mode 100644 index 0000000..c20ca9e --- /dev/null +++ b/docs/fetchers/uk_ea.rst @@ -0,0 +1,5 @@ +UK EA Fetcher +============= + +.. automodule:: rivretrieve.uk_ea + :members: diff --git a/docs/fetchers/uk_nrfa.rst b/docs/fetchers/uk_nrfa.rst new file mode 100644 index 0000000..90c7bb1 --- /dev/null +++ b/docs/fetchers/uk_nrfa.rst @@ -0,0 +1,5 @@ +UK NRFA Fetcher +=============== + +.. automodule:: rivretrieve.uk_nrfa + :members: diff --git a/docs/fetchers/usa.rst b/docs/fetchers/usa.rst new file mode 100644 index 0000000..baed54b --- /dev/null +++ b/docs/fetchers/usa.rst @@ -0,0 +1,5 @@ +USA Fetcher +=========== + +.. automodule:: rivretrieve.usa + :members: diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..52fab05 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,16 @@ + +.. include:: ../README.md + :parser: myst_parser.sphinx_ + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + api + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/pyproject.toml b/pyproject.toml index e27c574..2c484ab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,4 +18,5 @@ select = [ [tool.ruff.lint.per-file-ignores] "rivretrieve/__init__.py" = ["F401"] -"rivretrieve/chile.py" = ["E501"] # The url is too long but can't be splitted. \ No newline at end of file +"rivretrieve/chile.py" = ["E501"] # The url is too long but can't be splitted. +"docs/conf.py" = ["E402"] # rivretrieve can't be imported before path is added. \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 75e242b..fef4e5c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,4 +11,7 @@ parameterized python-dotenv ruff tqdm -zarr>=3.0.7 \ No newline at end of file +zarr>=3.0.7 +sphinx>=8.0.0 +sphinx-rtd-theme>=3.0.0 +myst-parser>=4.0.0 \ No newline at end of file diff --git a/rivretrieve/australia.py b/rivretrieve/australia.py index 5dc6f6a..943306a 100644 --- a/rivretrieve/australia.py +++ b/rivretrieve/australia.py @@ -14,13 +14,27 @@ class AustraliaFetcher(base.RiverDataFetcher): - """Fetches river gauge data from Australia's BoM.""" + """Fetches river gauge data from Australia's Bureau of Meteorology (BoM). + + Data Source: Bureau of Meteorology Water Data Online (http://www.bom.gov.au/waterdata/) + + Supported Variables: + - ``constants.DISCHARGE_DAILY_MEAN`` (m³/s) + - ``constants.STAGE_DAILY_MEAN`` (m) + """ BOM_URL = "http://www.bom.gov.au/waterdata/services" @staticmethod def get_cached_metadata() -> pd.DataFrame: - """Retrieves a DataFrame of available Australian gauge IDs and metadata.""" + """Retrieves a DataFrame of available Australian gauge IDs and metadata. + + This method loads the metadata from a cached CSV file located in + the ``rivretrieve/cached_site_data/`` directory. + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ return utils.load_cached_metadata_csv("australia") @staticmethod @@ -160,7 +174,31 @@ def get_data( start_date: Optional[str] = None, end_date: Optional[str] = None, ) -> pd.DataFrame: - """Fetches and parses Australian river gauge data.""" + """Fetches and parses time series data for a specific gauge and variable. + + This method retrieves the requested data from the provider's API or data source, + parses it, and returns it in a standardized pandas DataFrame format. + + Args: + gauge_id: The site-specific identifier for the gauge. + variable: The variable to fetch. Must be one of the strings listed + in the fetcher's ``get_available_variables()`` output. + These are typically defined in ``rivretrieve.constants``. + start_date: Optional start date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched from the earliest available date. + end_date: Optional end date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched up to the latest available date. + + Returns: + pd.DataFrame: A pandas DataFrame indexed by datetime objects (``constants.TIME_INDEX``) + with a single column named after the requested ``variable``. The DataFrame + will be empty if no data is found for the given parameters. + + Raises: + ValueError: If the requested ``variable`` is not supported by this fetcher. + requests.exceptions.RequestException: If a network error occurs during data download. + Exception: For other unexpected errors during data fetching or parsing. + """ start_date = utils.format_start_date(start_date) end_date = utils.format_end_date(end_date) if variable not in self.get_available_variables(): diff --git a/rivretrieve/base.py b/rivretrieve/base.py index 5c8ec52..7846d0d 100644 --- a/rivretrieve/base.py +++ b/rivretrieve/base.py @@ -21,18 +21,30 @@ def get_data( start_date: Optional[str] = None, end_date: Optional[str] = None, ) -> pd.DataFrame: - """Fetches the time series data for the given variable and date range. + """Fetches and parses time series data for a specific gauge and variable. + + This method retrieves the requested data from the provider's API or data source, + parses it, and returns it in a standardized pandas DataFrame format. Args: gauge_id: The site-specific identifier for the gauge. - variable: The variable to fetch, should be one of the values from constants.py - (e.g., constants.DISCHARGE, constants.STAGE). - start_date: Optional start date in 'YYYY-MM-DD' format. - end_date: Optional end date in 'YYYY-MM-DD' format. + variable: The variable to fetch. Must be one of the strings listed + in the fetcher's ``get_available_variables()`` output. + These are typically defined in ``rivretrieve.constants``. + start_date: Optional start date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched from the earliest available date. + end_date: Optional end date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched up to the latest available date. Returns: - A pandas DataFrame indexed by time (constants.TIME_INDEX) with a column - for the requested variable (e.g., constants.DISCHARGE). + pd.DataFrame: A pandas DataFrame indexed by datetime objects (``constants.TIME_INDEX``) + with a single column named after the requested ``variable``. The DataFrame + will be empty if no data is found for the given parameters. + + Raises: + ValueError: If the requested ``variable`` is not supported by this fetcher. + requests.exceptions.RequestException: If a network error occurs during data download. + Exception: For other unexpected errors during data fetching or parsing. """ pass @@ -43,15 +55,20 @@ def get_cached_metadata() -> pd.DataFrame: pass def get_metadata(self) -> pd.DataFrame: - """Fetches site metadata for the given site. + """Fetches site metadata from the data provider. + + .. warning:: This method is not implemented for all fetchers. + Check the specific fetcher's documentation. Returns: - A pandas DataFrame indexed by gauge_id, containing site metadata. - Returns an empty DataFrame if metadata fetching is not supported for this fetcher. + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + + Raises: + NotImplementedError: If the method is not implemented for the specific fetcher. """ - # Default implementation returns an empty DataFrame. - # Subclasses should override this method if metadata is available. - raise NotImplementedError + # Default implementation raises NotImplementedError. + # Subclasses should override this method if live metadata fetching is available. + raise NotImplementedError(f"{self.__class__.__name__} does not support fetching live metadata.") @staticmethod @abc.abstractmethod diff --git a/rivretrieve/brazil.py b/rivretrieve/brazil.py index 9339182..d2383fd 100644 --- a/rivretrieve/brazil.py +++ b/rivretrieve/brazil.py @@ -23,7 +23,17 @@ class BrazilFetcher(base.RiverDataFetcher): - """Fetches river gauge data from Brazil's ANA Hidroweb API v2.""" + """Fetches river gauge data from Brazil's National Water and Sanitation Agency (ANA). + + Data Source: ANA Hidroweb API v2 (https://www.ana.gov.br/hidroweb/) + Requires credentials (username/password) which can be set in a ``.env`` file + in the ``rivretrieve`` directory or passed to the constructor. + Keys in ``.env``: ``ANA_USERNAME``, ``ANA_PASSWORD`` + + Supported Variables: + - ``constants.DISCHARGE_DAILY_MEAN`` (m³/s) + - ``constants.STAGE_DAILY_MEAN`` (m) + """ BASE_URL = "https://www.ana.gov.br/hidrowebservice/EstacoesTelemetricas" AUTH_URL = f"{BASE_URL}/OAUth/v1" @@ -43,7 +53,14 @@ def __init__(self, username: Optional[str] = None, password: Optional[str] = Non @staticmethod def get_cached_metadata() -> pd.DataFrame: - """Retrieves a DataFrame of available Brazilian gauge IDs and metadata.""" + """Retrieves a DataFrame of available Brazilian gauge IDs and metadata. + + This method loads the metadata from a cached CSV file located in + the ``rivretrieve/cached_site_data/`` directory. + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ return utils.load_cached_metadata_csv("brazil") @staticmethod @@ -51,7 +68,14 @@ def get_available_variables() -> tuple[str, ...]: return (constants.DISCHARGE_DAILY_MEAN, constants.STAGE_DAILY_MEAN) def get_metadata(self) -> pd.DataFrame: - """Fetches station metadata for all Brazilian states.""" + """Fetches station metadata for all Brazilian states from the ANA Hidroweb API. + + Data is fetched from the HidroInventarioEstacoes endpoint: + ``https://www.ana.gov.br/hidrowebservice/EstacoesTelemetricas/HidroInventarioEstacoes/v1`` + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ if not self.username or not self.password: logger.error("ANA Username or Password not provided.") return pd.DataFrame().set_index(constants.GAUGE_ID) @@ -300,7 +324,31 @@ def get_data( start_date: Optional[str] = None, end_date: Optional[str] = None, ) -> pd.DataFrame: - """Fetches and parses Brazilian river gauge data.""" + """Fetches and parses time series data for a specific gauge and variable. + + This method retrieves the requested data from the provider's API or data source, + parses it, and returns it in a standardized pandas DataFrame format. + + Args: + gauge_id: The site-specific identifier for the gauge. + variable: The variable to fetch. Must be one of the strings listed + in the fetcher's ``get_available_variables()`` output. + These are typically defined in ``rivretrieve.constants``. + start_date: Optional start date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched from the earliest available date. + end_date: Optional end date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched up to the latest available date. + + Returns: + pd.DataFrame: A pandas DataFrame indexed by datetime objects (``constants.TIME_INDEX``) + with a single column named after the requested ``variable``. The DataFrame + will be empty if no data is found for the given parameters. + + Raises: + ValueError: If the requested ``variable`` is not supported by this fetcher. + requests.exceptions.RequestException: If a network error occurs during data download. + Exception: For other unexpected errors during data fetching or parsing. + """ if not self.username or not self.password: logger.error("ANA Username or Password not provided. Check your .env file or constructor arguments.") return pd.DataFrame(columns=[constants.TIME_INDEX, variable]) diff --git a/rivretrieve/canada.py b/rivretrieve/canada.py index 3c0219b..f268805 100644 --- a/rivretrieve/canada.py +++ b/rivretrieve/canada.py @@ -20,7 +20,15 @@ class CanadaFetcher(base.RiverDataFetcher): - """Fetches river gauge data from Canada's HYDAT database.""" + """Fetches river gauge data from Canada's National Hydrometric Program (HYDAT). + + Data Source: HYDAT Database (https://collaboration.cmc.ec.gc.ca/cmc/hydrometrics/www/) + This fetcher downloads the entire HYDAT SQLite database on first use. + + Supported Variables: + - ``constants.DISCHARGE_DAILY_MEAN`` (m³/s) + - ``constants.STAGE_DAILY_MEAN`` (m) + """ HYDAT_URL = "https://collaboration.cmc.ec.gc.ca/cmc/hydrometrics/www/" DATA_DIR = Path(os.path.dirname(__file__)) / "data" @@ -28,7 +36,14 @@ class CanadaFetcher(base.RiverDataFetcher): @staticmethod def get_cached_metadata() -> pd.DataFrame: - """Retrieves a DataFrame of available Canadian gauge IDs and metadata.""" + """Retrieves a DataFrame of available Canadian gauge IDs and metadata. + + This method loads the metadata from a cached CSV file located in + the ``rivretrieve/cached_site_data/`` directory. + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ return utils.load_cached_metadata_csv("canada") @staticmethod @@ -122,7 +137,31 @@ def get_data( start_date: Optional[str] = None, end_date: Optional[str] = None, ) -> pd.DataFrame: - """Fetches data from the local HYDAT SQLite database.""" + """Fetches and parses time series data for a specific gauge and variable. + + This method retrieves the requested data from the provider's API or data source, + parses it, and returns it in a standardized pandas DataFrame format. + + Args: + gauge_id: The site-specific identifier for the gauge. + variable: The variable to fetch. Must be one of the strings listed + in the fetcher's ``get_available_variables()`` output. + These are typically defined in ``rivretrieve.constants``. + start_date: Optional start date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched from the earliest available date. + end_date: Optional end date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched up to the latest available date. + + Returns: + pd.DataFrame: A pandas DataFrame indexed by datetime objects (``constants.TIME_INDEX``) + with a single column named after the requested ``variable``. The DataFrame + will be empty if no data is found for the given parameters. + + Raises: + ValueError: If the requested ``variable`` is not supported by this fetcher. + requests.exceptions.RequestException: If a network error occurs during data download. + Exception: For other unexpected errors during data fetching or parsing. + """ start_date = utils.format_start_date(start_date) end_date = utils.format_end_date(end_date) diff --git a/rivretrieve/chile.py b/rivretrieve/chile.py index 368835a..47fea53 100644 --- a/rivretrieve/chile.py +++ b/rivretrieve/chile.py @@ -15,11 +15,24 @@ class ChileFetcher(base.RiverDataFetcher): - """Fetches river gauge data from Chile's CR2 explorador.""" + """Fetches river gauge data from Chile's CR2 explorador. + + Data Source: CR2 explorador (https://explorador.cr2.cl/) + + Supported Variables: + - ``constants.DISCHARGE_DAILY_MEAN`` (m³/s) + """ @staticmethod def get_cached_metadata() -> pd.DataFrame: - """Retrieves a DataFrame of available Chilean gauge IDs and metadata.""" + """Retrieves a DataFrame of available Chilean gauge IDs and metadata. + + This method loads the metadata from a cached CSV file located in + the ``rivretrieve/cached_site_data/`` directory. + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ return utils.load_cached_metadata_csv("chile") @staticmethod @@ -116,7 +129,31 @@ def get_data( start_date: Optional[str] = None, end_date: Optional[str] = None, ) -> pd.DataFrame: - """Fetches and parses Chilean river gauge data.""" + """Fetches and parses time series data for a specific gauge and variable. + + This method retrieves the requested data from the provider's API or data source, + parses it, and returns it in a standardized pandas DataFrame format. + + Args: + gauge_id: The site-specific identifier for the gauge. + variable: The variable to fetch. Must be one of the strings listed + in the fetcher's ``get_available_variables()`` output. + These are typically defined in ``rivretrieve.constants``. + start_date: Optional start date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched from the earliest available date. + end_date: Optional end date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched up to the latest available date. + + Returns: + pd.DataFrame: A pandas DataFrame indexed by datetime objects (``constants.TIME_INDEX``) + with a single column named after the requested ``variable``. The DataFrame + will be empty if no data is found for the given parameters. + + Raises: + ValueError: If the requested ``variable`` is not supported by this fetcher. + requests.exceptions.RequestException: If a network error occurs during data download. + Exception: For other unexpected errors during data fetching or parsing. + """ if variable != constants.DISCHARGE_DAILY_MEAN: logger.warning(f"ChileFetcher only supports variable='{constants.DISCHARGE_DAILY_MEAN}'") return pd.DataFrame(columns=[constants.TIME_INDEX, variable]) diff --git a/rivretrieve/czech.py b/rivretrieve/czech.py index 400e732..4935b7c 100644 --- a/rivretrieve/czech.py +++ b/rivretrieve/czech.py @@ -12,7 +12,18 @@ class CzechFetcher(base.RiverDataFetcher): - """Fetches river gauge data from Czech Republic's CHMI.""" + """Fetches river gauge data from the Czech Hydrometeorological Institute (CHMI). + + Data Source: CHMI Open Data Portal (https://opendata.chmi.cz/) + + Supported Variables: + - ``constants.DISCHARGE_DAILY_MEAN`` (m³/s) + - ``constants.STAGE_DAILY_MEAN`` (m) + - ``constants.WATER_TEMPERATURE_DAILY_MEAN`` (°C) + - ``constants.DISCHARGE_INSTANT`` (m³/s, hourly) + - ``constants.STAGE_INSTANT`` (m, hourly) + + """ METADATA_URL = "https://opendata.chmi.cz/hydrology/historical/metadata/meta1.json" DAILY_BASE_URL = "https://opendata.chmi.cz/hydrology/historical/data/daily/H_{id}_DQ_{year}.json" @@ -21,11 +32,25 @@ class CzechFetcher(base.RiverDataFetcher): @staticmethod def get_cached_metadata() -> pd.DataFrame: - """Retrieves a DataFrame of available Czech gauge IDs and metadata.""" + """Retrieves a DataFrame of available Czech gauge IDs and metadata. + + This method loads the metadata from a cached CSV file located in + the ``rivretrieve/cached_site_data/`` directory. + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ return utils.load_cached_metadata_csv("czech") def get_metadata(self) -> pd.DataFrame: - """Downloads and returns CHMI hydrological station metadata.""" + """Downloads and returns CHMI hydrological station metadata. + + Data is fetched from: + ``https://opendata.chmi.cz/hydrology/historical/metadata/meta1.json`` + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ logger.info(f"Fetching metadata from {self.METADATA_URL}") s = utils.requests_retry_session() try: @@ -186,7 +211,31 @@ def get_data( start_date: Optional[str] = None, end_date: Optional[str] = None, ) -> pd.DataFrame: - """Fetches and parses Czech river gauge data.""" + """Fetches and parses time series data for a specific gauge and variable. + + This method retrieves the requested data from the provider's API or data source, + parses it, and returns it in a standardized pandas DataFrame format. + + Args: + gauge_id: The site-specific identifier for the gauge. + variable: The variable to fetch. Must be one of the strings listed + in the fetcher's ``get_available_variables()`` output. + These are typically defined in ``rivretrieve.constants``. + start_date: Optional start date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched from the earliest available date. + end_date: Optional end date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched up to the latest available date. + + Returns: + pd.DataFrame: A pandas DataFrame indexed by datetime objects (``constants.TIME_INDEX``) + with a single column named after the requested ``variable``. The DataFrame + will be empty if no data is found for the given parameters. + + Raises: + ValueError: If the requested ``variable`` is not supported by this fetcher. + requests.exceptions.RequestException: If a network error occurs during data download. + Exception: For other unexpected errors during data fetching or parsing. + """ start_date = utils.format_start_date(start_date) end_date = utils.format_end_date(end_date) diff --git a/rivretrieve/france.py b/rivretrieve/france.py index 5aaadcd..dcfca8d 100644 --- a/rivretrieve/france.py +++ b/rivretrieve/france.py @@ -12,13 +12,27 @@ class FranceFetcher(base.RiverDataFetcher): - """Fetches river gauge data from France's Hubeau API.""" + """Fetches river gauge data from France's Hubeau API. + + Data Source: Hubeau (https://hubeau.eaufrance.fr/) + + Supported Variables: + - ``constants.DISCHARGE_DAILY_MEAN`` (m³/s) + - ``constants.STAGE_DAILY_MAX`` (m) + """ BASE_URL = "https://hubeau.eaufrance.fr/api/v2/hydrometrie/obs_elab" @staticmethod def get_cached_metadata() -> pd.DataFrame: - """Retrieves a DataFrame of available French gauge IDs and metadata.""" + """Retrieves a DataFrame of available French gauge IDs and metadata. + + This method loads the metadata from a cached CSV file located in + the ``rivretrieve/cached_site_data/`` directory. + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ return utils.load_cached_metadata_csv("french") # Note: CSV file name is french_sites.csv @staticmethod @@ -127,7 +141,31 @@ def get_data( start_date: Optional[str] = None, end_date: Optional[str] = None, ) -> pd.DataFrame: - """Fetches and parses French river gauge data.""" + """Fetches and parses time series data for a specific gauge and variable. + + This method retrieves the requested data from the provider's API or data source, + parses it, and returns it in a standardized pandas DataFrame format. + + Args: + gauge_id: The site-specific identifier for the gauge. + variable: The variable to fetch. Must be one of the strings listed + in the fetcher's ``get_available_variables()`` output. + These are typically defined in ``rivretrieve.constants``. + start_date: Optional start date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched from the earliest available date. + end_date: Optional end date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched up to the latest available date. + + Returns: + pd.DataFrame: A pandas DataFrame indexed by datetime objects (``constants.TIME_INDEX``) + with a single column named after the requested ``variable``. The DataFrame + will be empty if no data is found for the given parameters. + + Raises: + ValueError: If the requested ``variable`` is not supported by this fetcher. + requests.exceptions.RequestException: If a network error occurs during data download. + Exception: For other unexpected errors during data fetching or parsing. + """ start_date = utils.format_start_date(start_date) end_date = utils.format_end_date(end_date) diff --git a/rivretrieve/japan.py b/rivretrieve/japan.py index ea80911..06b24c6 100644 --- a/rivretrieve/japan.py +++ b/rivretrieve/japan.py @@ -16,13 +16,27 @@ class JapanFetcher(base.RiverDataFetcher): - """Fetches river gauge data from Japan's MLIT.""" + """Fetches river gauge data from Japan's Ministry of Land, Infrastructure, Transport and Tourism (MLIT). + + Data Source: Water Information System (http://www1.river.go.jp/) + + Supported Variables: + - ``constants.DISCHARGE_DAILY_MEAN`` (m³/s) + - ``constants.STAGE_DAILY_MEAN`` (m) + """ BASE_URL = "http://www1.river.go.jp/cgi-bin/DspWaterData.exe" @staticmethod def get_cached_metadata() -> pd.DataFrame: - """Retrieves a DataFrame of available Japanese gauge IDs and metadata.""" + """Retrieves a DataFrame of available Japanese gauge IDs and metadata. + + This method loads the metadata from a cached CSV file located in + the ``rivretrieve/cached_site_data/`` directory. + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ return utils.load_cached_metadata_csv("japan") @staticmethod @@ -152,7 +166,31 @@ def get_data( start_date: Optional[str] = None, end_date: Optional[str] = None, ) -> pd.DataFrame: - """Fetches and parses Japanese river gauge data.""" + """Fetches and parses time series data for a specific gauge and variable. + + This method retrieves the requested data from the provider's API or data source, + parses it, and returns it in a standardized pandas DataFrame format. + + Args: + gauge_id: The site-specific identifier for the gauge. + variable: The variable to fetch. Must be one of the strings listed + in the fetcher's ``get_available_variables()`` output. + These are typically defined in ``rivretrieve.constants``. + start_date: Optional start date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched from the earliest available date. + end_date: Optional end date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched up to the latest available date. + + Returns: + pd.DataFrame: A pandas DataFrame indexed by datetime objects (``constants.TIME_INDEX``) + with a single column named after the requested ``variable``. The DataFrame + will be empty if no data is found for the given parameters. + + Raises: + ValueError: If the requested ``variable`` is not supported by this fetcher. + requests.exceptions.RequestException: If a network error occurs during data download. + Exception: For other unexpected errors during data fetching or parsing. + """ start_date = utils.format_start_date(start_date) end_date = utils.format_end_date(end_date) if variable not in self.get_available_variables(): diff --git a/rivretrieve/poland.py b/rivretrieve/poland.py index b33894a..40af595 100644 --- a/rivretrieve/poland.py +++ b/rivretrieve/poland.py @@ -20,7 +20,17 @@ class PolandFetcher(base.RiverDataFetcher): - """Fetches river gauge data from Poland's IMGW.""" + """Fetches river gauge data from Poland's Institute of Meteorology and Water Management (IMGW). + + Data Source: IMGW Public Data (https://danepubliczne.imgw.pl/) + This fetcher downloads all historical data and caches it in a Zarr store + in ``rivretrieve/data/poland.zarr`` on first use. + + Supported Variables: + - ``constants.DISCHARGE_DAILY_MEAN`` (m³/s) + - ``constants.STAGE_DAILY_MEAN`` (m) + - ``constants.WATER_TEMPERATURE_DAILY_MEAN`` (°C) + """ BASE_URL = "https://danepubliczne.imgw.pl/data/dane_pomiarowo_obserwacyjne/dane_hydrologiczne/" CACHE_FILE = Path(os.path.dirname(__file__)) / "data" / "poland.zarr" @@ -31,7 +41,14 @@ class PolandFetcher(base.RiverDataFetcher): @staticmethod def get_metadata(): - """Downloads the metadata CSV file and converts it into a pandas DataFrame.""" + """Downloads the metadata CSV file from IMGW and converts it into a pandas DataFrame. + + Data is fetched from: + ``https://danepubliczne.imgw.pl/data/dane_pomiarowo_obserwacyjne/dane_hydrologiczne/lista_stacji_hydro.csv`` + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ logger.info(f"Downloading metadata from {PolandFetcher.METADATA_URL}") try: r = utils.requests_retry_session().get(PolandFetcher.METADATA_URL) @@ -65,7 +82,14 @@ def get_metadata(): @staticmethod def get_cached_metadata() -> pd.DataFrame: - """Loads cache metadata.""" + """Retrieves a DataFrame of available Polish gauge IDs and metadata. + + This method loads the metadata from a cached CSV file located in + the ``rivretrieve/cached_site_data/`` directory. + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ return utils.load_cached_metadata_csv("poland") @staticmethod @@ -226,7 +250,31 @@ def get_data( start_date: Optional[str] = None, end_date: Optional[str] = None, ) -> pd.DataFrame: - """Fetches and parses Polish river gauge data from cache or source.""" + """Fetches and parses time series data for a specific gauge and variable. + + This method retrieves the requested data from the provider's API or data source, + parses it, and returns it in a standardized pandas DataFrame format. + + Args: + gauge_id: The site-specific identifier for the gauge. + variable: The variable to fetch. Must be one of the strings listed + in the fetcher's ``get_available_variables()`` output. + These are typically defined in ``rivretrieve.constants``. + start_date: Optional start date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched from the earliest available date. + end_date: Optional end date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched up to the latest available date. + + Returns: + pd.DataFrame: A pandas DataFrame indexed by datetime objects (``constants.TIME_INDEX``) + with a single column named after the requested ``variable``. The DataFrame + will be empty if no data is found for the given parameters. + + Raises: + ValueError: If the requested ``variable`` is not supported by this fetcher. + requests.exceptions.RequestException: If a network error occurs during data download. + Exception: For other unexpected errors during data fetching or parsing. + """ start_date = utils.format_start_date(start_date) end_date = utils.format_end_date(end_date) diff --git a/rivretrieve/portugal.py b/rivretrieve/portugal.py index 2416db0..8307051 100644 --- a/rivretrieve/portugal.py +++ b/rivretrieve/portugal.py @@ -742,13 +742,27 @@ class PortugalFetcher(base.RiverDataFetcher): - """Fetches river gauge data from Portugal's SNIRH.""" + """Fetches river gauge data from Portugal's National Water Resources Information System (SNIRH). + + Data Source: SNIRH (https://snirh.apambiente.pt/) + + Supported Variables: + - ``constants.DISCHARGE_DAILY_MEAN`` (m³/s) + - ``constants.STAGE_DAILY_MEAN`` (m) + """ BASE_URL = "https://snirh.apambiente.pt/snirh/_dadosbase/site/janela_verdados.php" @staticmethod def get_cached_metadata() -> pd.DataFrame: - """Retrieves a DataFrame of available Portuguese gauge IDs and metadata.""" + """Retrieves a DataFrame of available Portuguese gauge IDs and metadata. + + This method loads the metadata from a cached CSV file located in + the ``rivretrieve/cached_site_data/`` directory. + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ return utils.load_cached_metadata_csv("portugal") @staticmethod @@ -834,7 +848,31 @@ def get_data( start_date: Optional[str] = None, end_date: Optional[str] = None, ) -> pd.DataFrame: - """Fetches and parses Portuguese river gauge data.""" + """Fetches and parses time series data for a specific gauge and variable. + + This method retrieves the requested data from the provider's API or data source, + parses it, and returns it in a standardized pandas DataFrame format. + + Args: + gauge_id: The site-specific identifier for the gauge. + variable: The variable to fetch. Must be one of the strings listed + in the fetcher's ``get_available_variables()`` output. + These are typically defined in ``rivretrieve.constants``. + start_date: Optional start date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched from the earliest available date. + end_date: Optional end date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched up to the latest available date. + + Returns: + pd.DataFrame: A pandas DataFrame indexed by datetime objects (``constants.TIME_INDEX``) + with a single column named after the requested ``variable``. The DataFrame + will be empty if no data is found for the given parameters. + + Raises: + ValueError: If the requested ``variable`` is not supported by this fetcher. + requests.exceptions.RequestException: If a network error occurs during data download. + Exception: For other unexpected errors during data fetching or parsing. + """ start_date = utils.format_start_date(start_date) end_date = utils.format_end_date(end_date) diff --git a/rivretrieve/slovenia.py b/rivretrieve/slovenia.py index 6e6adc1..647f3f7 100644 --- a/rivretrieve/slovenia.py +++ b/rivretrieve/slovenia.py @@ -14,13 +14,27 @@ class SloveniaFetcher(base.RiverDataFetcher): - """Fetches river gauge data from Slovenia's ARSO API.""" + """Fetches river gauge data from Slovenia's Environmental Agency (ARSO). + + Data Source: ARSO (https://vode.arso.gov.si/) + + Supported Variables: + - ``constants.DISCHARGE_DAILY_MEAN`` (m³/s) + - ``constants.STAGE_DAILY_MEAN`` (m) + """ BASE_URL = "https://vode.arso.gov.si/hidarhiv/pov_arhiv_tab.php" @staticmethod def get_cached_metadata() -> pd.DataFrame: - """Retrieves a DataFrame of available Slovenian gauge IDs and metadata.""" + """Retrieves a DataFrame of available Slovenian gauge IDs and metadata. + + This method loads the metadata from a cached CSV file located in + the ``rivretrieve/cached_site_data/`` directory. + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ return utils.load_cached_metadata_csv("slovenia") @staticmethod @@ -99,7 +113,31 @@ def get_data( start_date: Optional[str] = None, end_date: Optional[str] = None, ) -> pd.DataFrame: - """Fetches and parses Slovenian river gauge data.""" + """Fetches and parses time series data for a specific gauge and variable. + + This method retrieves the requested data from the provider's API or data source, + parses it, and returns it in a standardized pandas DataFrame format. + + Args: + gauge_id: The site-specific identifier for the gauge. + variable: The variable to fetch. Must be one of the strings listed + in the fetcher's ``get_available_variables()`` output. + These are typically defined in ``rivretrieve.constants``. + start_date: Optional start date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched from the earliest available date. + end_date: Optional end date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched up to the latest available date. + + Returns: + pd.DataFrame: A pandas DataFrame indexed by datetime objects (``constants.TIME_INDEX``) + with a single column named after the requested ``variable``. The DataFrame + will be empty if no data is found for the given parameters. + + Raises: + ValueError: If the requested ``variable`` is not supported by this fetcher. + requests.exceptions.RequestException: If a network error occurs during data download. + Exception: For other unexpected errors during data fetching or parsing. + """ start_date = utils.format_start_date(start_date) end_date = utils.format_end_date(end_date) diff --git a/rivretrieve/southafrica.py b/rivretrieve/southafrica.py index a28da4a..8746f7c 100644 --- a/rivretrieve/southafrica.py +++ b/rivretrieve/southafrica.py @@ -16,13 +16,28 @@ class SouthAfricaFetcher(base.RiverDataFetcher): - """Fetches river gauge data from South Africa's DWS.""" + """Fetches river gauge data from South Africa's Department of Water and Sanitation (DWS). + + Data Source: DWS Hydrology Services (https://www.dws.gov.za/Hydrology/Verified/HyData.aspx) + + Supported Variables: + - ``constants.DISCHARGE_DAILY_MEAN`` (m³/s) + - ``constants.DISCHARGE_INSTANT`` (m³/s) + - ``constants.STAGE_INSTANT`` (m) + """ BASE_URL = "https://www.dws.gov.za/Hydrology/Verified/HyData.aspx" @staticmethod def get_cached_metadata() -> pd.DataFrame: - """Retrieves a DataFrame of available South African gauge IDs and metadata.""" + """Retrieves a DataFrame of available South African gauge IDs and metadata. + + This method loads the metadata from a cached CSV file located in + the ``rivretrieve/cached_site_data/`` directory. + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ return utils.load_cached_metadata_csv("southAfrican") @staticmethod @@ -176,7 +191,31 @@ def get_data( start_date: Optional[str] = None, end_date: Optional[str] = None, ) -> pd.DataFrame: - """Fetches and parses South African river gauge data.""" + """Fetches and parses time series data for a specific gauge and variable. + + This method retrieves the requested data from the provider's API or data source, + parses it, and returns it in a standardized pandas DataFrame format. + + Args: + gauge_id: The site-specific identifier for the gauge. + variable: The variable to fetch. Must be one of the strings listed + in the fetcher's ``get_available_variables()`` output. + These are typically defined in ``rivretrieve.constants``. + start_date: Optional start date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched from the earliest available date. + end_date: Optional end date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched up to the latest available date. + + Returns: + pd.DataFrame: A pandas DataFrame indexed by datetime objects (``constants.TIME_INDEX``) + with a single column named after the requested ``variable``. The DataFrame + will be empty if no data is found for the given parameters. + + Raises: + ValueError: If the requested ``variable`` is not supported by this fetcher. + requests.exceptions.RequestException: If a network error occurs during data download. + Exception: For other unexpected errors during data fetching or parsing. + """ start_date = utils.format_start_date(start_date) end_date = utils.format_end_date(end_date) if variable not in self.get_available_variables(): diff --git a/rivretrieve/uk_ea.py b/rivretrieve/uk_ea.py index 0c67329..b7160dc 100644 --- a/rivretrieve/uk_ea.py +++ b/rivretrieve/uk_ea.py @@ -13,7 +13,14 @@ class UKEAFetcher(base.RiverDataFetcher): - """Fetches river gauge data from the UK Environment Agency.""" + """Fetches river gauge data from the UK Environment Agency (EA). + + Data Source: Environment Agency Hydrology API (https://environment.data.gov.uk/hydrology/) + + Supported Variables: + - ``constants.DISCHARGE_DAILY_MEAN`` (m³/s) + - ``constants.STAGE_INSTANT`` (m) + """ BASE_URL = "http://environment.data.gov.uk" @@ -29,7 +36,14 @@ class UKEAFetcher(base.RiverDataFetcher): @staticmethod def get_cached_metadata() -> pd.DataFrame: - """Retrieves a DataFrame of available UK gauge IDs and metadata.""" + """Retrieves a DataFrame of available UK Environment Agency gauge IDs and metadata. + + This method loads the metadata from a cached CSV file located in + the ``rivretrieve/cached_site_data/`` directory. + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ return utils.load_cached_metadata_csv("uk_ea") @staticmethod @@ -39,6 +53,9 @@ def get_available_variables() -> tuple[str, ...]: def get_metadata(self) -> pd.DataFrame: """Fetches site metadata for all stations from the EA API. + Data is fetched from: + ``http://environment.data.gov.uk/hydrology/id/stations.json`` + Returns: A pandas DataFrame indexed by gauge_id, containing site metadata. """ @@ -162,7 +179,31 @@ def get_data( start_date: Optional[str] = None, end_date: Optional[str] = None, ) -> pd.DataFrame: - """Fetches and parses UK river gauge data.""" + """Fetches and parses time series data for a specific gauge and variable. + + This method retrieves the requested data from the provider's API or data source, + parses it, and returns it in a standardized pandas DataFrame format. + + Args: + gauge_id: The site-specific identifier for the gauge. + variable: The variable to fetch. Must be one of the strings listed + in the fetcher's ``get_available_variables()`` output. + These are typically defined in ``rivretrieve.constants``. + start_date: Optional start date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched from the earliest available date. + end_date: Optional end date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched up to the latest available date. + + Returns: + pd.DataFrame: A pandas DataFrame indexed by datetime objects (``constants.TIME_INDEX``) + with a single column named after the requested ``variable``. The DataFrame + will be empty if no data is found for the given parameters. + + Raises: + ValueError: If the requested ``variable`` is not supported by this fetcher. + requests.exceptions.RequestException: If a network error occurs during data download. + Exception: For other unexpected errors during data fetching or parsing. + """ start_date = utils.format_start_date(start_date) end_date = utils.format_end_date(end_date) if variable not in self.get_available_variables(): diff --git a/rivretrieve/uk_nrfa.py b/rivretrieve/uk_nrfa.py index f6f6413..a32ebd8 100644 --- a/rivretrieve/uk_nrfa.py +++ b/rivretrieve/uk_nrfa.py @@ -12,7 +12,14 @@ class UKNRFAFetcher(base.RiverDataFetcher): - """Fetches river gauge data from the UK National River Flow Archive.""" + """Fetches river gauge data from the UK National River Flow Archive (NRFA). + + Data Source: NRFA API (https://nrfaapps.ceh.ac.uk/nrfa/ws) + + Supported Variables: + - ``constants.DISCHARGE_DAILY_MEAN`` (m³/s) + - ``constants.CATCHMENT_PRECIPITATION_DAILY_SUM`` (mm) + """ BASE_URL = "https://nrfaapps.ceh.ac.uk/nrfa/ws" GAUGE_ID_COL = "id" @@ -29,11 +36,25 @@ class UKNRFAFetcher(base.RiverDataFetcher): @staticmethod def get_cached_metadata() -> pd.DataFrame: - """Retrieves a DataFrame of available NRFA gauge IDs from the cached CSV.""" + """Retrieves a DataFrame of available UK NRFA gauge IDs and metadata. + + This method loads the metadata from a cached CSV file located in + the ``rivretrieve/cached_site_data/`` directory. + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ return utils.load_cached_metadata_csv("uk_nrfa") def get_metadata(self) -> pd.DataFrame: - """Fetches site metadata from the NRFA API and renames columns.""" + """Fetches site metadata from the NRFA API and renames columns. + + Data is fetched from: + ``https://nrfaapps.ceh.ac.uk/nrfa/ws/station-info`` + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ query_params = {"station": "*", "format": "json-object", "fields": "all"} try: s = utils.requests_retry_session() @@ -114,7 +135,31 @@ def get_data( start_date: Optional[str] = None, end_date: Optional[str] = None, ) -> pd.DataFrame: - """Fetches and parses UK NRFA river gauge data.""" + """Fetches and parses time series data for a specific gauge and variable. + + This method retrieves the requested data from the provider's API or data source, + parses it, and returns it in a standardized pandas DataFrame format. + + Args: + gauge_id: The site-specific identifier for the gauge. + variable: The variable to fetch. Must be one of the strings listed + in the fetcher's ``get_available_variables()`` output. + These are typically defined in ``rivretrieve.constants``. + start_date: Optional start date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched from the earliest available date. + end_date: Optional end date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched up to the latest available date. + + Returns: + pd.DataFrame: A pandas DataFrame indexed by datetime objects (``constants.TIME_INDEX``) + with a single column named after the requested ``variable``. The DataFrame + will be empty if no data is found for the given parameters. + + Raises: + ValueError: If the requested ``variable`` is not supported by this fetcher. + requests.exceptions.RequestException: If a network error occurs during data download. + Exception: For other unexpected errors during data fetching or parsing. + """ if variable not in self.get_available_variables(): raise ValueError(f"Unsupported variable: {variable}") diff --git a/rivretrieve/usa.py b/rivretrieve/usa.py index d638e6c..e35bed8 100644 --- a/rivretrieve/usa.py +++ b/rivretrieve/usa.py @@ -12,11 +12,30 @@ class USAFetcher(base.RiverDataFetcher): - """Fetches river gauge data from USGS NWIS.""" + """Fetches river gauge data from the US Geological Survey (USGS) National Water Information System (NWIS). + + Data Source: USGS NWIS (https://waterservices.usgs.gov/) + This fetcher uses the ``dataretrieval`` package. + + Supported Variables: + - ``constants.DISCHARGE_DAILY_MEAN`` (m³/s) + - ``constants.DISCHARGE_INSTANT`` (m³/s) + - ``constants.STAGE_DAILY_MEAN`` (m) + - ``constants.STAGE_DAILY_MAX`` (m) + - ``constants.STAGE_DAILY_MIN`` (m) + - ``constants.STAGE_INSTANT`` (m) + """ @staticmethod def get_cached_metadata() -> pd.DataFrame: - """Retrieves a DataFrame of available USA gauge IDs and metadata.""" + """Retrieves a DataFrame of available USA gauge IDs and metadata. + + This method loads the metadata from a cached CSV file located in + the ``rivretrieve/cached_site_data/`` directory. + + Returns: + pd.DataFrame: A DataFrame indexed by gauge_id, containing site metadata. + """ return utils.load_cached_metadata_csv("usa") @staticmethod @@ -111,7 +130,31 @@ def get_data( start_date: Optional[str] = None, end_date: Optional[str] = None, ) -> pd.DataFrame: - """Fetches and parses USA river gauge data.""" + """Fetches and parses time series data for a specific gauge and variable. + + This method retrieves the requested data from the provider's API or data source, + parses it, and returns it in a standardized pandas DataFrame format. + + Args: + gauge_id: The site-specific identifier for the gauge. + variable: The variable to fetch. Must be one of the strings listed + in the fetcher's ``get_available_variables()`` output. + These are typically defined in ``rivretrieve.constants``. + start_date: Optional start date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched from the earliest available date. + end_date: Optional end date for the data retrieval in 'YYYY-MM-DD' format. + If None, data is fetched up to the latest available date. + + Returns: + pd.DataFrame: A pandas DataFrame indexed by datetime objects (``constants.TIME_INDEX``) + with a single column named after the requested ``variable``. The DataFrame + will be empty if no data is found for the given parameters. + + Raises: + ValueError: If the requested ``variable`` is not supported by this fetcher. + requests.exceptions.RequestException: If a network error occurs during data download. + Exception: For other unexpected errors during data fetching or parsing. + """ start_date = utils.format_start_date(start_date) end_date = utils.format_end_date(end_date) if variable not in self.get_available_variables():