Skip to content

Guides

Forecasts

Two complementary forecast surfaces: IEM MOS (text/JSON, both SDKs) and gridded NWP (GRIB2, Python today). Both feed dataset(include_forecast=True); Python additionally exposes the per-model NWP path for cross-model comparison.

┌──────────────────────────┐
dataset(...) │ IEM MOS (both) │ → fcst_* columns
include_forecast│ gridded NWP (py) │ → fcst_*_nwp_<model> columns
└──────────────────────────┘
  • IEM MOS is the default forecast in research(). Text/JSON, station-level point forecasts, fully wired on both SDKs.
  • NWP (gridded) wraps NOAA Big Data Program, ECMWF Open Data, and MSC Datamart. 11 NCEP-family models are wired end-to-end in Python today (HRRR, HRRRAK, GFS, GEFS, GDAS, NBM, RAP, RRFS, RTMA, URMA, CFS). 13 others ship URL patterns + QC rules but raise structured errors (see Wiring status below). TypeScript: deferred to v2.0+ — see NWP in TypeScript.

dataset(include_forecast=True) (and its research() alias) wires both the IEM MOS forecast and the per-NWP-model forecast end-to-end. Settlement-day bucketing uses station LST via settlement_date_for(observed_at, station) so post-midnight tail rows roll into the correct calendar settlement.

import mostlyright
# Default — IEM MOS forecasts populate fcst_* columns
df = mostlyright.dataset(
"KNYC", "2026-05-01", "2026-05-07",
include_forecast=True,
)
print(df[["date", "obs_high_f", "fcst_high_f", "fcst_model"]])
# Additionally include NWP forecasts per model
df = mostlyright.dataset(
"KNYC", "2026-05-01", "2026-05-07",
include_forecast=True,
forecast_models=["hrrr", "gfs"],
)
print(df[[
"date", "fcst_high_f",
"fcst_high_f_nwp_hrrr", "fcst_high_f_nwp_gfs",
]])

The TS SDK ships iemMosForecasts() as a standalone surface — useful when you want raw MOS rows without going through dataset().

# Python folds IEM MOS into dataset(); call sites that want raw MOS
# use the internal _fetchers (not yet a public surface).
import mostlyright
df = mostlyright.dataset("KNYC", "2026-05-01", "2026-05-07", include_forecast=True)

Wiring status legendwired = fetch + decode + QC end-to-end. reserved = schema-declared (URL patterns + QC rules + idx dispatch present) but forecast_nwp() raises today. Reserved models flip to wired in follow-up releases.

ModelWiringCoverageCycle freqHistorical depthNotes
hrrrwiredCONUS 3kmhourly2014-07-30High-resolution rapid refresh
hrrrakwiredAlaska 3km3-hourly2018-01-01HRRR for Alaska
gfswiredGlobal 0.25°6-hourly2021-01-01Standard global model
gefswiredGlobal ensemble 32m6-hourly2017-01-01Default member c00; opt-in via member=
gdaswiredGlobal 0.25° short6-hourly2021-01-01GFS analysis system
nbmwiredRegional blendhourly2020-01-01National Blend; fxx=0 auto-bumps to 1
rapwiredCONUS 13kmhourly2020-01-01Rapid refresh
rrfswiredCONUS 3kmhourly2024-01-01HRRR successor (pre-operational)
rtmawiredCONUS 2.5km analysishourly2024-01-01Real-time mesoscale (fxx=0 only)
urmawiredCONUS 2.5km analysishourly2024-01-01Un-Restricted MA (fxx=0 only)
cfswiredGlobal 1° (4-member)6-hourly2011-01-01Climate Forecast System

All 11 NCEP-family models wired in Python.

ModelWiringCycle freqHistorical depthNotes
ecmwf_ifs_hresreserved6-hourly2022-01-01Deterministic IFS HRES
ecmwf_ifs_ensreserved6-hourly2022-01-01Ensemble IFS
ecmwf_aifs_singlereserved6-hourly2024-02-25AI single
ecmwf_aifs_ensreserved6-hourly2024-02-25AI ensemble
ModelWiringCycle freqHistorical depthNotes
hrdpsreservedhourlylive-onlyHigh-Resolution Deterministic Prediction
rdpsreserved6-hourlylive-onlyRegional Deterministic Prediction
gdpsreserved12-hourlylive-onlyGlobal Deterministic Prediction
gepsreserved12-hourlylive-onlyGlobal Ensemble Prediction
repsreserved12-hourlylive-onlyRegional Ensemble Prediction

MSC models raise HistoricalDepthError(archive_depth=None) (live-only Datamart, 24h retention) — different from NwpModelNotAvailableError so callers can branch on the recovery action.

ModelWiringNotes
hafsreservedHurricane Analysis & Forecast System
namreservedNorth American Mesoscale — retires 2026-08-31 (NWS scn26-47)
hrefreservedHigh-Resolution Ensemble Forecast — retires 2026-08-31
hireswreservedHigh-Resolution Window — retires 2026-08-31

Calling a retiring legacy model emits DeprecatedModelWarning with the retirement date.

from mostlyright.weather import forecast_nwp
from datetime import datetime, UTC
df = forecast_nwp(
"KNYC", "hrrr",
cycle=datetime(2026, 5, 27, 12, tzinfo=UTC),
fxx=24,
)
print(df[["station", "valid_time", "temp_c"]])
  • AWS BDP / Google Cloud / Azure — tolerate aggressive parallelism. Default httpx.Limits per FORECAST-LIMITS.md.
  • NOMADS — capped at NOMADS_CONCURRENCY_CAP=4. mostlyright fails fast on 403.
  • MSC Datamart — undocumented; mostlyright is polite (N≤4).
  • ECMWF Open Data — 500 simultaneous connections per IP; mostlyright uses N≤8.
ErrorWhen it fires
NwpModelNotAvailableErrorReserved model called (ECMWF, HAFS, legacy)
HistoricalDepthErrorCycle older than the model’s archive depth, OR MSC×5 (live-only)
NoLiveForNwpErrorThe wired mirror has no live cycle reachable
GribIntegrityErrorDecoded GRIB2 bytes failed structural validation
DeprecatedModelWarningNAM / HREF / HiResW after 2026-08-31 retirement