Skip to content

mostlyright.weather

Weather observations, forecasts, daily settlement summaries, and satellite data.

The default path fetches the public AWC, IEM, GHCNh, and NWS CLI sources directly; their addresses resolve through the keyed manifest catalog (MOSTLYRIGHT_API_KEY). Observation rows preserve raw_metar so callers can re-parse the original report with tools such as MetPy.

mostlyright.weather.daily_summaries(station, from_date, to_date, , source=None, backend=‘pandas’, return_type=‘dataframe’)

Section titled “mostlyright.weather.daily_summaries(station, from_date, to_date, , source=None, backend=‘pandas’, return_type=‘dataframe’)”

Return NWS CLI daily settlement labels for station over [from_date, to_date].

The settlement source for Kalshi NHIGH/NLOW markets: the official NWS CLI daily high/low, merged via the frozen dedup policy (highest report_type_priority with STRICT > — overnight final wins).

  • Parameters:
    • station (str) – ICAO code (e.g. "KNYC") or 3-letter NWS code.
    • from_date (str) – ISO date strings (YYYY-MM-DD), inclusive bounds.
    • to_date (str) – ISO date strings (YYYY-MM-DD), inclusive bounds.
    • source ( {None , “iem” , “cli” , “cli.archive”} , keyword-only , default None) – Provenance selector. A degenerate single-authority axis: IEM CLI is the sole live provider, so every accepted value resolves to the same fetch. None means best-available (== "iem"). "acis" raises ValueError — there is no ACIS leg in this code path.
    • backend ( {“pandas” , “polars”} , keyword-only , default “pandas”) – Output frame type. "polars" requires return_type="wrapper" (polars frames carry no df.attrs for provenance).
    • return_type ( {“dataframe” , “wrapper” , “list”} , keyword-only , default “dataframe”) –
      • "dataframe" (default): a pandas.DataFrame with provenance on df.attrs.
      • "list": a plain list[dict] of rows.
      • "wrapper": a ProvenancedFrame.
  • Returns: One row per CLI settlement day with the public column contract: station, local_standard_date, daily_summary_temp_high_f, daily_summary_temp_low_f, daily_summary_report_type plus provenance source (per-row endpoint tag "iem") and issued_at_utc. Frame identity df.attrs["source"] == "cli.archive".
  • Return type: pd.DataFrame | list[dict]
  • Raises: ValueError – If source is not in {None, "iem", "cli", "cli.archive"}, if from_date/to_date are not ISO dates, or if the backend/return_type pair is incoherent (e.g. backend="polars", return_type="dataframe").
  • CLI is a daily batch product — daily_summaries() has no grain axis and no live path; the upstream is re-fetchable.
  • This wraps the local CLI fetcher only; it makes no hosted call.
>>> from mostlyright.weather import daily_summaries
>>> df = daily_summaries("KNYC", "2026-01-01", "2026-01-03")
>>> df.attrs["source"]
'cli.archive'

mostlyright.weather.forecasts(station, from_date=None, to_date=None, , source=‘model_output_statistics’, models=None)

Section titled “mostlyright.weather.forecasts(station, from_date=None, to_date=None, , source=‘model_output_statistics’, models=None)”

Return the settlement-day forecast frame for station over [from_date, to_date].

  • Parameters:
    • station (str) – The station id to fetch forecasts for.
    • from_date (DateLike | None) – Inclusive ISO start date (YYYY-MM-DD). Required.
    • to_date (DateLike | None) – Inclusive ISO end date (YYYY-MM-DD). Required.
    • source (str) – The forecast engine — "model_output_statistics" (alias "mos", default), "open_meteo", or "numerical_weather_prediction" (alias "nwp").
    • models (str | list[str] | None) – Product(s) within source. A str or single-item list for MOS/Open-Meteo; a list for raw NWP. Ambiguous multi-model MOS selections raise.
  • Return type: pd.DataFrame
  • Returns: The eager forecast_* frame keyed by station and settlement date.
  • Raises: ContractErrorfrom_date/to_date is missing or the window is inverted (raised before any I/O); or source/models is invalid or ambiguous.
>>> from mostlyright.weather import forecasts
>>> df = forecasts("KNYC", "2025-01-01", "2025-01-07")

mostlyright.weather.observations(station, from_date=None, to_date=None, , source=None, report_type=‘all’, backend=‘pandas’, return_type=‘dataframe’, timezone=None, quality_control=False)

Section titled “mostlyright.weather.observations(station, from_date=None, to_date=None, , source=None, report_type=‘all’, backend=‘pandas’, return_type=‘dataframe’, timezone=None, quality_control=False)”

Return merged per-report observation rows for station over [from_date, to_date].

  • Parameters:
    • station (str | list[str] | tuple[str, …]) – ICAO code (e.g. "KNYC"), 3-letter NWS code, or a list/tuple of them (each station is fetched separately and the per-report rows are concatenated in input order — duplicates are kept, not deduped). Unordered containers (e.g. a set) raise ContractError, as does an empty list or a non-string entry.
    • from_date (DateLike | None) – Inclusive ISO start date (YYYY-MM-DD); omitting it raises ContractError (the None default is a typing convenience, not a whole-history fetch).
    • to_date (DateLike | None) – Inclusive ISO end date (YYYY-MM-DD); omitting it raises ContractError.
    • source (Source | None) – If set, only that source ("iem" / "ghcnh" / "awc") is queried; otherwise every source whose coverage can reach the window is merged by priority (the GHCNh leg is skipped for window slices inside the station’s current LST month — NCEI’s publication lag — and for non-US stations).
    • report_type (Literal[‘metar’, ‘speci’, ‘all’]) – Which report kinds to return — "all" (default, both hourly METAR and off-hour SPECI), "metar" (hourly only), or "speci" (special reports only). Filters on the per-row observation_type column; an invalid value raises ContractError before any I/O.
    • backend (str) – Output frame backend ("pandas" / "polars").
    • return_type (str) – Output shape ("dataframe" / "list" / "wrapper"). The key set is the same in every shape — including knowledge_time and, with quality_control=True, obs_qc_status. Only the representation differs: "list" keeps the time keys (event_time_utc, local_standard_date, knowledge_time) as ISO strings where the frame shapes carry datetime64.
    • timezone (str | None) – IANA timezone override for stations outside the registry.
    • quality_control (bool) – When True, attach an obs_qc_status column — the core QCEngine’s per-row bitmask (temp/dewpoint/wind/pressure physical-bounds rules). This is the SDK’s own computed QC, not an upstream passthrough: IEM/GHCNh carry no upstream qc_field (only AWC does). The label columns are byte-identical whether it is on or off (obs_qc_status is an extra column). Default False.
  • Return type: pd.DataFrame | list[dict]
  • Returns: The merged per-report rows, each carrying event_time_utc, observation_type (METAR / SPECI), the bare parser source tag, raw_metar, and the LST local_standard_date. Shape follows return_type.
  • Raises:
    • ContractErrorfrom_date or to_date is missing, or the window is inverted (raised before any I/O).
    • ValueErrorsource is not in its allowed set.
    • HttpError – a queried upstream failed in transport or with a non-404 HTTP status — never a raw httpx exception, and never a silently thinner frame.
>>> from mostlyright.weather import observations
>>> rows = observations("KNYC", "2024-03-01", "2024-03-31")

mostlyright.weather.satellite(station=None, satellite=None, product=None, , lat=None, lon=None, site_id=None, tz_override=None, variable=None, from_time, to_time, as_of=None, delivery=‘live’, backend=‘pandas’, return_type=‘dataframe’)

Section titled “mostlyright.weather.satellite(station=None, satellite=None, product=None, , lat=None, lon=None, site_id=None, tz_override=None, variable=None, from_time, to_time, as_of=None, delivery=‘live’, backend=‘pandas’, return_type=‘dataframe’)”

Fetch native-L2 satellite single-pixel values for one or more stations.

  • Parameters:
    • station (str | list[str] | None) – Single ICAO/NWS code or a list, resolved against the settlement registry first and then the full packaged station catalog. Unknown codes are skipped with a logged warning (partial list -> partial DataFrame). Mutually exclusive with lat/lon: exactly one of the two identity forms must be supplied.
    • lat (float | None) – Latitude of a coordinate site, in decimal degrees. Given together with lon, addresses an arbitrary point that need not exist in any registry or catalog; its identity is the derived site id (40.7789, -73.9692 -> "N4078W07397"), which is what selects the cache partition, the object-store key, and the row’s station value. Supplying only one of lat/lon raises.
    • lon (float | None) – Longitude of a coordinate site, in decimal degrees (negative = west). See lat.
    • site_id (str | None) – Override the derived identity of a coordinate site. Coordinate mode only. It cannot claim an allocated station’s identifier (nor a merely ICAO-shaped one) unless the supplied coordinates are that station’s own grid cell — identity selects which partition receives rows, so an accepted site_id="KNYC" beside arbitrary coordinates would write non-KNYC pixels into the KNYC settlement-feeding namespace.
    • tz_override (str | None) – Override a coordinate site’s timezone, which otherwise comes from the nearest packaged-catalog station (precomputed at build time — no runtime geo dependency). Coordinate mode only.
    • satellite (str | None) – A native-ring satellite id, or None (the default) to auto-route by the station’s coverage region — GOES for the Americas/Pacific, Himawari for Asia-Pacific, Meteosat for Europe/Africa/Indian Ocean (needs a Data Store key only for the live fetch), and VIIRS for the poles and any band no supported geostationary source covers. Explicit values: GOES (all noaa_goes): "goes16"/"goes19" (GOES-East, CONUS) and "goes18" (operational GOES-West) / "goes17" (GOES-West archive) — West “C” covers PACUS (Pacific incl. Hawaii). Himawari (jma_himawari): "himawari8"/"himawari9". VIIRS (noaa_viirs): "viirs-npp"/"viirs-n20"/"viirs-n21". Meteosat (eumetsat_meteosat, needs a key): "meteosat-0deg"/"meteosat-iodc". When auto-routing, a single (source, satellite, product) triple is picked from the first resolved station and applied to the whole call. Cross-region caveat: auto-routing a station list that spans regions (e.g. ["KNYC", "RJTT"]) fetches every station on the first station’s source, so stations outside that footprint silently return no rows (off-disk -> dropped; leakage-safe but a partial frame). A warning is logged naming the divergent stations; prefer per-region calls or an explicit satellite= for mixed lists.
    • product (str | None) – Product id, or None (the default) to use the resolved source’s cheap default product (GOES "ABI-L2-ACMC", Himawari "AHI-L2-FLDK-Clouds", VIIRS "VIIRS-JRR-CloudMask", Meteosat "MSG-CLM"). "ABI-L2-DSRF" emits a one-time gating warning on the live path.
    • variable (str | None) – Optional single-variable filter; None keeps every registered variable of product.
    • from_time (datetime) – Event-time window start (UTC, tz-aware recommended). Typed datetime — sub-day times are honored (the window is filtered back precisely after the day-grain fetch).
    • to_time (datetime) – Event-time window end. to_time < from_time raises ValueError. A midnight (date-granular) bound means “through the end of that UTC day”.
    • as_of (Any) – Knowledge-time cutoff. TimePoint | datetime | None. Filters in-process on typed datetimes via KnowledgeView; a naive datetime is rejected loudly rather than compared as a string.
    • delivery (str) – "live" (default) parses public data directly and makes no hosted call; "hosted" fetches the deployed weather serving endpoint ${MOSTLYRIGHT_WEATHER_HOSTED_URL}/satellite with the MOSTLYRIGHT_API_KEY header and returns rows byte-identical to delivery="live" (delivery records the channel, not source identity). Hosted is opt-in via those two environment variables; the default live path never touches it.
    • backend (str) – "pandas" (default) or "polars".
    • return_type (str) – "dataframe" (default) or "wrapper".
  • Return type: DataFrame
  • Returns: pd.DataFrame carrying the satellite rows plus the temporal columns (source/event_time/knowledge_time/retrieved_at/ delivery) and qc_status, with df.attrs["source"] set to the resolved per-source identity (noaa_goes for GOES, and the matching id for each other native-ring source).
  • Raises:
    • ContractError – the identity arguments conflict — station given beside lat/lon, only one of lat/lon, neither form, or a coordinate-only override (site_id/tz_override) in station mode. Raised before any I/O.
    • ValueErrorsatellite/product/delivery not in their enums (or product not registered for satellite’s source), or to_time < from_time, or a naive as_of datetime, or a coordinate that is out of range / not finite, or a site_id that claims a reserved identifier.
    • SourceUnavailableError – the [satellite] optional extra is absent.

mostlyright.weather.training_table(station, from_date, to_date, , label=‘daily_summary’, **_unsupported)

Section titled “mostlyright.weather.training_table(station, from_date, to_date, , label=‘daily_summary’, **_unsupported)”

A built-in supervised-table example: features -> label rows.

Returns one row per station-settlement-day — the label="daily_summary" settlement target (Kalshi NHIGH/NLOW ground truth) beside the observation feature aggregates. The recipe keeps its cutoff fields visible and applies the timing metadata available from its sources. The label="daily_summary" default is explicit and contractually stable (no FutureWarning, no deprecation path). Two positional dates, inclusive ends. label="daily_extremes" swaps in the Polymarket WU/NOAA-WRH target.

>>> from datetime import date
>>> from mostlyright import weather
>>> table = weather.training_table(
... "KNYC", date(2025, 1, 6), date(2025, 1, 12)
... )
  • Parameters:
    • station (str | list[str] | tuple[str, …]) – A station id (or a list -> a long-format panel).
    • from_date (DateLike) – YYYY-MM-DD inclusive start.
    • to_date (DateLike) – YYYY-MM-DD inclusive end.
    • label (Label) – The settlement label recipe — "daily_summary" (default) or "daily_extremes".
    • _unsupported (object)
  • Return type: pd.DataFrame
  • Returns: The training table (the settlement y columns + the observed_* observation feature aggregates), one row per station-settlement-day.
  • Raises:
    • TypeError – an unsupported keyword was passed — training_table() is capped. For anything beyond the capped surface, compose the raw weather.observations() / weather.forecasts() sources yourself and compose them via mostlyright.experimental (docs/dataset.md); the message names that path, never an internal API.
    • HttpError – an upstream fetch (label or observations) failed in transport or with an HTTP error status — never a raw httpx exception.
ModuleDescription
cacheLocal parquet cache for Mostly Right weather observations and climate.
catalogWeather catalog package.
cwopmostlyright.weather.cwop — standalone CWOP (Citizen Weather Observer Program) live adapter.
daily_summaries(station, from_date, to_date, *)Return NWS CLI daily settlement labels for station over [from_date, to_date].
forecast_nwpPublic NWP-forecast surface (live HRRR/GFS/NBM).
forecasts(station[, from_date, to_date, …])Return the settlement-day forecast frame for station over [from_date, to_date].
hazardsmostlyright.weather.hazards — standalone NWS/NHC hazard adapter.
labelweather.label.* — the .label.-registered weather spine factories.
nwpmostlyright.weather.nwp — raw cycle-grain NWP forecasts.
qcWeather QC rules + per-model NWP physics-bounds registry.
qc_sidecarObservation QC sidecar writer.
satellite([station, satellite, product, …])Fetch native-L2 satellite single-pixel values for one or more stations.
spineInternal per-settlement-day weather spine constructor.
stationsmostlyright.weather.stations — the canonical home for the station catalog.
training_table(station, from_date, to_date, *)A built-in supervised-table example: features -> label rows.