Water OGC API: Water Data Client for the USGS Services¶
A Python client for USGS water data services over OGC API Features. Its service classes
block, for scripts and notebooks, and water_ogcapi.aio holds their async twins.
Status: early development. The async and sync query APIs and the metadata cache work on all three services, with the quota governor, page-level resume, and concurrent NWIS pieces. The release candidate on PyPI only reserves the name and has no query API, so install from this repository until the first final release.
Features¶
- Blocking service classes for scripts and notebooks, Jupyter included.
- Async twins in
water_ogcapi.aio, over HTTP/2 with bounded concurrency. - Retries transient failures with exponential backoff and honors
Retry-After. - Splits an NWIS query by year, month, or site list and runs the pieces concurrently, as USGS's efficiency guidance recommends.
- Spaces requests further apart as a service's
X-RateLimit-Remainingruns down, and one second apart on a service that sends no rate-limit headers. - Checks a query's collection and parameter names against the service's metadata, so a typo raises an error listing the valid names before it can return the whole collection.
- Two direct runtime dependencies,
httpx2andh2. No pandas.
Services¶
| Service | Class | Base URL |
|---|---|---|
| NWIS | NWIS |
api.waterdata.usgs.gov/ogcapi/v1/ |
| FabricData | FabricData |
api.water.usgs.gov/fabric/pygeoapi/ |
| GeoConnex | GeoConnex |
reference.geoconnex.us/ |
NWIS sends the key in USGS_API_KEY, when set, in the X-Api-Key header. The other
two services never receive it.
Installation¶
PyPI holds only a release candidate, which reserves the name and has no query API, and conda-forge has no package yet. Install the development version from GitHub (Python 3.12 or later):
Quick start¶
The monitoring locations in a small box around Washington, DC:
from water_ogcapi import NWIS
with NWIS() as nwis:
result = nwis.collect("monitoring-locations", bbox=(-77.12, 38.80, -76.91, 38.99))
print(len(result.geojson["features"]), result.pagination.completeness)
collect() returns one QueryResult holding the aggregated GeoJSON and the evidence
for every page; iter_pages() streams each page as it arrives. The
design decisions (D-02 and D-03)
describe both.
Code that runs its own event loop can use the async classes in water_ogcapi.aio, which
take the same arguments:
import asyncio
from water_ogcapi.aio import NWIS
async def main() -> None:
async with NWIS() as nwis:
result = await nwis.collect("monitoring-locations", bbox=(-77.12, 38.80, -76.91, 38.99))
asyncio.run(main())
Documentation¶
The documentation has the API reference, a logging guide, and the design decisions behind the library. Example notebooks for each service are in progress.
Roadmap¶
The roadmap shows the progress on each GitHub milestone, regenerated daily from the milestone issues.
Contributing¶
Report bugs and ask questions in GitHub issues. The contributing guide covers the development setup, the checks a change must pass, and the project conventions.
License¶
MIT. See LICENSE.