Migration
v0.14.1 → v1.2
v1.2 produces byte-equivalent output to v0.14.1’s client.pairs() on five canonical fixtures. This page preserves that historical migration only. For the current 2.0 API, use the upgrade guide.
TL;DR — the diff
Section titled “TL;DR — the diff”| API | v0.14.1 | v1.2 |
|---|---|---|
| Package name | tradewinds | mostlyrightmd (Python) / mostlyright (TS meta) |
| Import | from tradewinds import Client | from mostlyright import research |
| Main call | Client().pairs(station, from, to) | research(station, from, to) |
| Cache directory | ~/.tradewinds/cache/ | ~/.mostlyright/cache/ |
| Env var | TRADEWINDS_CACHE_DIR | MOSTLYRIGHT_CACHE_DIR |
| Async | await client.pairs(...) | df = research(...) (sync — async still available via live.*) |
| TS package | n/a | mostlyright + @mostlyrightmd/* scoped |
Output frame is byte-equivalent. Same columns, same dtypes, same row order, same null handling.
Python migration
Section titled “Python migration”Install
Section titled “Install”Remove the legacy client (pip uninstall tradewinds) and install the current SDK from PyPI:
pip install mostlyrightmdImport + first call
Section titled “Import + first call”from tradewinds import Client
client = Client()df = await client.pairs("KNYC", "2025-01-06", "2025-01-12")from mostlyright import research
df = research("KNYC", "2025-01-06", "2025-01-12")No more Client object
Section titled “No more Client object”The v0.14.1 Client carried per-instance state for cache path, HTTP timeouts, etc. v1.x exposes those as call-site kwargs or module-level overrides:
client = Client(cache_dir="/custom/cache", timeout=60)
# v1.2 — env varimport osos.environ["MOSTLYRIGHT_CACHE_DIR"] = "/custom/cache"from mostlyright import researchdf = research("KNYC", "2025-01-06", "2025-01-12")For per-call overrides, see Build a point-in-time research table.
v0.14.1 was async-first; v1.x defaults to sync because backtest/notebook workflows dominate. Async is still available for live streaming:
import asynciofrom mostlyright.weather import live
async def main(): async for row in live.stream("KNYC"): print(row)
asyncio.run(main())If you need parallel research calls, use asyncio.to_thread:
import asynciofrom mostlyright import research
async def main(): dfs = await asyncio.gather(*[ asyncio.to_thread(research, s, "2025-01-06", "2025-01-12") for s in ["KNYC", "KORD", "KLAX"] ])Cache directory migration
Section titled “Cache directory migration”Move your existing cache:
mv ~/.tradewinds ~/.mostlyrightOr set the env var:
export MOSTLYRIGHT_CACHE_DIR=~/.tradewinds/cacheBoth work. The on-disk format (parquet, per-month layout) is unchanged from v0.14.1 — your existing cache reads without re-fetching.
Resolution order is canonical → legacy → default: MOSTLYRIGHT_CACHE_DIR wins when set; the legacy TRADEWINDS_CACHE_DIR var was honored for one release after the rename and is ignored now; otherwise ~/.mostlyright/cache/ is used. The TypeScript FsStore followed the same rename (cache-ts/).
TypeScript SDK is new
Section titled “TypeScript SDK is new”v0.14.1 had no TypeScript SDK. v1.2 adds equivalent methods through the mostlyright package and scoped @mostlyrightmd/* packages on npm:
import { research } from "mostlyright";const rows = await research("KNYC", "2025-01-06", "2025-01-12");The TS API mirrors Python — see the Quickstart.
v1.2 additions (not in v0.14.1)
Section titled “v1.2 additions (not in v0.14.1)”These are net-new — your v0.14.1 code doesn’t break, but you can opt in:
research(include_forecast=True)— Phase 17 wired forecasts end-to-end. WasNotImplementedErrorin v0.14.1.research(forecast_models=["hrrr","gfs"])— per-NWP-model forecast fan-out.research(qc=True)— Phase-3.x QC engine.research(source="iem")— single-source provenance pinning (withSourceMismatchError).research(sources=["awc","iem"])— LIVE_V1 multi-source subset.research(backend="polars")— Phase 6 Polars backend (Python only).research(return_type="wrapper")— Phase 6TradewindsResultwrapper.live.stream()/live.latest()— Phase 11 live ticker.obs()— Phase 7 ingest-planner.daily_extremes()— international per-day rollups.forecast_nwp()— Phase 17 gridded NWP, 24 models.DataAvailabilityError— Phase 21 typed exception for data-availability paths.
v1.2 breakage list
Section titled “v1.2 breakage list”The ones you have to fix:
- Package name.
tradewinds→mostlyrightmd. There’s nopip install tradewindsshim. - Client class removed.
Client().pairs()→research(). Construction kwargs become module env vars / call kwargs. - Async signature.
await client.pairs(...)→research(...)(sync). Wrap inasyncio.to_threadif you need async. - Cache path.
~/.tradewinds/cache/→~/.mostlyright/cache/.mvis enough; format unchanged.
That’s the full list. The columns, dtypes, row order, and null handling are unchanged, so code that consumed the v0.14.1 DataFrame keeps working.
Verifying byte-equivalence
Section titled “Verifying byte-equivalence”If you have a v0.14.1 backtest and want to confirm v1.2 produces identical output:
# Generate from v0.14.1import picklefrom tradewinds import Client # in a v0.14.1 venvold = await Client().pairs("KNYC", "2025-01-06", "2025-01-12")pickle.dump(old, open("/tmp/v014.pkl", "wb"))
# Generate from v1.2import pickle, pandas as pdfrom mostlyright import research # in a v1.2 venvnew = research("KNYC", "2025-01-06", "2025-01-12")old = pickle.load(open("/tmp/v014.pkl", "rb"))pd.testing.assert_frame_equal(old, new) # exact equalityCI compares the five canonical fixtures on every release.
See also
Section titled “See also”- Build a point-in-time research table — the current research workflow
- Changelog — every release between v0.14.1 and v1.2