A tiny, tweepy-style Python wrapper for the Octopus Energy API (read-only)
Project description
🐙 octopy
A tiny, read-only Python wrapper for the Octopus Energy API, modelled on
tweepy: construct a client once, then call
get_* methods that return typed model objects.
Targets Octopus Energy Spain (api.oees-kraken.energy, Kraken-token auth)
and Octopus UK (api.octopus.energy, HTTP Basic auth), whose public
endpoints are handy for credential-free exploration and tests.
REST or GraphQL? The UK has public REST consumption endpoints, so the
Clientis a GET-only REST reader. Octopus Spain exposes its account and consumption data through the Kraken GraphQL API instead — that path lives inoctopy.graphql.KrakenGraphQLClient. Auth for Spain is a Kraken token minted via a GraphQL mutation, and there is no public products endpoint.
Looking for the web UI? It now lives in its own repo: octopus-energy-web.
What you get
octopy.Client— GET methods for products, tariff unit rates & standing charges, electricity/gas consumption, account details and postcode→region (GSP) lookups; typed models; a tweepy-stylePaginator; a status-code exception hierarchy; and a gas m³→kWh helper. Factories:Client.spain(token=…)andClient.uk(api_key=…).octopy.graphql.KrakenGraphQLClient— the Spain path (GraphQL, the one that actually carries ES data):login(obtainKrakenToken),account_numbers,hourly_consumption,account_summary.octopy.aio.AsyncKrakenGraphQLClient— anawaitable version of the above for asyncio / Home Assistant (optional[async]extra).scripts/obtain_token.py— mints a Kraken token for Spain (the GET-only client can't authenticate itself there).scripts/explore_spain.py— lists accounts + recent hourly consumption in one command (the quickest end-to-end check).
Layout
octopy/ # the package (pip-installable, depends only on requests)
├─ client.py # Client + factories + all GET methods
├─ models.py # Product, Consumption, Rate, Account, …
├─ countries.py # per-country config registry (base URLs, auth)
├─ pagination.py # Page + Paginator (tweepy-style)
├─ exceptions.py # HTTPException, Unauthorized, NotFound, …
├─ units.py # m3_to_kwh / kwh_to_m3
├─ graphql.py # KrakenGraphQLClient — the Spain (GraphQL) path
└─ aio.py # AsyncKrakenGraphQLClient (optional [async] extra)
scripts/ # obtain_token.py (mint token) · explore_spain.py (demo)
tests/ # test_client.py · test_graphql.py · smoke_live.py
pyproject.toml · requirements.txt · .env.example
Install
System Python may be old; use a modern one in a venv.
python3.13 -m venv .venv
.venv/bin/pip install -e . # editable install of the package
.venv/bin/pip install -e ".[async]" # …plus the async client (aiohttp)
.venv/bin/python -m unittest discover -s tests # offline tests
.venv/bin/python tests/smoke_live.py # live UK-public smoke test
Once published to PyPI: pip install octopus-kraken (imports as octopy), or
pip install "octopus-kraken[async]" for the async client.
Using the wrapper
import octopy
from datetime import datetime, timedelta, timezone
# --- Octopus Energy Spain: data is via GraphQL (Kraken) ---
from octopy.graphql import KrakenGraphQLClient
es = KrakenGraphQLClient.login(api_key="<kraken-api-key>") # or email=/password=
end = datetime.now(timezone.utc); start = end - timedelta(days=2)
for acct in es.account_numbers():
rows = es.hourly_consumption(acct, start, end) # electricity, hourly
print(acct, len(rows), "measurements")
# one-shot from the shell: python scripts/explore_spain.py --api-key <KEY>
# --- Octopus UK: public data needs no key (great for exploring/testing) ---
uk = octopy.Client.uk()
for p in uk.get_products(is_green=True):
print(p.code, p.display_name)
region = uk.get_grid_supply_points("BS1")[0].group_id # "_B"
tariff = uk.get_product("AGILE-24-10-01").electricity_tariff_code(region)
rates = uk.get_electricity_standard_unit_rates("AGILE-24-10-01", tariff)
# Walk every page, tweepy-style; convert SMETS2 gas m³ → kWh
from octopy import Paginator
all_rates = list(Paginator(uk.get_electricity_standard_unit_rates,
"AGILE-24-10-01", tariff).flatten())
print(octopy.m3_to_kwh(120.0), "kWh")
Getting a Spain (Kraken) token
python scripts/obtain_token.py --api-key <KRAKEN_API_KEY> # or --email/--password
Pass the printed token to Client.spain(token=…) / KrakenGraphQLClient(token=…).
Choosing a country
Octopus runs a separate API deployment per country. Select one with country=
(a code/alias, case-insensitive) on either client — it sets the base URL and
GraphQL endpoint for you. The Client.uk() / Client.spain() factories are
shorthands for country="GB" / country="ES".
octopy.Client(country="GB", api_key="sk_live_…") # == Client.uk(...)
octopy.Client(country="ES", token="…") # == Client.spain(...)
octopy.KrakenGraphQLClient(country="GB") # UK Kraken GraphQL endpoint
octopy.KrakenGraphQLClient.login(country="ES", api_key="…")
Defaults reflect each transport's reality: the REST Client defaults to the
UK (public, key-free data) while the GraphQL client defaults to Spain (the
deployment whose account/consumption data is GraphQL-only).
Built-in countries are GB (aliases: UK) and ES. Add another Kraken
deployment at runtime:
octopy.register_country(octopy.Country(
code="DE", name="Germany",
base_url="https://api.oeg-kraken.energy/v1", # example — verify the host
))
octopy.Client(country="DE", token="…")
Async (asyncio / Home Assistant)
For asyncio apps, octopy.aio.AsyncKrakenGraphQLClient is an awaitable
counterpart to KrakenGraphQLClient with the same methods. Install the extra
(pip install "octopus-kraken[async]"); the base package stays aiohttp-free.
from octopy.aio import AsyncKrakenGraphQLClient
async with await AsyncKrakenGraphQLClient.login(country="ES", api_key="…") as es:
for number in await es.account_numbers():
rows = await es.hourly_consumption(number, start, end)
Pass an existing aiohttp.ClientSession to reuse a shared connection pool — in
Home Assistant, async_get_clientsession(hass). The auth token is sent per
request, so sharing a session never leaks your credential onto it, and octopy
only closes sessions it created itself.
Notes & safety
- Read-only by design. No data is ever modified. (Token minting is the one
isolated POST, in
scripts/obtain_token.py.) - Gas units: SMETS1 reports kWh, SMETS2 reports m³ — use
octopy.m3_to_kwh/kwh_to_m3to convert. - Errors map to typed exceptions (
Unauthorized,NotFound,TooManyRequests, …), all subclasses ofoctopy.OctopyException.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file octopus_kraken-0.1.0.tar.gz.
File metadata
- Download URL: octopus_kraken-0.1.0.tar.gz
- Upload date:
- Size: 26.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60851b44eb1a326c8c287d50f57825c5f2096d1e135fa0cc3cc1cc0c32fae911
|
|
| MD5 |
8dbdb8a8efcf50687d4a93fcc454843c
|
|
| BLAKE2b-256 |
c126011506ef56c1398f48bedf7ca48e6234dd591be0b08238ab1d8b711e3930
|
Provenance
The following attestation bundles were made for octopus_kraken-0.1.0.tar.gz:
Publisher:
publish.yml on mariolonghi/octopusenergy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
octopus_kraken-0.1.0.tar.gz -
Subject digest:
60851b44eb1a326c8c287d50f57825c5f2096d1e135fa0cc3cc1cc0c32fae911 - Sigstore transparency entry: 1900357991
- Sigstore integration time:
-
Permalink:
mariolonghi/octopusenergy@c68d9e9b17715bec158e86acb9842b0dc90fb3cd -
Branch / Tag:
- Owner: https://github.com/mariolonghi
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c68d9e9b17715bec158e86acb9842b0dc90fb3cd -
Trigger Event:
release
-
Statement type:
File details
Details for the file octopus_kraken-0.1.0-py3-none-any.whl.
File metadata
- Download URL: octopus_kraken-0.1.0-py3-none-any.whl
- Upload date:
- Size: 26.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d2c69f723a3f95609649d5abfc1f733cb971a940fe6dcd180b89c388a928f0dc
|
|
| MD5 |
13825b9d9b315ed376e23460f194fafa
|
|
| BLAKE2b-256 |
0dc4d53c0b63f298e43a0e143e56e6ee8301eed8f610313ef157ed365d44d67c
|
Provenance
The following attestation bundles were made for octopus_kraken-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on mariolonghi/octopusenergy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
octopus_kraken-0.1.0-py3-none-any.whl -
Subject digest:
d2c69f723a3f95609649d5abfc1f733cb971a940fe6dcd180b89c388a928f0dc - Sigstore transparency entry: 1900358172
- Sigstore integration time:
-
Permalink:
mariolonghi/octopusenergy@c68d9e9b17715bec158e86acb9842b0dc90fb3cd -
Branch / Tag:
- Owner: https://github.com/mariolonghi
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c68d9e9b17715bec158e86acb9842b0dc90fb3cd -
Trigger Event:
release
-
Statement type: