Metadata-Version: 2.4
Name: mostlyright
Version: 0.14.0
Summary: Settlement truth layer for prediction markets. Raw weather observations, climate records, and forecasts with point-in-time query semantics.
Project-URL: Homepage, https://mostlyright.md
Project-URL: Repository, https://github.com/Tarabcak/mostlyright
Project-URL: Issues, https://github.com/Tarabcak/mostlyright/issues
Project-URL: Changelog, https://github.com/Tarabcak/mostlyright/releases
Project-URL: Documentation, https://mostlyright.md/docs/
Author-email: Robert Tarabcak <tarabcakr@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: Kalshi,METAR,forecasts,machine-learning,prediction-markets,quant,settlement,weather
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27
Requires-Dist: jsonschema>=4.21
Requires-Dist: tzdata; sys_platform == 'win32'
Provides-Extra: dev
Requires-Dist: boto3>=1.34; extra == 'dev'
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: fastapi>=0.115; extra == 'dev'
Requires-Dist: mypy>=1.11; extra == 'dev'
Requires-Dist: pandas>=2.2; extra == 'dev'
Requires-Dist: pyarrow>=17.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: pyyaml>=6.0; extra == 'dev'
Requires-Dist: ruff>=0.7; extra == 'dev'
Requires-Dist: twine>=5.0; extra == 'dev'
Requires-Dist: uvicorn>=0.32; extra == 'dev'
Provides-Extra: parquet
Requires-Dist: pandas>=2.2; extra == 'parquet'
Requires-Dist: pyarrow>=17.0; extra == 'parquet'
Provides-Extra: server
Requires-Dist: boto3>=1.34; extra == 'server'
Requires-Dist: fastapi>=0.115; extra == 'server'
Requires-Dist: pandas>=2.2; extra == 'server'
Requires-Dist: pyarrow>=17.0; extra == 'server'
Requires-Dist: uvicorn>=0.32; extra == 'server'
Description-Content-Type: text/markdown

# MostlyRight

Settlement truth layer for prediction markets. Raw weather observations,
climate records, and forecasts with point-in-time query semantics — for
quants training Kalshi NHIGH/NLOW temperature models.

[![PyPI](https://img.shields.io/pypi/v/mostlyright.svg)](https://pypi.org/project/mostlyright/)
[![Python](https://img.shields.io/pypi/pyversions/mostlyright.svg)](https://pypi.org/project/mostlyright/)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

## Install

```bash
pip install mostlyright             # SDK only (~2 deps: httpx, jsonschema)
pip install mostlyright[parquet]    # adds pandas + pyarrow for DataFrames
```

## Quickstart

```python
from mostlyright import MostlyRightClient

with MostlyRightClient() as client:
    obs = client.observations("NYC", from_date="2024-07-04", to_date="2024-07-04")
    # → list[Observation] with 30 raw METAR fields (temp_f, wind_speed_kt, ...)
```

## Training workflow

Paired observations + NWS CLI settlement + optional forecasts, one row per
settlement date. The primary training surface.

```python
from mostlyright import MostlyRightClient

with MostlyRightClient() as client:
    # 5 years, joined against IEM MOS forecasts + Open-Meteo fallback.
    train = client.pairs(
        "NYC",
        from_date="2020-01-01",
        to_date="2024-12-31",
        include_forecast=True,
        as_dataframe=True,      # requires mostlyright[parquet]
    )
    # Columns: date, cli_high_f, cli_low_f (settlement truth),
    #          obs_high_f, obs_low_f (observed),
    #          fcst_high_f, fcst_low_f, fcst_model, fcst_issued_at, ...
```

## Inference workflow

Live forecast signal, fetched directly from the upstream source — no
MostlyRight infrastructure between the quant and the weather model.
Column parity with the historical `client.forecasts()` output is the
contract.

```python
import mostlyright

live = mostlyright.live.get_forecast("NYC", model="NBS", source="iem")
# → pandas.DataFrame with the same columns as client.forecasts(...)
prediction = model.predict(live)

# Or Open-Meteo (seamless hourly):
live_om = mostlyright.live.get_forecast(
    "NYC", model="gfs_seamless", source="open_meteo"
)
```

## Authentication

Dev mode requires no key. Production quants should set:

```bash
export MOSTLYRIGHT_API_KEY=<your-key>
```

Or pass explicitly:

```python
import os
from mostlyright import MostlyRightClient

client = MostlyRightClient()  # reads MOSTLYRIGHT_API_KEY from env
# Legacy THERMINAL_API_KEY is also honoured for drop-in migration.
```

## Point-in-time queries

Every method accepts an `as_of` watermark. Results are filtered so an
inference loop on historical data sees only what was knowable at that
UTC moment — climate records are withheld until the NWS CLI publication
threshold has passed.

```python
snap = client.snapshot("NYC", as_of="2024-07-04T18:00:00Z")
snap.observations             # filtered to [window_start_utc, as_of]
snap.climate                  # None until CLI publishes (~10h after midnight LST)
snap.version                  # DataVersion — reproducibility token
```

## Data methods

| Method | Returns | Purpose |
| --- | --- | --- |
| `client.observations(station, from_date, to_date)` | METAR/SPECI observations | 30 raw fields, up to 24/day |
| `client.climate(station, from_date, to_date)` | NWS CLI daily records | Kalshi settlement source |
| `client.forecasts(station, ...)` | IEM MOS runs | Discrete issued_at runs, per-hour rows |
| `client.forecast_series(station, ...)` | Open-Meteo hourly | Seamless hourly, metric/SI |
| `client.pairs(station, from_date, to_date)` | Settlement-date rows | Observations + climate + optional forecast, joined |
| `client.snapshot(station, as_of)` | `DataSnapshot` | All data available at a UTC moment |
| `client.feature_catalog()` | Feature metadata | Discovery surface for AI agents |
| `mostlyright.live.get_forecast(station, ...)` | pandas.DataFrame | Live upstream forecast |

See [`docs/QUICKSTART.md`](docs/QUICKSTART.md) for the longer walkthrough
of each method, format options (`toon`, `parquet`, `csv`), and settlement
window conventions.

## Available stations

20 airports with active Kalshi NHIGH/NLOW markets. Codes accept 3-letter
NWS form (`NYC`) or 4-letter ICAO (`KNYC`):

```
ATL  AUS  BOS  DCA  DEN  DFW  HOU  LAS  LAX  MDW
MIA  MSP  MSY  NYC  OKC  PHL  PHX  SAT  SEA  SFO
```

Station metadata (lat/lon, timezone, ICAO) is available at runtime:

```python
stations = client.stations()             # list[StationInfo]
info = client.station("NYC")             # one station
```

## Error handling

The SDK raises typed exceptions mapped from HTTP status codes:

```python
from mostlyright.exceptions import (
    NotFoundError, ValidationError, RateLimitError,
    AuthenticationError, ForbiddenError, ServerError,
)

try:
    obs = client.observations("XYZ")  # unknown station
except NotFoundError as exc:
    ...
except RateLimitError as exc:
    wait_s = exc.retry_after
```

All exception classes subclass `mostlyright.exceptions.TherminalError`.

## Schemas

Every data entity has a JSON Schema under [`specs/`](https://github.com/Tarabcak/mostlyright/tree/main/specs)
on GitHub (`observation.json`, `climate.json`, `forecast.json`,
`forecast_series.json`, `snapshot.json`, `market_unified.json`, ...).
The SDK validates every response against these schemas before returning.

## Changelog

Release notes live on [GitHub Releases](https://github.com/Tarabcak/mostlyright/releases).

## License

MIT — see [LICENSE](LICENSE).
