Repository navigation
Remove the deprecated nwis module (without the STA8 copy edits) - #458
thodson-usgs wants to merge 7 commits into
Conversation
Remove dataretrieval.nwis ahead of its 2027-05-06 horizon. USGS is decommissioning the waterservices endpoints it called, and every getter has a waterdata (or nwdc) replacement. - Delete dataretrieval/nwis.py, its tests and fixtures, and its reference page. - Remove NoSitesError (only the waterservices path raised it) and the "No sites/data" body check in _querying; remove REMOVALS["nwis"] and the now-unused _validation.require_any_of. - Drop nwis from .importlinter (layers + nwis-quarantine contract), pyproject, pre-commit comments, and the pyscn clone baseline. - Port demos: the defunct hydroshare water-use notebook is rewritten on nwdc.get_wateruse (USGS_NWDC_WaterUse_Examples); the nwqn_data_pull scripts use waterdata.get_monitoring_locations / get_daily; copy-edit notebooks that still described nwis as current. - Docs: add missing nblinks for USGS_WaterUse_Examples and USGS_NLDI_Examples; update README, NEWS, CONTEXT, AGENTS, CONTRIBUTING, the architecture overview, and mark ADR 0005 completed. BREAKING CHANGE: `import dataretrieval.nwis` raises ModuleNotFoundError, and dataretrieval.NoSitesError / exceptions.NoSitesError are removed.
- Drop the retry wrapper the NWQN demo put around waterdata.get_monitoring_locations, which already retries; carry USGS- IDs end to end instead of stripping and re-adding the prefix; delete the agency_code filter that no longer removes anything. - Delete the ignore-variadic-names ruff exemption: with it off, ARG001 reports nothing. - Use the glossary's "single-shot" instead of the new "single-request", and state shared-module rules without hand-written adapter lists (one said NGWMN never receives the key). - Replace the WQP-specific URL-too-long pseudo-code with a remedy that holds for every caller; make the format_datetime warning name the columns to check rather than the nonexistent datetime_index. - Move the ADR "Note (2026-10)" paragraphs into each record's Notes with an amended Status (ADR 0000); restore ADR 0010's decision-time survey; correct ADR 0003's note, which said rules still present were deleted. - Document that utils.query does not retry, the statement the removal deleted along with its NWIS rationale. - Remove a duplicate URL-too-long test, the NWIS payload in test_header, and the hard-coded wateruse horizon in the deprecation test. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
find_neighboring_sites already fetched every neighbor's monitoring location to filter by drainage area, then returned only the IDs, so the streamflow script requested the same rows again. It now returns the frame; only the BAD_NLDI_SITES branch fetches on its own. The streamflow get_daily call requests only the three columns the script reads, and the unused update_dataframe(overwrite=) parameter and project locals are gone. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Restore dataretrieval/nwis.py as a stub that raises ImportError on import, so every spelling (import dataretrieval.nwis, from dataretrieval import nwis, from dataretrieval.nwis import get_dv) names the waterdata replacements and the last release that ships the module: pip install "dataretrieval==1.4.0". NEWS, CONTEXT, and ADR 0005 say the same, and .importlinter places the stub in the top layer. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Point to the waterdata and nwdc modules instead of listing each getter, matching the nwis ImportError. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
| and ``dataretrieval.waterdata.ratings`` use. Callers layer their own | ||
| post-processing (NWIS-specific datetime indexing, ratings-specific | ||
| ``df.attrs`` provenance, etc.) on top of the raw frame. | ||
| This module exposes the parsing primitives. Callers layer their own |
There was a problem hiding this comment.
| This module exposes the parsing primitives. Callers layer their own | |
| This module exposes the parsing primitives used by ``dataretrieval.waterdata.get_ratings``. Callers layer their own |
| "# USGS dataretrieval Python Package Peak Streamflow Examples\n", | ||
| "\n", | ||
| "This notebook provides examples of using the Python dataretrieval package to retrieve annual peak streamflow data for United States Geological Survey (USGS) monitoring locations using the **USGS Water Data API** via the `waterdata` module. The `waterdata` module is the recommended way to access USGS water data and replaces the deprecated `nwis` module." | ||
| "This notebook provides examples of using the Python dataretrieval package to retrieve annual peak streamflow data for United States Geological Survey (USGS) monitoring locations using the **USGS Water Data API** via the `waterdata` module. The `waterdata` module is the recommended way to access USGS water data." |
There was a problem hiding this comment.
| "This notebook provides examples of using the Python dataretrieval package to retrieve annual peak streamflow data for United States Geological Survey (USGS) monitoring locations using the **USGS Water Data API** via the `waterdata` module. The `waterdata` module is the recommended way to access USGS water data." | |
| "This notebook provides examples of using the Python dataretrieval package to retrieve annual peak streamflow data for United States Geological Survey (USGS) monitoring locations using the **USGS Water Data API** via the `waterdata` module." |
| "# USGS dataretrieval Python Package Rating Curve Examples\n", | ||
| "\n", | ||
| "This notebook provides examples of using the Python dataretrieval package to retrieve stage–discharge rating curve data for United States Geological Survey (USGS) streamgages using the **USGS Water Data API** via the `waterdata` module. The `waterdata` module is the recommended way to access USGS water data and replaces the deprecated `nwis` module.\n", | ||
| "This notebook provides examples of using the Python dataretrieval package to retrieve stage–discharge rating curve data for United States Geological Survey (USGS) streamgages using the **USGS Water Data API** via the `waterdata` module. The `waterdata` module is the recommended way to access USGS water data.\n", |
There was a problem hiding this comment.
| "This notebook provides examples of using the Python dataretrieval package to retrieve stage–discharge rating curve data for United States Geological Survey (USGS) streamgages using the **USGS Water Data API** via the `waterdata` module. The `waterdata` module is the recommended way to access USGS water data.\n", | |
| "This notebook provides examples of using the Python dataretrieval package to retrieve stage–discharge rating curve data for United States Geological Survey (USGS) streamgages using the **USGS Water Data API** via the `waterdata` module.\n", |
| "# USGS dataretrieval Python Package Statistics Examples\n", | ||
| "\n", | ||
| "This notebook provides examples of using the Python dataretrieval package to retrieve summary statistics for observed variables at a United States Geological Survey (USGS) monitoring location using the **USGS Water Data API** via the `waterdata` module. The `waterdata` module is the recommended way to access USGS water data and replaces the deprecated `nwis` module.\n", | ||
| "This notebook provides examples of using the Python dataretrieval package to retrieve summary statistics for observed variables at a United States Geological Survey (USGS) monitoring location using the **USGS Water Data API** via the `waterdata` module. The `waterdata` module is the recommended way to access USGS water data.\n", |
There was a problem hiding this comment.
| "This notebook provides examples of using the Python dataretrieval package to retrieve summary statistics for observed variables at a United States Geological Survey (USGS) monitoring location using the **USGS Water Data API** via the `waterdata` module. The `waterdata` module is the recommended way to access USGS water data.\n", | |
| "This notebook provides examples of using the Python dataretrieval package to retrieve summary statistics for observed variables at a United States Geological Survey (USGS) monitoring location using the **USGS Water Data API** via the `waterdata` module.\n", |
| The ``waterdata`` module will replace the ``nwis`` module as the primary | ||
| set of data download functions for USGS water data. This Jupyter notebook | ||
| covers a basic introduction to module functions and usage. | ||
| The ``waterdata`` module is the primary set of data download functions for |
There was a problem hiding this comment.
| The ``waterdata`` module is the primary set of data download functions for | |
| The ``waterdata`` module contains the set of data download functions for |
| def test_key_excluded_for_external_host(self): | ||
| """The key is not added for an external (non-USGS) host.""" | ||
| url = "https://nwis.waterservices.usgs.gov/nwis/iv/" | ||
| url = "https://example.invalid/data/" |
There was a problem hiding this comment.
Why was this changed? Because nwis.waterservices.... is still in existence?
|
|
||
| def test_query_nldi_opts_into_retry(monkeypatch): | ||
| """NLDI explicitly enables shared retry while NWIS remains unchanged.""" | ||
| """NLDI explicitly enables shared retry while the default path stays unchanged.""" |
There was a problem hiding this comment.
Does it make sense to refactor the architecture supporting these endpoints ("the default path") now that nwis is gone, or is the architecture still robust with the remaining endpoints?
| } | ||
| response = utils.query(url, payload) | ||
| httpx_mock.add_response(method="GET") | ||
| response = utils.query("https://example.invalid/x", {"a": "1"}) |
There was a problem hiding this comment.
Is this really what we want/need? Seems like it used to test a "valid" url and now it's testing an invalid one?
| @@ -1,3 +1,5 @@ | |||
| **10/22/2026:** **Breaking change:** `dataretrieval.nwis` is removed, ahead of its 2027-05-06 horizon, because USGS is [decommissioning the legacy waterservices endpoints](https://waterdata.usgs.gov/blog/api-waterservices-decom/) the module called. `import dataretrieval.nwis` (or any import from it) now raises `ImportError`. Use `waterdata` instead, or `nwdc` for water use. To keep using `nwis` while the waterservices endpoints remain online, pin the last release that includes it: `pip install "dataretrieval<=1.4.0"`. **Breaking change:** `dataretrieval.exceptions.NoSitesError` (and its `dataretrieval.NoSitesError` re-export) is removed; only the waterservices path raised it, and the modern getters return an empty `DataFrame` when nothing matches. The other published deprecations are unchanged and remain on their horizons: the `get_time_series_metadata()` v0 filters (`begin_utc`, `end_utc`, `state`, `state_name`, `hydrologic_unit_code`) on or after 2027-06-01, `get_cql(service=)` on or after 2027-08-09, the `wateruse` module alias on or after 2027-08-11, and `ogc.interruptions` on or after 2027-08-25. | |||
There was a problem hiding this comment.
| **10/22/2026:** **Breaking change:** `dataretrieval.nwis` is removed, ahead of its 2027-05-06 horizon, because USGS is [decommissioning the legacy waterservices endpoints](https://waterdata.usgs.gov/blog/api-waterservices-decom/) the module called. `import dataretrieval.nwis` (or any import from it) now raises `ImportError`. Use `waterdata` instead, or `nwdc` for water use. To keep using `nwis` while the waterservices endpoints remain online, pin the last release that includes it: `pip install "dataretrieval<=1.4.0"`. **Breaking change:** `dataretrieval.exceptions.NoSitesError` (and its `dataretrieval.NoSitesError` re-export) is removed; only the waterservices path raised it, and the modern getters return an empty `DataFrame` when nothing matches. The other published deprecations are unchanged and remain on their horizons: the `get_time_series_metadata()` v0 filters (`begin_utc`, `end_utc`, `state`, `state_name`, `hydrologic_unit_code`) on or after 2027-06-01, `get_cql(service=)` on or after 2027-08-09, the `wateruse` module alias on or after 2027-08-11, and `ogc.interruptions` on or after 2027-08-25. | |
| **10/22/2026:** **Breaking change:** `dataretrieval.nwis` is removed, ahead of its 2027-02-22 horizon, because USGS is [decommissioning the legacy waterservices endpoints](https://waterdata.usgs.gov/blog/api-waterservices-decom/) the module called. `import dataretrieval.nwis` (or any import from it) now raises `ImportError`. Use `waterdata` instead, or `nwdc` for water use. To keep using `nwis` while the waterservices endpoints remain online, pin the last release that includes it: `pip install "dataretrieval<=1.4.0"`. **Breaking change:** `dataretrieval.exceptions.NoSitesError` (and its `dataretrieval.NoSitesError` re-export) is removed; only the waterservices path raised it, and the modern getters return an empty `DataFrame` when nothing matches. The other published deprecations are unchanged and remain on their horizons: the `get_time_series_metadata()` v0 filters (`begin_utc`, `end_utc`, `state`, `state_name`, `hydrologic_unit_code`) on or after 2027-06-01, `get_cql(service=)` on or after 2027-08-09, the `wateruse` module alias on or after 2027-08-11, and `ogc.interruptions` on or after 2027-08-25. |
|
Opened a PR that addresses a use case where someone might try loading the nwis module via |
This is #457 without its two STA8 copy-edit commits (
a87052e5,a99c0763), which touch 71 files unrelated to the nwis removal and are hard to review alongside it. The other seven commits are cherry-picked unchanged. Apart from those copy edits, the tree is identical to #457.Summary
This removes
dataretrieval.nwisbefore its published 2027-05-06 horizon, as part of the next major release. USGS is decommissioning the waterservices endpoints the module called, and every getter in it already has awaterdataornwdcreplacement.Breaking:
dataretrieval.nwisin any form (import dataretrieval.nwis,from dataretrieval import nwis,from dataretrieval.nwis import get_dv) raisesImportError. The message points towaterdata(andnwdcfor water use) and says how to keep using nwis while the endpoints are still online:pip install "dataretrieval<=1.4.0".nwis.pyis now a stub that does nothing except raise that error. NEWS gives the same pin.NoSitesErroris removed, bothdataretrieval.NoSitesErrorandexceptions.NoSitesError. Only the waterservices path raised it. The modern getters return an empty DataFrame when nothing matches.Code
nwis.py, deletedtests/nwis_test.py,tests/waterservices_test.py, and 9 fixtures used only by those tests.REMOVALS["nwis"], the"No sites/data"body check in_querying, and_validation.require_any_of, whose only caller was nwis..importlinter: dropped nwis from the layers contract and deleted thenwis-quarantinecontract. Also updated the pyproject comment, the pre-commit comments, and the pyscn clone baseline.utils.query, the deprecation mechanism) so they call that code directly.rdb.read_rdb's HTML-response message used to tell callers to migrate to waterdata. Onlywaterdata.get_ratingsreaches it now, so the message asks them to report the moved endpoint instead.Notebooks and demos
hydroshare/USGS_NWIS_WaterUse_Examples.ipynbwas defunct and couldn't run. It is rewritten onnwdc.get_wateruseand renamedUSGS_NWDC_WaterUse_Examples.ipynb.nwqn_data_pullscripts now usewaterdata.get_monitoring_locationsandget_daily. Approval filtering happens on the server (approval_status="Approved") instead of matching the old NWIS_cdstrings.USGS_WaterUse_Examplesandhydroshare/USGS_NLDI_Examples. Updatedexamples/index.rst.Prose
userguide/dataportals.rst.Other deprecations evaluated
None of the other published horizons is earlier than May 2027, so they all stay. They are listed in the NEWS entry:
get_time_series_metadatav0 filtersget_cql(service=)waterusealiasogc.interruptionsThe camelCase
get_sampleskwargs have no horizon published.Remaining "NWIS" mentions (intentional)
providers=NWIS, NLDInwissite/nwisgw, NGWMNorganization_type="NWIS", the USGS NWIS time-zone code list, and docstrings saying site numbers are assigned by NWIS.readNWIS*calls quoted in the R-vignette notebook comments.Testing
Run on this branch:
ruff check,ruff format --check,lint-imports(7 kept, 0 broken),xenon, andcomplexipyall pass.pytest: 1652 passed. Branch coverage is 99.07%, abovefail_under98.9.mypy --python-version 3.12reports no issues in 61 source files.import dataretrieval.nwisraises theImportErrorthat nameswaterdata,nwdc, and thedataretrieval<=1.4.0pin.Run on #457 and not repeated on this branch:
make htmlsucceeds and the executed notebooks render. The only cell errors areNetworkErrors on WQP calls inrvignettesandDiscreteSamples, caused by a local SSL problem that also reproduces with a barehttpx.get.retrieve_nwqn_streamflow.map_retrievalon one site with lithops and S3 stubbed out.🤖 Generated with Claude Code