# therminal-py

Python SDK for [Therminal](https://api.mostlyright.xyz) — Kalshi temperature prediction markets + NWS weather data + real-time METAR signaling.

## Install

```bash
pip install therminal-py            # core
pip install therminal-py[pandas]    # + DataFrame + Parquet support
pip install therminal-py[ml]        # + scikit-learn ML features
pip install therminal-py[torch]     # + PyTorch Dataset
pip install therminal-py[cli]       # + CLI tool
pip install therminal-py[all]       # pandas + ml + cli
```

Requires Python 3.11+.

## Quick Start

```python
from therminal.weather import WeatherHistory, WeatherLive
from therminal.markets import MarketsClient

# Historical observations (via therminal-api)
weather = WeatherHistory()
obs = weather.observations(station="NYC", units="metric", as_dataframe=True)

# Live METAR (direct from AWC — same Observation schema as historical)
live = WeatherLive()
current = live.current("NYC")
print(current[0].temp_f)

# Batch: one AWC request for multiple stations
batch = live.current(["NYC", "ATL", "MDW", "LAX"])

# Market candles
markets = MarketsClient()
df = markets.candles(market="KXHIGHNY-26MAR20-T50", from_date="2026-03-01", as_dataframe=True)
```

Backward compatible: `from therminal import TherminalClient` still works. `WeatherClient` and `LiveClient` are aliases for `WeatherHistory` and `WeatherLive`.

## Configuration

Create `~/.therminal.toml` for sensible defaults:

```toml
[defaults]
units = "metric"
station = "NYC"

[api]
base_url = "https://api.mostlyright.xyz"
```

Resolution order: file < env vars (`THERMINAL_UNITS`, `THERMINAL_TZ`, `THERMINAL_STATION`) < per-call kwargs.

## Live METAR (AWC Direct)

`WeatherLive` fetches real-time METAR from the Aviation Weather Center. Returns `Observation` objects identical in schema to `WeatherHistory.observations()`, eliminating train/serve skew for trading signals.

```python
from therminal.weather import WeatherLive

live = WeatherLive()
obs = live.current(["NYC", "ATL"])         # batch: one request
history = live.latest("NYC", hours=3)      # last 3 hours
metric = live.current("NYC", units="metric")  # with conversion
```

## ML Features (scikit-learn)

```bash
pip install therminal-py[ml]
```

```python
from therminal.ml import WeatherFeatures, LOBFeatures
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import GradientBoostingRegressor

pipe = make_pipeline(
    WeatherFeatures(station="ATL", sources=["omo", "metar"], lookback_hours=24),
    StandardScaler(),
    GradientBoostingRegressor(),
)
pipe.fit(dates_train, y_train)
pipe.predict(dates_test)
```

## Typed Models

All responses return frozen dataclasses with both attribute and dict-style access:

```python
obs = weather.observations(station="NYC")[0]
obs.temp_f          # attribute access
obs["temp_f"]       # dict access (backward compat)
obs.get("temp_f")   # .get() with default
obs.to_dict()       # full dict with all 29 fields
```

## Documentation

Full API reference with interactive playground: **[docs.mostlyright.xyz](https://docs.mostlyright.xyz)**
