WeatherLive
WeatherLive is the real-time sibling of MostlyRightClient. Where MostlyRightClient queries our archive (AWC + IEM + GHCNh, deduped and stored), WeatherLive hits the NOAA Aviation Weather feed directly and returns the latest METAR within seconds of broadcast.
from mostlyright import WeatherLive
with WeatherLive() as live: now = live.observations("NYC") print(now)Use it for inference loops, live dashboards, and any pipeline that needs the station’s latest observation before it lands in the historical archive.
01 · Column parity
Section titled “01 · Column parity”Every field WeatherLive.observations() returns is a field MostlyRightClient.observations() returns. Same names, same units, same encodings. Whatever code you wrote against historical data runs against live with no adjustments.
def check_settlement_threshold(obs): return obs["temp_f"] >= 85 # works on both
hist = MostlyRightClient().observations("NYC", as_of="2024-07-04T18:00:00Z")assert check_settlement_threshold(hist[-1])
live = WeatherLive().observations("NYC")assert check_settlement_threshold(live[0]) # same shape, same keysParity is enforced by a shared schema spec, OBSERVATION_SCHEMA. If the live feed ever drops a field or changes a unit, the parse fails loudly rather than returning mismatched shapes. See Observation schema for the full field list.
02 · Construction
Section titled “02 · Construction”WeatherLive( timeout: float = 15.0, # per-request timeout cache_ttl: int = 60, # seconds to cache a METAR before refetching)No API key required. The AWC feed is public. Rate-limiting is enforced client-side at 30 requests/minute per host by default.
Use as a context manager to guarantee the HTTP session closes:
with WeatherLive() as live: obs = live.observations("NYC")03 · observations(): one station, latest METAR
Section titled “03 · observations(): one station, latest METAR”live.observations( station: str, *, include_forecast: bool = False,) -> list[dict]Returns the most recent METAR for station. Same 30 fields as the historical API. The list always has at least one row. Older METARs can be fetched by range from MostlyRightClient.
with WeatherLive() as live: latest = live.observations("NYC")[0] print(latest["temp_f"], latest["observed_at"]) # 84.0 2026-04-21T14:51:00ZPass include_forecast=True to attach a short-horizon forecast block:
latest = live.observations("NYC", include_forecast=True)[0]latest["forecast"]["nbm"]["temp_f"] # current NBM 1-hour forecast04 · forecasts(): short-horizon
Section titled “04 · forecasts(): short-horizon”live.forecasts( station: str, model: str = "nbm", horizon: int = 24, # hours ahead) -> list[dict]Returns the forecast issued closest to “now” for station, out to horizon hours. Models supported: "nbm" (default), "gfs", "hrrr", "ecmwf".
with WeatherLive() as live: f = live.forecasts("NYC", model="nbm", horizon=6) for hour in f: print(hour["valid_at"], hour["temp_f"])05 · When to reach for historical instead
Section titled “05 · When to reach for historical instead”Use MostlyRightClient instead of WeatherLive when you need any of:
as_offiltering. Backtests, point-in-time inference, settlement replay.WeatherLiveis always “now”.- Multi-station slices.
WeatherLive.observations()is one station at a time. For a cross-station snapshot,MostlyRightClient.observations()withfrom_date/to_dateis the right call. - Non-METAR fields.
WeatherLiveonly exposes what is in the live feed. Climate aggregates, forecast history, and pairs tables live in the archive only. - Anything settlement-critical. Settlements use the archived record. Even for live display, pull from historical and only overlay
WeatherLiveas a “latest reading” badge.
WeatherLive is for the moment. Use MostlyRightClient for the record.
Related
Section titled “Related”MostlyRightClientfor the archive-backed client.- Observation schema for the 30-field contract shared by both.
- Data sources for what flows into the archive.