You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit b13c6b9
Browse filesBrowse the repository at this point in the historyBrowse files
authored
fix(ogc): read each side of a "start/end" interval string like the list form (#443)
* fix(ogc): read each side of a "start/end" interval string like the list form
_format_api_dates sent any single string containing "/" unchanged. The
same range spelled as the documented string ("2024-01-01T10:00:00/..")
and as the list (["2024-01-01T10:00:00", None]) could select different
data: the string skipped the local-to-UTC conversion of naive times, the
offset-to-Z conversion, and the date truncation for date-only
collections, and "not-a-date/also-bad" reached the service unvalidated.
Split the string on its "/" and format each side as a list element is
formatted, so an unreadable side raises ValueError naming the caller's
argument before any request. An empty side becomes "..", and "../.."
means no filter, as [None, None] does. One side may still be an ISO 8601
duration paired with an instant ("2024-01-01/P7D"), kept unchanged; any
other shape (three sides, two durations, a duration with an open end)
raises ValueError naming the argument. A lone duration ("P7D") is
unchanged.
Follow-up named in #441.
* fix(ogc): reject duration sides, open starts per API, naive dates as UTC
- Reject a duration as either side of an interval string. The Water Data
and NGWMN services reject '2024-01-01/P7D' and 'P7D/2024-01-08' with
HTTP 400, and that error does not name the argument. _split_interval
raises instead and passes the two sides to the list path as a tuple,
which removes the duration handling in _format_interval and the
_is_passthrough helper.
- Write an open range start in the form each API accepts. The NGWMN and
STAC firewalls reject any datetime containing '../' with HTTP 403, so
get_water_level(datetime=[None, end]) and get_ratings(time=[None, end])
always failed. The Water Data API accepts '../end' and rejects '/end'
with HTTP 400. OgcDialect.open_start holds the form (default '..');
NGWMN sets '', and get_ratings passes '' to _format_api_dates because
STAC has no dialect.
- Keep fractional seconds instead of truncating them, which changed a
closed bound. The Water Data, NGWMN, and STAC services all accept them
(checked 2026-10-12). Accept a minute-precision time and spaces around
the '/'; both were previously sent unchanged and worked.
- Read a naive date or time as UTC, as pandas does and as
get_nearest_continuous already did, instead of as the machine's local
time. Convert an aware value to UTC, including in a date-only
collection. Now that the string form is parsed like the list form,
local time would have made time="2024-03-01/2024-03-02", the example
in the docs, start at 06:00Z in Chicago and on the previous day in
Sydney.
- Docstrings: get_ratings no longer says time is passed through
unchanged, and the _format_api_dates notes describe open_start. The
duration test ids name the side that is a duration.
- Date the NEWS entry by the day it lands and place it above #446's.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBt3Ee7eneKtdKQWq2T3YK
---------
Co-authored-by: thodson-usgs <thodson@usgs.gov>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: NEWS.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,3 +1,5 @@
1
+
**10/12/2026:** **Behavior change:** a date range passed as one `"start/end"` string, such as `time="2024-01-01T10:00:00/.."`, is now formatted like the list form `["2024-01-01T10:00:00", None]` in the `waterdata` and `ngwmn` OGC getters and in `waterdata.get_ratings()`. **Bug fix:** the string used to be sent unchanged, so the two forms could select different data: an offset was not converted to `Z`, and a date-only collection such as `daily` received times. A string now raises `ValueError` before any request is sent if a side is not a date (`time="2024-01-01/tomorrow"`), if it contains more than one `/`, or if either side is a duration (`"2024-01-01/P7D"`), which the services rejected with HTTP 400. An empty side is an open bound, and `"../.."` means no date filter. A lone duration such as `"P7D"` is unchanged. **Bug fix:** in `ngwmn.get_water_level()` and `waterdata.get_ratings()`, a range with an open start, such as `[None, "2016-01-01"]` or `"../2016-01-01"`, failed with HTTP 403 because those services' firewalls reject `../`. Both getters now send an empty start (`"/2016-01-01"`), which both services treat as open. The other Water Data getters still send `..`, because that API rejects an empty start. Fractional seconds, such as `2024-01-01T10:00:00.999Z`, are kept instead of truncated, and a minute-precision time (`2024-01-01T10:00Z`) and spaces around the `/` are accepted. **Behavior change:** a naive date or time is now UTC, as in pandas (`pd.to_datetime(..., utc=True)`) and `get_nearest_continuous()`, instead of the machine's local time, so `time=["2024-03-01", "2024-03-02"]` sends `2024-03-01T00:00:00Z/2024-03-02T00:00:00Z` on every machine. An aware value is converted to UTC, including in a date-only collection such as `daily`. For a local time, include the offset: `"2024-03-01T00:00:00-06:00"`.
2
+
1
3
**10/12/2026:** Date arguments of the `waterdata` and `ngwmn` OGC getters (`time`, `begin`, `end`, `datetime`, `last_modified`) and of `waterdata.get_ratings()` accept `datetime.date`, `datetime.datetime`, and `pandas.Timestamp` values, alone or as either end of a range, such as `time=[df.index.min(), None]`. Each is read like the equivalent string: a `date` is midnight, and `NaT` is an open bound. **Bug fix:** these values used to raise `AttributeError` or `TypeError` without naming the argument. Any other type, such as a number, now raises `ValueError` naming the argument and the accepted types.
2
4
3
5
**10/11/2026:****Bug fix:** a list passed to most `waterdata` OGC filters, such as `get_daily(approval_status=["Approved", "Provisional"])`, returned no rows: the Water Data API reads a comma-joined value as one value for all but a few identifier and code filters, and rejects a numeric list with HTTP 400. Lists are now sent as a CQL2 `in` filter. A list combined with `filter=` in `get_monitoring_locations()` and `get_combined_metadata()` is no longer ignored. **Bug fix:**`filter_lang="cql-json"` failed with HTTP 400 in every `waterdata` OGC getter. The filter is now sent as the request body; one that is not a JSON object raises `ValueError`. A blank `filter=""` is now ignored rather than failing with HTTP 400. `ngwmn` is unchanged.
0 commit comments