Metadata-Version: 2.5
Name: uk-energy
Version: 0.2.0
Summary: Typed Python clients for the UK's public electricity data APIs: Elexon Insights, NESO Data Portal, Carbon Intensity, DNO open data, Octopus.
Project-URL: Homepage, https://github.com/Styrle/Wind-farm-sdk
Project-URL: Repository, https://github.com/Styrle/Wind-farm-sdk
Project-URL: Issues, https://github.com/Styrle/Wind-farm-sdk/issues
Author: Josh Serpis
License-Expression: MIT
Keywords: bmrs,carbon-intensity,elexon,energy,grid,neso,uk
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Requires-Dist: tzdata>=2024.1; sys_platform == 'win32'
Description-Content-Type: text/markdown

# uk-energy (Python)

Typed Python clients for the UK's public electricity data APIs. Mirrors the TypeScript packages in the same repo.

```bash
pip install uk-energy
```

Contains BMRS data © Elexon Limited copyright and database right 2026.
Contains NESO Data Portal data, used under the NESO Open Data Licence.
Carbon Intensity data © National Energy System Operator, CC BY 4.0.

See the [repo README](../README.md) for the full attribution and licence notes.

## Packages

| Module | Covers | Status |
| --- | --- | --- |
| `uk_energy.core` | `HttpClient` / `AsyncHttpClient` on httpx: retries with jittered backoff, per-host rate limiting, pagination, pluggable cache, `FixtureTransport` for tests | built, unpublished |
| `uk_energy.carbon_intensity` | Carbon Intensity API: `CarbonIntensityClient` / `AsyncCarbonIntensityClient` — national and regional intensity, forecasts, generation mix | published |
| `uk_energy.elexon` | Elexon Insights (BMRS): `ElexonClient` / `AsyncElexonClient` — BOALF, BOD, FUELINST, physical notifications, BMU reference, system prices | built, unpublished |
| `uk_energy.neso` | NESO Data Portal | planned |

```python
from uk_energy.elexon import ElexonClient

ex = ElexonClient()
boalf = ex.datasets_boalf("2026-10-15T00:00Z", "2026-10-15T01:00Z")  # 1,650 rows, every unit
curtailed = [r for r in boalf if r["soFlag"]]
wind = [u for u in ex.reference_bm_units() if u["fuelType"] == "WIND"]  # 287 units
ex.balancing_system_prices("2026-10-15", 1)[0]["systemSellPrice"]  # 174.23
ex.datasets_fuelinst(publish_from="2026-10-15T00:00Z", publish_to="2026-10-15T00:30Z")
ex.datasets_stream("MELS", from_="2026-10-15T00:00Z", to="2026-10-15T01:00Z")  # any /stream dataset
```

```python
# every WIND unit: the reference list + 3 requests per 200 units
day = ex.curtailment_for_day("2026-10-15")
total = day["total"]  # curtailedMwh, soFlaggedMwh, cashflowGbp, units, acceptances
worst = day["units"][0]  # most-curtailed unit; day["periods"] has one row per unit per period
```

Settlement time is local (Europe/London): `uk_energy.core.settlement_period_at(dt)` gives the
settlement date and period for an instant; `settlement_period_start(date, sp)` inverts it.

```python
from uk_energy.carbon_intensity import CarbonIntensityClient

ci = CarbonIntensityClient()
ci.intensity_current()["intensity"]  # {"forecast": 125, "actual": 134, "index": "moderate"}
ci.regional_for_postcode("M1")["data"][0]  # region 3, North West England
ci.intensity_forward48h("2026-10-15T00:00Z")  # 97 half-hour periods
```

Note: `intensity_for_date()` uses a local GB day (BST in summer), and range endpoints include
the period containing `from_`; see the TypeScript package README for the full list.

## Development

```bash
cd python
uv sync
uv run pytest            # fixtures only, no network
UK_ENERGY_LIVE=1 uv run pytest -m live
uv run ruff check . && uv run mypy
```
