easysnowdata.stations.clients.GHCNDClient#
- class easysnowdata.stations.clients.GHCNDClient(base_url: str = 'https://www.ncei.noaa.gov/pub/data/ghcn/daily', timeout: int = 120, max_retries: int = 3, backoff: int = 4, session: Session | None = None, keep_qc_failed: bool = False)[source]#
Bases:
objectClient for NOAA NCEI GHCN-Daily station files.
No credentials are needed.
- Parameters:
base_url (
str) – Root of the GHCN-D directory. Override for a mirror.timeout (
int) – HTTP request timeout in seconds. The inventory file is ~36 MB, so the default is generous.max_retries (
int) – Number of retry attempts on transient errors (5xx, network).backoff (
int) – Base backoff delay in seconds. Actual delay = backoff × attempt.session (
requests.SessionorNone) – Optional pre-configured session.keep_qc_failed (
bool) – If False (default), values carrying a non-blank GHCN-DQFLAGare returned asNone. If True they are returned as stored.
- get_stations(elements: list[str] | tuple[str, ...] | str = ('WESD', 'SNWD'), active_only: bool = False, bbox: tuple[float, float, float, float] | None = None, exclude_networks: list[str] | tuple[str, ...] | str | None = None) list[dict][source]#
Stations reporting any of
elements.- Parameters:
elements (
list[str]orstr) – GHCN-D element codes; a station is kept if it reports any of them. Defaults to("WESD", "SNWD").active_only (
bool) – Keep only stations whose latest snow-element year is this year or last.bbox (
tuple, optional) –(min_lon, min_lat, max_lon, max_lat).exclude_networks (
list[str]orstr, optional) – GHCN-D network codes to drop (seeGHCN_NETWORKS), e.g."S"to drop the SNOTEL mirror when AWDB is used alongside.
- Returns:
list[dict]– Station dicts withstation_id,name,latitude,longitude,elevation_m,status,state,country_code,ghcn_network,ghcn_network_name,gsn,hcn_crn,wmo_id,has_swe,has_snwd,elements({code: {first_year, last_year}}) andstation_url.- Raises:
GHCNDError – On an unknown element code or a failed inventory download.
- get_all_stations(active_only: bool = False, bbox: tuple[float, float, float, float] | None = None) list[dict][source]#
All GHCN-D stations reporting snow depth or SWE (any network).
- Parameters:
- Returns:
list[dict]– Same schema asget_stations()(which can also drop networks).- Raises:
GHCNDError – If the station or inventory file cannot be downloaded.
- get_metadata(station_id: str) dict[source]#
Metadata and element inventory for one station.
- Parameters:
station_id (
str) – GHCN-D station id, e.g."USS0021D08S".- Returns:
dict– Theget_stations()dict plusdata_variables: one entry per known element withname,type,interval,units(emitted),description,notes,begin_date,end_dateandn_obs(None— the inventory does not say). Dates are year-resolution ("YYYY-01-01"/"YYYY-12-31").- Raises:
GHCNDError – If the station id is not in
ghcnd-stations.txt.
- get_station_file(station_id: str) bytes[source]#
Raw
by_station/{ID}.csv.gzbytes for one station.- Parameters:
station_id (
str) – GHCN-D station id.- Returns:
bytes– The gzipped CSV, full period of record.- Raises:
GHCNDError – If the file cannot be downloaded (HTTP 404 for an unknown id).
- get_data(station_ids: list[str] | str | None = None, variables: list[str] | str | None = None, bbox: tuple[float, float, float, float] | None = None, begin_date: str | date | None = None, end_date: str | date | None = None, interval: str = 'daily', include_flags: bool = False) list[dict][source]#
Standardized data fetch — returns a flat list of observation records.
- Parameters:
station_ids (
list[str]orstrorNone) – GHCN-D station id(s), e.g."USS0021D08S". Required unlessbboxis provided.variables (
list[str]orstrorNone) – Element codes ("SNWD") or standardized types ("snwd").Nonemeans snow only:WESDandSNWD.bbox (
tuple, optional) –(min_lon, min_lat, max_lon, max_lat); fetches every snow station in the box. GHCN-D is dense — a large box means many full-record downloads.begin_date (
strordate, optional) – InclusiveYYYY-MM-DDbounds. The whole station file is downloaded either way; the bounds only filter rows.end_date (
strordate, optional) – InclusiveYYYY-MM-DDbounds. The whole station file is downloaded either way; the bounds only filter rows.interval (
str) – Only"daily"is supported.include_flags (
bool) – Addflag="MFLAG,QFLAG,SFLAG"to each record.
- Returns:
list[dict]–{station_id, date, variable, type, value, units, interval}records (plusflag). Stations whose file cannot be fetched are logged and skipped.- Raises:
ValueError – If neither
station_idsnorbboxis provided.GHCNDError – On an unknown variable or interval.
Example
>>> client = GHCNDClient() >>> records = client.get_data( ... station_ids="USS0021D08S", ... variables=["snwd"], ... begin_date="2024-01-01", ... end_date="2024-01-15", ... ) >>> records[0]["units"] 'cm'
- get_year_data(year: int, station_ids: list[str] | str | None = None, variables: list[str] | str | None = None, begin_date: str | date | None = None, end_date: str | date | None = None, include_flags: bool = False) Iterator[dict][source]#
Stream one
by_year/{year}.csv.gzfile as observation records.The bulk path for refreshing many stations: one download (~115–170 MB compressed for a recent year) instead of one full-record file per station. NCEI rebuilds the current year’s file daily. Late-arriving sources (COOP paper forms, ECA&D batches) can still add values to the previous year’s file for a month or two.
- Parameters:
year (
int) – Calendar year of the file.station_ids (
list[str]orstrorNone) – Keep only these stations.Nonekeeps every station.variables (
list[str]orstrorNone) – As inget_data();NonemeansWESDandSNWD.begin_date (
strordate, optional) – Inclusive row filter within the year.end_date (
strordate, optional) – Inclusive row filter within the year.include_flags (
bool) – Addflag="MFLAG,QFLAG,SFLAG"to each record.
- Yields:
dict– The same recordsget_data()returns, in file order.- Raises:
GHCNDError – On an unknown variable or a failed download.