A Python + TypeScript SDK for public data.
mostlyright gives you one clean interface to public data sources — general-first. Today it ships weather (live observations, forecasts, climate history) as source-identified domain tables, plus dataset(), a leakage-safe training-table builder that aligns them to any label you choose. Prediction markets (Kalshi, Polymarket) are a thin convenience layer on top. Local-first, no hosted backend, no API key.
# Python
pip install 'mostlyrightmd[research]'
# TypeScript / Node
pnpm add mostlyrightPython 3.11+. Node 18+. No API key required for any package below.
# Python
import mostlyright
# dataset() is the alignment engine; research() is a fully working alias.
# Pass an explicit label= (here the NWS CLI settlement extremes).
df = mostlyright.dataset("KNYC", "2025-01-06", "2025-01-12", label="cli")
print(df.head())
# pandas DataFrame: one row per LST settlement date
# Columns: date, station, cli_high_f, cli_low_f, obs_high_f, obs_low_f,
# obs_mean_f, obs_count, fcst_*, market_close_utc// TypeScript
import { research } from "mostlyright";
const rows = await research("KNYC", "2025-01-06", "2025-01-12");
console.log(rows[0]);
// ReadonlyArray<PairsRow>: same schema as Python, JSON-serializableFirst call writes a parquet (Python) or JSON-envelope (Node) cache to ~/.mostlyright/cache/. Subsequent calls in the same window are local-only — no network.
Full quickstart with concepts at https://mostlyright.md/docs/sdk/.
| Package | Description | Downloads | Status |
|---|---|---|---|
mostlyrightmd |
Core types, schemas, validators, the research() join, and snapshot primitives. Imports as mostlyright. |
stable | |
mostlyrightmd-weather |
Weather data fetchers — live METAR (AWC), ASOS archive (IEM), historical observations (GHCNh), and NWS climate text products (CLI). Direct public-API access. | stable | |
mostlyrightmd-markets |
Prediction-market data — Kalshi NHIGH/NLOW weather-contract resolvers, Polymarket discovery + settlement, and Kalshi + Polymarket trade history. | stable | |
mostlyrightmd-edgar |
SEC filings (10-K, 10-Q, 8-K) — direct EDGAR full-text + facts access. | n/a | planned |
mostlyrightmd-equities |
Equities structured data — fundamentals, corporate actions, normalized XBRL pulls. | n/a | planned |
mostlyrightmd-fred |
Federal Reserve economic data (FRED series, observations, releases). | n/a | planned |
mostlyrightmd-courts |
Court filings — federal (PACER) and state dockets, opinions, party data. | n/a | planned |
mostlyrightmd-fda |
FDA approvals — drug + medical-device clearance records, post-market events. | n/a | planned |
| Package | Description | Downloads | Status |
|---|---|---|---|
mostlyright |
Meta package — one import { research } from "mostlyright" for weather data + prediction-market settlements + the core join. |
stable | |
@mostlyrightmd/core |
Core types, schemas, validators, temporal-safety primitives, and the research() join. |
stable | |
@mostlyrightmd/weather |
Weather data fetchers — live METAR (AWC), ASOS archive (IEM), historical observations (GHCNh), and NWS climate text products (CLI). | stable | |
@mostlyrightmd/markets |
Prediction-market data — Kalshi NHIGH/NLOW weather-contract resolvers, Polymarket discovery + settlement, and Kalshi + Polymarket trade history. | stable | |
@mostlyrightmd/edgar |
SEC filings (10-K, 10-Q, 8-K) — direct EDGAR full-text + facts access. | n/a | planned |
@mostlyrightmd/equities |
Equities structured data — fundamentals, corporate actions, normalized XBRL pulls. | n/a | planned |
@mostlyrightmd/fred |
Federal Reserve economic data (FRED series, observations, releases). | n/a | planned |
@mostlyrightmd/courts |
Court filings — federal (PACER) and state dockets, opinions, party data. | n/a | planned |
@mostlyrightmd/fda |
FDA approvals — drug + medical-device clearance records, post-market events. | n/a | planned |
The domain tables are the raw ingredients — each row carries a durable source
identity so a model trained on one provider never silently reconciles against
another. Fetch them directly and join by hand, or feed them to dataset().
from mostlyright.weather import obs, climate
# Live + archive observations, fused (AWC > IEM > GHCNh) or source-pinned.
o = obs("KNYC", "2024-01-01", "2024-12-31", granularity="observation")
c = climate("KNYC", "2024-01-01", "2024-12-31") # NWS CLI settlement labels
# Forecasts compose into dataset() via features=["forecasts"]; the raw NWP
# table is mostlyright.forecasts.forecast_nwp (needs the [nwp] extra).dataset() is the alignment engine — a training-table builder, not a fixed
recipe. Give it a station, a window, a label axis, and the features you want;
it returns one leakage-safe row per LST settlement day, every column aligned to the
settlement calendar and joined as-of so nothing from the future leaks backward.
research() is a fully working alias in this release.
import mostlyright
# A general feature table — works for ANY catalog station worldwide, no market
# required. label=None composes features only (no settlement label columns).
df = mostlyright.dataset("EGLL", "2025-01-06", "2025-01-12", label=None)
# Attach the WU/NOAA-WRH daily extremes as the label (native Celsius names).
df = mostlyright.dataset("KNYC", "2025-01-06", "2025-01-12", label="daily_extremes")
# Or bring your own label frame — the SDK aligns it to the settlement calendar.
df = mostlyright.dataset("KNYC", "2025-01-06", "2025-01-12", label=my_label_frame)Calling
dataset()without an explicitlabel=still returns the NWS CLI settlement columns byte-identically, but emits aFutureWarning: the default flips tolabel=Noneat 2.0. Passlabel="cli"orlabel=Noneto silence it. Full walkthrough indocs/dataset.md.
dataset() (and its research() alias) stamps a source identity on every row.
Pinning source= on obs() returns single-source coverage; the validator catches
train/infer mismatches at load time, instead of silently corrupting predictions in
production.
from mostlyright.weather import obs
from mostlyright.core import validate_dataframe
train = obs("KNYC", "2024-01-01", "2024-12-31",
source="iem.archive", granularity="observation")
# Validator pins the schema's expected source. SourceMismatchError fires if you
# accidentally route a source-blind (fused AWC+IEM+GHCNh) DataFrame through an
# iem.archive-only schema. See the source-identity contract for the full rule.
validate_dataframe(train, schema_id="schema.observation.v1")Pinning
source=returns a different row composition than the fused default — migrating a pinned feature is a retrain event, not a find-replace. The one contract forsource=/delivery=/ grain across every vertical lives indocs/source-identity.md.
The prediction-market entry points are thin delegators to the venue-free
dataset() — they own all venue knowledge (station resolution, strike parsing,
outcome targets) and route to the venue-correct label: Kalshi settles on NWS CLI
(label="cli"), Polymarket on WU/NOAA-WRH extremes (label="daily_extremes").
outcome=True appends a binary label_outcome by binarizing that venue's label
against its parsed strike (inclusive >=).
from mostlyright.markets import kalshi, polymarket
# Kalshi → NWS CLI settlement. outcome=True adds the binary YES/NO target.
k = kalshi.dataset("KXHIGHNY-25MAY26-T79", "2025-05-26", "2025-05-26", outcome=True)
# Polymarket → WU/NOAA-WRH extremes (the correct ground truth — NOT cli_*).
p = polymarket.dataset("<event_id>", "2025-05-26", "2025-05-26", outcome=True)Every response carries a stable schema.*.v1 URI and serializes to JSON-Schema-validated shapes. Drop responses into MCP tool outputs or OpenAI/Anthropic function-call returns without re-shaping.
import { research } from "mostlyright";
import { validateRows } from "@mostlyrightmd/core/validator";
const rows = await research("KNYC", "2025-01-06", "2025-01-12");
const result = validateRows(rows, "schema.observation.v1");
// result.audit_log carries the schema URI + source identity + row count
// — ready to pass through to an agent's tool-call response.Native-L2 single-pixel extraction across the entire populated world, each
instrument family carrying its own leakage-safe source identity so a model
trained on one never silently reconciles against another. A feature supplement
(cloud-mask / land-surface covariates), not a primary Tmax/Tmin settlement
source. Ships as the optional mostlyrightmd-weather[satellite] extra
(whole-file S3 reads via s3fs + h5netcdf/h5py; no hosted backend — reads
the same anonymous public buckets as the AWC/IEM/NWP calls).
| Source identity | Instrument | Coverage | Access |
|---|---|---|---|
noaa_goes |
GOES-East/West ABI | Americas + eastern Pacific | anonymous |
jma_himawari |
Himawari AHI | Asia-Pacific | anonymous |
noaa_viirs |
VIIRS (JPSS) polar swath | global incl. poles | anonymous |
eumetsat_meteosat |
Meteosat SEVIRI (MSG-CLM) | Europe/Africa/Indian-Ocean | key (EUMETSAT Data Store) |
pip install mostlyrightmd-weather[satellite]from mostlyright.weather.satellite import satellite
# Explicit source.
df = satellite("RJTT", "himawari9", product="AHI-L2-FLDK-Clouds", start=..., end=...)
# Omit satellite= to AUTO-ROUTE by the station's coverage region.
df = satellite("KSEA", start=..., end=...) # -> noaa_goes (GOES-West/PACUS)
df = satellite("RJTT", start=..., end=...) # -> jma_himawari
df = satellite("EGLL", start=..., end=...) # -> noaa_viirs fill (Meteosat gated from auto-route; see below)
# Meteosat SEVIRI projection landed but its live Data-Store GRIB reader is a
# forward seam, so it is reachable by EXPLICIT satellite= (and gated out of
# auto-routing). An explicit fetch surfaces a clear "not yet wired" signal:
df = satellite("EGLL", "meteosat-0deg", start=..., end=...) # needs a Data-Store keyLive vs hosted. delivery="live" (default) self-parses the public data
directly. delivery="hosted" is the Phase-27 paid-adapter seam and raises a
clear "arrives in Phase 27" error — there is no api.mostlyright.md call
anywhere. The future paid adapter shares each native source identity
(byte-identical to live self-extraction), distinguished only by the
informational delivery lineage column.
The fleet bulk/training path is python -m mostlyright.weather.satellite backfill (per-(satellite,year,month) slices, crash-safe resume,
--mirror aws|gcp, Thread/Process split). max_workers + the S3 rate cap are
probe-derived constants — run python -m mostlyright.weather.satellite probe to
re-measure. See docs/satellite.md for the source-identity
table, coverage map, auto-routing, cheap-CONUS steering, DSRF gating, the 28 TB
/ near-data reality, and the EUMETSAT key-setup.
- No hosted backend. Direct calls to public APIs (NOAA, NWS, IEM, Kalshi, Polymarket). No proxy. No vendor account. No rate-limited tier.
- Local-first cache. Parquet (Python) or JSON envelope (Node) at
~/.mostlyright/cache/. Byte-stable across runs — deterministic backtests. - Schema-versioned outputs. Every response carries a stable
schema.*.v1URI. Train/infer source mismatches fail loudly instead of silently corrupting models. - Python + TypeScript peers. Same
research()shape, byte-equivalent on the parity fixtures. Use whichever runtime your stack prefers. - MIT licensed. Use it commercially. Fork it. Ship it.
- Quickstart + concepts: https://mostlyright.md/docs/sdk/
dataset()— the alignment engine:docs/dataset.md— the label axis, the contributor protocol, panels, and the honest with/without comparison.- Source identity — the cross-vertical kwarg contract:
docs/source-identity.md—source=/delivery=/ grain, the labels-only firewall, and the fetch-provenance ledger. - Migrating to 1.15.0:
docs/migration-1.15.md— the D-22 default-labelFutureWarning,include_*→features=, andcontract=→ the markets layer. - API reference: https://mostlyright.md/docs/sdk/ (Python + TypeScript reference auto-generated per release)
- Migration from the legacy hosted-API client: https://mostlyright.md/docs/sdk/migration/legacy/
Bug reports, feature requests, and pull requests are welcome. See CONTRIBUTING.md for the development workflow (fork → branch → PR) and the test gate. See CODE_OF_CONDUCT.md for community guidelines.
For security issues, see SECURITY.md — do not file public issues for vulnerabilities; email vu@mostlyright.md instead.
MIT. See LICENSE.
mostlyright calls the following public APIs directly. We are grateful for the work that makes weather and market data accessible at the public-API layer:
- NOAA Aviation Weather Center (AWC) — live METAR feeds
- Iowa State University Iowa Environmental Mesonet (IEM) — ASOS archive + CLI text products
- NOAA National Centers for Environmental Information (NCEI) — GHCNh historical observations
- National Weather Service (NWS) — climate data products (CLI) and forecast model outputs
- Open-Meteo — multi-provider forecast aggregation (added Phase 20). 36 models across NCEP / ECMWF / DWD / Météo-France / Asia / Oceania / Europe / GEM Canada. Leakage-safe via per-cycle endpoint + conservative
issued_atlower bound. See docs/forecast-sources.md. - Kalshi + Polymarket — public prediction-market metadata + settlement feeds