Skip to content

Python quickstart

mostlyrightmd ships three PyPI packages — mostlyrightmd (the core join), mostlyrightmd-weather (the public-API fetchers), and mostlyrightmd-markets (the Kalshi/Polymarket resolvers). The [research] extra installs everything research() needs, including pandas and pyarrow.

Terminal window
pip install 'mostlyrightmd[research]>=0.1.0,<0.2'

Python 3.11+. No API key. The first call writes a parquet cache to ~/.mostlyright/cache/; subsequent calls in the same window are local-only.

import mostlyright
df = mostlyright.research(
station="KNYC",
from_date="2025-01-06",
to_date="2025-01-12",
)
print(df.head())

Output is a pandas DataFrame with one row per settlement date in [from_date, to_date]. Columns include:

date, station, cli_high_f, cli_low_f, cli_report_type,
obs_high_f, obs_low_f, obs_mean_f, obs_mean_dewpoint_f,
obs_max_wind_kt, obs_max_gust_kt, obs_total_precip_in,
obs_count, market_close_utc

cli_high_f / cli_low_f come from the NWS CLI overnight final — the Kalshi NHIGH/NLOW settlement source. obs_high_f / obs_low_f come from the merged METAR feed (AWC, IEM ASOS, GHCNh) and are byte-equivalent to mostlyright==0.14.1’s client.pairs(...) output on the 5 parity fixtures.

research() v0.1.0 supports the 20 Kalshi-traded US stations. Pass either the 3-letter NWS code or the 4-letter ICAO:

mostlyright.research("KNYC", "2025-01-06", "2025-01-12") # ICAO
mostlyright.research("NYC", "2025-01-06", "2025-01-12") # NWS code
mostlyright.research("KLAX", "2025-01-06", "2025-01-12")
mostlyright.research("KORD", "2025-01-06", "2025-01-12")

Unknown codes raise ValueError with the canonical list.

Calls write to ~/.mostlyright/cache/v1/:

~/.mostlyright/cache/v1/
├── observations/{ICAO}/{YYYY}/{MM}.parquet # per-month METAR aggregates
└── climate/{ICAO}/{YYYY}.parquet # per-year NWS CLI

Override the root with MOSTLYRIGHT_CACHE_DIR:

Terminal window
export MOSTLYRIGHT_CACHE_DIR=/data/mostlyright

The current LST month is never cached — those observations are still arriving. Every other month is read locally after the first fetch.

research() is the database surface. For live METAR ticks (dashboards, threshold alerts, real-time settlement watching), use mostlyright.live.stream():

import asyncio
import mostlyright
async def main() -> None:
async for row in mostlyright.live.stream("KNYC"):
print(row["observed_at"], row["temp_f"])
asyncio.run(main())

live.stream() yields one row per fresh METAR from a single source (awc by default). It never writes to the cache. See live streaming in the SDK repo for source selection, polite-floor cadence, and multi-station fan-out.

  • Temporal safetyKnowledgeView for point-in-time filtering, LeakageDetector for the audit path.
  • Source identity — Mode 1 vs Mode 2, SourceMismatchError.
  • Cache migration — moving from ~/.tradewinds/ to ~/.mostlyright/.