Fix nldi: validate data source on every call, not just cache-miss#246
Conversation
The validation check `data_source not in _AVAILABLE_DATA_SOURCES` was nested inside `if _AVAILABLE_DATA_SOURCES is None:`, so once any caller warmed the cache, subsequent invalid `data_source`/`feature_source` values were silently accepted. Move the check outside the cache-load branch so all calls are validated. Also guard the `_validate_data_source(feature_source)` call in `get_features` with `if feature_source:` — the previous code unconditionally validated `None` when the user provided only `comid`. The cache bug masked this; with the check now active it would otherwise raise "Invalid data source 'None'". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes NLDI data-source validation so invalid data_source / feature_source values are rejected on every call, not just while populating the cache. It fits the NLDI client layer by restoring early, user-facing argument validation instead of letting bad inputs fall through to confusing server-side 4xx responses.
Changes:
- Moved
_validate_data_source()’s membership check out of the cache-miss branch so cached calls are still validated. - Added a guard in
get_features()to avoid validatingfeature_source=Noneon comid-based calls. - Added regression tests and a test fixture to reset the module-level data-source cache between tests.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
dataretrieval/nldi.py |
Fixes cached validation behavior and adjusts get_features() feature-source validation flow. |
tests/nldi_test.py |
Adds regression tests for cold-cache and warm-cache invalid data-source handling, plus cache reset fixture. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| _validate_data_source(data_source) | ||
| # validate feature source | ||
| _validate_data_source(feature_source) | ||
| if feature_source: |
Per copilot review on PR DOI-USGS#246. The previous truthiness guard skipped validation for empty-string feature_source/data_source, letting bad inputs build invalid URLs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per /simplify review on PR DOI-USGS#246: - Use `monkeypatch.setattr` in the autouse cache-reset fixture rather than direct attribute assignment + yield. Auto-restores on teardown and collapses the fixture to one line. - Drop redundant cold-cache regression test (`test_validate_data_source_rejects_invalid_on_first_call`); the warm-cache test exercises the cold path on its first call anyway. - Strip stale WHAT-comments (`# validate the data source`, `# validate feature source`, etc.) from the `get_features` validation block while we're touching adjacent lines. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…e-validation # Conflicts: # dataretrieval/nldi.py # tests/nldi_test.py
Summary
_validate_data_sourcenested itsdata_source not in cachecheck inside theif cache is None:branch, so the validator was effectively a no-op after the first call. Any invaliddata_source/feature_sourcevalue passed thereafter was silently accepted and used to construct an invalid URL, surfacing as a confusing 4xx from the server rather than a clean ValueError._validate_data_source(feature_source)call inget_featureswithif feature_source is not None:— without this guard the now-active validator would raise "Invalid data source 'None'" whenever a user provided onlycomid(the cache bug previously masked this).Test plan
tests/nldi_test.pythat exercises the load-bearing behavior change: invalid sources must still raise after the cache is warm. Cold-cache test was dropped as redundant — the warm-cache test exercises the cold path on its first call.monkeypatchfixture resets the module-level_AVAILABLE_DATA_SOURCEScache between tests to keep test order independent.Related PRs
nldi-cleanup) is a broader cleanup ofnldi.pythat adds the sameif feature_source:guard at the same line inget_features. Trivial textual conflict at merge time; the fix is identical so either can land first.nldi-navigation-mode-valueerror) touches a different function (_validate_navigation_mode) in the same file. No conflict.