Skip to main content

pyeonenergia

Async client for the E.ON Energia (Italy) customer API.

E.ON publish no public API. This talks to the same endpoints their own app and web client use, with credentials you supply, to read your own consumption and billing data. It is the protocol layer behind the E.ON Energia Home Assistant integration, split out so it can be used, tested and released on its own.

from pyeonenergia import EonEnergiaAuth, EonEnergiaClient, build_authorization_url

# Sign in. E.ON's Auth0 client forbids password grants, so the only way in is the
# browser flow: open this URL, log in, and pull the code out of the callback.
print(await build_authorization_url())
tokens = await EonEnergiaAuth.exchange_code_for_tokens(code)

client = EonEnergiaClient(tokens["access_token"], tokens["refresh_token"])
for pod in await client.get_points_of_delivery():
    print(pod.pod_id, pod.address, pod.is_active)

Install with pip install pyeonenergia. Python 3.12 or newer.

What it gives you

EonEnergiaClient handles tokens on its own: it reads the expiry out of the access token and refreshes shortly before it lapses, so you hand it a token pair once and stop thinking about it. Pass token_callback to be told when they rotate, and persist what you are given — Auth0 rotates the refresh token on every use, so the old one stops working immediately.

Method Returns
get_accounts() list[Account]
get_points_of_delivery() list[PointOfDelivery]
get_daily_consumption(pod, start, end) list[HourlyConsumption]
get_invoices(start, end) list[Invoice]
get_invoices_for_pod(pod, start, end) list[Invoice]
get_monthly_consumption(...) raw list[dict]
get_energy_wallet(pod, year) raw dict

Every model keeps the untouched response in .raw, so a field with no typed home is still reachable without going round the library.

Tariff bands and the calendar

pyeonenergia.tariff carries the Italian domain logic: which of the three ARERA bands an hour falls in, the national holidays including Easter Monday, and the mapping from E.ON's hourly fields onto real instants.

from pyeonenergia import fascia_for_hour, local_hour_starts

fascia_for_hour(date(2026, 9, 22), 10)      # "F1" — Tuesday 09:00, peak
len(local_hour_starts(date(2026, 10, 25)))  # 25 — the clocks go back

That last one matters. E.ON send twenty-four valore_hNN fields every day of the year, including the two days when the Italian day is not twenty-four hours long. HourlyConsumption.hours() resolves them against the real calendar, so on the short day the field with nowhere to go is dropped and on the long day the final hour is simply unreported — rather than two readings landing on the same instant, which is a silent double count.

Two things about this API

It answers HTTP 500 for a bad token, never 401. An expired token, a garbage bearer and no Authorization header at all all come back as {"statusCode": 500, "message": "Internal server error"}. A status code alone cannot tell an auth problem from a server fault, so the client treats a 500 as possibly-auth, refreshes once and retries, and only then reports it as a server error. Worth knowing before you debug anything here.

getInvoiceDvc answers 202, with the complete invoice list in the body. Anything checking for exactly 200 throws the data away.

Errors

All descend from EonEnergiaError.

EonEnergiaAuthError for a failed login, with EonEnergiaCaptchaError and EonEnergiaMfaRequiredError as the two cases worth handling separately: the first means Auth0's bot detection has decided you look automated and nothing headless will get past it, the second carries the session state to hand back with the code. EonEnergiaApiError for a rejected request, EonEnergiaConfigError when the API base URL and subscription key cannot be resolved.

Development

pip install -e ".[test]"
pytest

The API configuration is normally scraped from E.ON's public login page at runtime. That page sits behind Cloudflare and intermittently refuses non-browser clients, so there is a fallback; tools/seal_fallback.py regenerates it if the values ever change.

Licence

MIT. Not affiliated with, authorised by or endorsed by E.ON Energia S.p.A. See the integration repository for the full legal notice.

Release files for pyeonenergia 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyeonenergia 0.1.0
File Size Uploaded
pyeonenergia-0.1.0.tar.gz 33.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyeonenergia 0.1.0
File Interpreter ABI Platform
pyeonenergia-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 64.8 kB

Release files / pyeonenergia-0.1.0.tar.gz

Download URL pyeonenergia-0.1.0.tar.gz
Size 33.9 kB
Tags Source
SHA-256 checksum
How to use checksums
ed7d60f2a0b375989f6b64352b1263b0abf801c31e8280f665ffa59ed6fa4372
BLAKE2b-256 checksum
How to use checksums
d3e40720874bd6b911629492d6c2865ada91e8971c043e6273bff84376c513b0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.

Transparency log

Release files / pyeonenergia-0.1.0-py3-none-any.whl

Download URL pyeonenergia-0.1.0-py3-none-any.whl
Size 30.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a4e68b00f529ec992e1f281fd94e0768d51e7cbd8a45660172b72ccf2dc2aeee
BLAKE2b-256 checksum
How to use checksums
7656def010b72757c5d16355df5bfad4000911ed567505506975d08141ceb777
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page