Skip to content

refactor(ogc): declare date parameters on the dialect and read them on entry (ADR 0014, step 2) - #449

Closed
thodson-usgs wants to merge 4 commits into
DOI-USGS:mainfrom
thodson-usgs:refactor/ogc-date-fields
Closed

thodson-usgs wants to merge 4 commits into
DOI-USGS:mainfrom
thodson-usgs:refactor/ogc-date-fields

Conversation

@thodson-usgs

@thodson-usgs thodson-usgs commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Step 2 of ADR 0014 (proposed). Stacked on #448: this branch includes #448's three commits. Review only the last commit, 5a9a0490; I'll rebase once #448 merges.

Problem

The shared OGC code still named Water Data's facts:

  • the request builder listed its seven date parameters (_DATE_RANGE_PARAMS);
  • the request builder exempted last_modified by name from date-only writing;
  • the chunk planner repeated the seven date parameters in _NEVER_CHUNK, and a test checked that the two lists matched.

Change

  • OgcDialect:
    • New field date_params, defaulting to {"datetime"}, the standard's one date parameter.
    • New field timed_params.
    • date_only_services is renamed date_only_collections, because it is keyed by collection (see the CONTEXT.md note).
    • The Water Data dialect lists its seven date parameters and sets timed_params={"last_modified"}.
  • prepare_request_args(..., dialect=) reads the dialect's date parameters into a DateRange when the getter is called, and drops a range with both ends open.
    • Water Data's _get_args passes WATERDATA_DIALECT. The Samples and Statistics getters pass None, because those APIs are not OGC.
    • NGWMN passes NGWMN_DIALECT.
  • get_ogc_data reads any date parameter that is still raw, which is the case for a get_reference_table(query=...) dict. It raises TypeError for a DateRange under a key the dialect does not list, which would otherwise be sent as its repr.
  • The chunk planner lists no date parameter, since a DateRange is not a list. _DATE_RANGE_PARAMS is removed.
  • New architecture test: test_protocol_code_names_nothing_a_dialect_declares fails if a string a shipped dialect lists appears as a literal in ogc/ or _intervals.py.
    • It found one: the "value" default of _normalize_str_iterable's param_name, which matches Water Data's value column. param_name is now required.
    • monitoring_location_id is the one allowlisted literal; ADR 0014 records it as a known departure.

Behavior

  • The values sent are unchanged.
  • An unreadable date now raises when the getter is called, rather than when the first request is built. The message is the same.
  • No NEWS entry, since nothing a caller sees changes.

Tests

  • New tests:
    • prepare_request_args reads dates on entry, and reads none without a dialect;
    • a DateRange under an unlisted key raises;
    • get_reference_table(query={"last_modified": ...}) reads and writes the date, and drops [None, None];
    • the planner never splits a DateRange.
  • Results:
    • The offline suite (1334 tests) passes under UTC, America/Chicago and Asia/Kolkata.
    • Coverage is 99.01%.
    • The pre-commit gates pass.
    • The live tests that send dates (daily, water level, reference, ratings, and the dialect tests) pass.

Next

Step 3: Service and Endpoint, and the service-name architecture test.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HBt3Ee7eneKtdKQWq2T3YK

thodson-usgs and others added 2 commits October 12, 2026 15:47
… (ADR 0014)

Step 1 of ADR 0014 (proposed), which replaces the single-branch draft in
DOI-USGS#445.

- dataretrieval._dates (a dependency-free leaf) reads a date argument
  into a DateRange: an instant, a range with None for an open bound, or
  a duration. Every bound is UTC; a naive value is UTC, as in pandas.
- dataretrieval._intervals writes a DateRange in the ISO 8601 interval
  grammar that OGC API Features and STAC share, adjusted by a
  DateDialect(open_start, durations). It sits below ogc because STAC is
  not OGC.
- OgcDialect.open_start becomes OgcDialect.dates. Water Data sets
  durations=True; NGWMN sets open_start=""; get_ratings uses STAC_DATES
  (open_start="").
- ogc/dates.py and get_ratings' separate duration check are removed.

Behavior change: a lone duration passed to an NGWMN getter raises
ValueError before sending; the service rejects one with HTTP 400.
get_ratings' duration message is now the shared one. Otherwise the
values sent are unchanged: a comparison of 1432 inputs (each element
type, every pair, interval strings, error cases) against main's
_format_api_dates found no difference in output or message, under UTC
and America/Chicago.

Live tests check each DateDialect field against the Water Data OGC,
NGWMN, and STAC services.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBt3Ee7eneKtdKQWq2T3YK
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBt3Ee7eneKtdKQWq2T3YK
@thodson-usgs
thodson-usgs force-pushed the refactor/ogc-date-fields branch from 3da0abc to 3e446e8 Compare October 12, 2026 20:56
thodson-usgs and others added 2 commits October 12, 2026 16:01
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBt3Ee7eneKtdKQWq2T3YK
…n entry (ADR 0014)

Step 2 of ADR 0014 (proposed), stacked on step 1 (DOI-USGS#448).

- OgcDialect gains date_params (default {"datetime"}, the standard's one
  date parameter) and timed_params, and date_only_services is renamed
  date_only_collections, since it is keyed by collection. The Water Data
  dialect lists its seven date parameters and timed_params
  {"last_modified"}, which the request builder used to name.
- prepare_request_args(..., dialect=) reads the dialect's date parameters
  into a DateRange when the getter is called and drops an all-open one.
  Water Data's _get_args passes WATERDATA_DIALECT (the Samples and
  Statistics getters pass None, as those APIs are not OGC); NGWMN passes
  NGWMN_DIALECT.
- get_ogc_data reads any date parameter still raw (a verbatim query from
  get_reference_table), and raises TypeError for a DateRange under a key
  the dialect does not list.
- The chunk planner's _NEVER_CHUNK lists no date parameter: a DateRange
  is not a list. _DATE_RANGE_PARAMS is removed.
- tests/architecture_test.py fails if a string a shipped dialect lists
  appears as a literal in ogc/ or _intervals.py. It found one: the
  "value" default of _normalize_str_iterable's param_name, now required.

The values sent are unchanged. An unreadable date now raises when the
getter is called rather than when the first request is built; the
message is the same.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBt3Ee7eneKtdKQWq2T3YK
@thodson-usgs

Copy link
Copy Markdown
Collaborator Author

Combined into #448, which now holds all three ADR 0014 steps as one commit each.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant