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.
Nonemeans best-available (=="iem")."acis"raisesValueError— there is no ACIS leg in this code path. - backend ( {“pandas” , “polars”} , keyword-only , default “pandas”) – Output frame type.
"polars"requiresreturn_type="wrapper"(polars frames carry nodf.attrsfor provenance). - return_type ( {“dataframe” , “wrapper” , “list”} , keyword-only , default “dataframe”) –
"dataframe"(default): apandas.DataFramewith provenance ondf.attrs."list": a plainlist[dict]of rows."wrapper": aProvenancedFrame.
- station (str) – ICAO code (e.g.
- 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_typeplus provenancesource(per-row endpoint tag"iem") andissued_at_utc. Frame identitydf.attrs["source"] == "cli.archive". - Return type: pd.DataFrame | list[dict]
- Raises:
ValueError – If
sourceis not in{None, "iem", "cli", "cli.archive"}, iffrom_date/to_dateare not ISO dates, or if thebackend/return_typepair 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.
Examples
Section titled “Examples”>>> 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 bystationand settlementdate. - Raises:
ContractError –
from_date/to_dateis missing or the window is inverted (raised before any I/O); orsource/modelsis invalid or ambiguous.
Example
Section titled “Example”>>> 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. aset) raiseContractError, as does an empty list or a non-string entry. - from_date (DateLike | None) – Inclusive ISO start date (
YYYY-MM-DD); omitting it raisesContractError(theNonedefault is a typing convenience, not a whole-history fetch). - to_date (DateLike | None) – Inclusive ISO end date (
YYYY-MM-DD); omitting it raisesContractError. - 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 hourlyMETARand off-hourSPECI),"metar"(hourly only), or"speci"(special reports only). Filters on the per-rowobservation_typecolumn; an invalid value raisesContractErrorbefore 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 — includingknowledge_timeand, withquality_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 carrydatetime64. - timezone (str | None) – IANA timezone override for stations outside the registry.
- quality_control (bool) – When
True, attach anobs_qc_statuscolumn — 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 upstreamqc_field(only AWC does). The label columns are byte-identical whether it is on or off (obs_qc_statusis an extra column). DefaultFalse.
- station (str | list[str] | tuple[str, …]) – ICAO code (e.g.
- Return type: pd.DataFrame | list[dict]
- Returns:
The merged per-report rows, each carrying
event_time_utc,observation_type(METAR/SPECI), the bare parsersourcetag,raw_metar, and the LSTlocal_standard_date. Shape followsreturn_type. - Raises:
- ContractError –
from_dateorto_dateis missing, or the window is inverted (raised before any I/O). - ValueError –
sourceis not in its allowed set. - HttpError – a queried upstream failed in transport or with a non-404
HTTP status — never a raw
httpxexception, and never a silently thinner frame.
- ContractError –
Example
Section titled “Example”>>> 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 withlat/lon: exactly one of the two identity forms must be supplied. - lat (
float|None) – Latitude of a coordinate site, in decimal degrees. Given together withlon, 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’sstationvalue. Supplying only one oflat/lonraises. - lon (
float|None) – Longitude of a coordinate site, in decimal degrees (negative = west). Seelat. - 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 acceptedsite_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, orNone(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 (allnoaa_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 explicitsatellite=for mixed lists. - product (
str|None) – Product id, orNone(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;Nonekeeps every registered variable ofproduct. - from_time (
datetime) – Event-time window start (UTC, tz-aware recommended). Typeddatetime— 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_timeraisesValueError. 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 viaKnowledgeView; 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}/satellitewith theMOSTLYRIGHT_API_KEYheader and returns rows byte-identical todelivery="live"(deliveryrecords 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".
- station (
- Return type:
DataFrame - Returns:
pd.DataFramecarrying the satellite rows plus the temporal columns (source/event_time/knowledge_time/retrieved_at/delivery) andqc_status, withdf.attrs["source"]set to the resolved per-source identity (noaa_goesfor GOES, and the matching id for each other native-ring source). - Raises:
- ContractError – the identity arguments conflict —
stationgiven besidelat/lon, only one oflat/lon, neither form, or a coordinate-only override (site_id/tz_override) in station mode. Raised before any I/O. - ValueError –
satellite/product/deliverynot in their enums (orproductnot registered forsatellite’s source), orto_time < from_time, or a naiveas_ofdatetime, or a coordinate that is out of range / not finite, or asite_idthat claims a reserved identifier. - SourceUnavailableError – the
[satellite]optional extra is absent.
- ContractError – the identity arguments conflict —
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.
Example
Section titled “Example”>>> 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-DDinclusive start. - to_date (DateLike) –
YYYY-MM-DDinclusive 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
ycolumns + theobserved_*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 rawweather.observations()/weather.forecasts()sources yourself and compose them viamostlyright.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
httpxexception.
- TypeError – an unsupported keyword was passed —
Modules
Section titled “Modules”| Module | Description |
|---|---|
cache | Local parquet cache for Mostly Right weather observations and climate. |
catalog | Weather catalog package. |
cwop | mostlyright.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_nwp | Public 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]. |
hazards | mostlyright.weather.hazards — standalone NWS/NHC hazard adapter. |
label | weather.label.* — the .label.-registered weather spine factories. |
nwp | mostlyright.weather.nwp — raw cycle-grain NWP forecasts. |
qc | Weather QC rules + per-model NWP physics-bounds registry. |
qc_sidecar | Observation QC sidecar writer. |
satellite([station, satellite, product, …]) | Fetch native-L2 satellite single-pixel values for one or more stations. |
spine | Internal per-settlement-day weather spine constructor. |
stations | mostlyright.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. |