Python wrapper for the Fluvius Energy API
Project description
Fluvius Energy API
Python wrapper for the Fluvius Energy API v3 (ESCO - Energy Service Company API).
Installation
pip install fluvius-energy-api
Or with uv:
uv add fluvius-energy-api
Configuration
The client requires OAuth2 credentials for Azure AD authentication. Two authentication methods are supported:
- Certificate-based (production): Uses certificate thumbprint + private key
- Client secret (sandbox): Uses a simple client secret
Common Environment Variables
These are shared between production and sandbox:
| Variable | Description |
|---|---|
FLUVIUS_SUBSCRIPTION_KEY |
Azure API Management subscription key |
FLUVIUS_CLIENT_ID |
Azure AD application (client) ID |
FLUVIUS_TENANT_ID |
Azure AD tenant ID |
FLUVIUS_SCOPE |
OAuth2 scope (e.g., api://your-app-id/.default) |
Production (Certificate-based auth)
| Variable | Description |
|---|---|
FLUVIUS_CERTIFICATE_THUMBPRINT |
Certificate thumbprint (hex format) |
FLUVIUS_PRIVATE_KEY |
RSA private key in PEM format |
FLUVIUS_PRIVATE_KEY_PATH |
Alternative: path to private key file |
Sandbox (Client secret auth)
| Variable | Description |
|---|---|
FLUVIUS_SANDBOX_CLIENT_SECRET |
Client secret for sandbox |
Note: For sandbox, common values (subscription_key, client_id, tenant_id, scope, data_access_contract_number) automatically fall back to FLUVIUS_* if not set with FLUVIUS_SANDBOX_* prefix.
Data Access Contract
| Variable | Description |
|---|---|
FLUVIUS_DATA_ACCESS_CONTRACT_NUMBER |
Data access contract number (required, typically constant per service provider) |
Private Key Formats
The private key can be provided in three ways:
- Inline PEM: Set
FLUVIUS_PRIVATE_KEYwith the full PEM content - Base64-encoded: Set
FLUVIUS_PRIVATE_KEYwith the PEM content encoded as base64 - File path: Set
FLUVIUS_PRIVATE_KEY_PATHto point to a.pemfile
Usage
Production (Certificate auth)
from fluvius_energy_api import FluviusEnergyClient, Environment
# Credentials loaded from FLUVIUS_* environment variables
with FluviusEnergyClient(environment=Environment.PRODUCTION) as client:
response = client.get_mandates()
for mandate in response.data.mandates:
print(f"EAN: {mandate.ean}, Status: {mandate.status}")
Sandbox (Client secret auth)
from fluvius_energy_api import FluviusEnergyClient, FluviusCredentials, Environment
# Load credentials - falls back to FLUVIUS_* for common values,
# uses FLUVIUS_SANDBOX_CLIENT_SECRET for auth
sandbox_credentials = FluviusCredentials.from_env(prefix="FLUVIUS_SANDBOX")
with FluviusEnergyClient(credentials=sandbox_credentials, environment=Environment.SANDBOX) as client:
response = client.get_mandates()
print(f"Found {len(response.data.mandates)} mandates in sandbox")
Explicit Credentials
from fluvius_energy_api import FluviusEnergyClient, FluviusCredentials, Environment
# Production with certificate
prod_credentials = FluviusCredentials(
subscription_key="your-subscription-key",
client_id="your-client-id",
tenant_id="your-tenant-id",
scope="api://your-scope/.default",
certificate_thumbprint="YOUR_CERTIFICATE_THUMBPRINT",
private_key="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----",
)
# Sandbox with client secret
sandbox_credentials = FluviusCredentials(
subscription_key="your-subscription-key",
client_id="your-client-id",
tenant_id="your-tenant-id",
scope="api://your-scope/.default",
client_secret="your-client-secret",
)
with FluviusEnergyClient(credentials=prod_credentials, environment=Environment.PRODUCTION) as client:
mandates = client.get_mandates()
Create Client Session
Create a session for end-users to grant data access:
from fluvius_energy_api import (
FluviusEnergyClient,
ClientSessionDataService,
DataServiceType,
Environment,
)
with FluviusEnergyClient(environment=Environment.PRODUCTION) as client:
response = client.create_client_session(
data_access_contract_number="3599900040",
reference_number="my-unique-reference",
flow="B2B",
data_services=[
ClientSessionDataService(
data_service_type=DataServiceType.VH_DAG,
data_period_from="2024-01-01T00:00:00Z",
),
ClientSessionDataService(
data_service_type=DataServiceType.VH_KWARTIER_UUR,
data_period_from="2024-01-01T00:00:00Z",
),
],
number_of_eans=5,
)
if response.data.status == "success":
# Build the consent URL for end-users
consent_url = f"https://mijn.fluvius.be/verbruik/dienstverlener?id={response.data.short_url_identifier}"
print(f"Consent URL: {consent_url}")
print(f"Valid until: {response.data.valid_to}")
Get Mandates
Retrieve mandates with optional filters:
from fluvius_energy_api import (
FluviusEnergyClient,
EnergyType,
MandateStatus,
DataServiceType,
Environment,
)
with FluviusEnergyClient(environment=Environment.PRODUCTION) as client:
# Get all mandates
response = client.get_mandates()
# Get mandates with filters
response = client.get_mandates(
ean="541448800000004312",
energy_type=EnergyType.ELECTRICITY,
status=MandateStatus.APPROVED,
data_service_types=[DataServiceType.VH_DAG, DataServiceType.VH_KWARTIER_UUR],
)
for mandate in response.data.mandates:
print(f"EAN: {mandate.ean}")
print(f"Status: {mandate.status}")
print(f"Energy type: {mandate.energy_type}")
print(f"Data service: {mandate.data_service_type}")
Get Energy Data
Retrieve energy consumption/production data:
from datetime import datetime
from fluvius_energy_api import FluviusEnergyClient, PeriodType, Environment
with FluviusEnergyClient(environment=Environment.PRODUCTION) as client:
response = client.get_energy(
ean="541448800000004312",
period_type=PeriodType.READ_TIME,
granularity="daily",
from_date=datetime(2024, 1, 1),
to_date=datetime(2024, 6, 1),
)
headpoint = response.data.headpoint
print(f"EAN: {headpoint.ean}")
print(f"Energy type: {headpoint.energy_type}")
Postman Collection
A hand-crafted Postman collection is included in the postman/ directory covering authentication, client sessions, mandates, and energy data endpoints.
To generate the environment files from your .env:
python postman/generate_postman_env.py
This creates two files (gitignored):
postman/fluvius-sandbox.postman_environment.json-- client-secret authpostman/fluvius-production.postman_environment.json-- certificate / JWT auth
Import the collection (postman/fluvius-energy-api.postman_collection.json) and the appropriate environment into Postman. The collection's pre-request script acquires tokens automatically.
The production client assertion is valid for 1 hour. Re-run the script for a fresh one -- the JWT is printed to stdout so you can copy-paste it directly into your already-imported Postman environment without re-importing the file.
Environments
The client supports two environments:
| Environment | Base URL | Auth Method |
|---|---|---|
Environment.PRODUCTION |
https://apihub.fluvius.be/esco-live/v3 |
Certificate |
Environment.SANDBOX |
https://apihub.fluvius.be/esco-sbx/v3 |
Client secret |
from fluvius_energy_api import FluviusEnergyClient, Environment
# Production
client = FluviusEnergyClient(environment=Environment.PRODUCTION)
# Sandbox
client = FluviusEnergyClient(environment=Environment.SANDBOX)
Error Handling
The client raises specific exceptions for different error scenarios:
from fluvius_energy_api import (
FluviusEnergyClient,
FluviusAPIError,
AuthenticationError,
ForbiddenError,
NotFoundError,
ValidationError,
ServerError,
ServiceUnavailableError,
ConfigurationError,
Environment,
)
try:
with FluviusEnergyClient(environment=Environment.PRODUCTION) as client:
response = client.get_mandates()
except ConfigurationError as e:
print(f"Configuration error: {e}")
except AuthenticationError as e:
print(f"Authentication failed: {e}")
except ForbiddenError as e:
print(f"Access forbidden: {e}")
except NotFoundError as e:
print(f"Resource not found: {e}")
except ValidationError as e:
print(f"Validation error: {e}")
if e.validation_errors:
for error in e.validation_errors:
print(f" - {error}")
except ServerError as e:
print(f"Server error: {e}")
except ServiceUnavailableError as e:
print(f"Service unavailable: {e}")
except FluviusAPIError as e:
print(f"API error: {e}")
Data Service Types
Available data service types:
| Type | Description |
|---|---|
VH_DAG |
Daily consumption history |
VH_KWARTIER_UUR |
Quarter-hourly/hourly consumption history |
VH_ONBEPAALD |
Indefinite consumption history |
IG |
Installation data |
License
GNU AFFERO GENERAL PUBLIC LICENSE
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 fluvius_energy_api-0.2.2.tar.gz.
File metadata
- Download URL: fluvius_energy_api-0.2.2.tar.gz
- Upload date:
- Size: 96.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
96583a4010b77f53589479cad5f916b9edeb44d9abc0c8af6a4a97f834865608
|
|
| MD5 |
b441cdda6ae41b03be3b3bb282f761bf
|
|
| BLAKE2b-256 |
df718d1db5de85dc73ad6e6c5fb3b051ed8c0041e4ff61baf662c2fe032f9736
|
Provenance
The following attestation bundles were made for fluvius_energy_api-0.2.2.tar.gz:
Publisher:
publish.yml on warreee/fluvius-energy-api
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fluvius_energy_api-0.2.2.tar.gz -
Subject digest:
96583a4010b77f53589479cad5f916b9edeb44d9abc0c8af6a4a97f834865608 - Sigstore transparency entry: 938225311
- Sigstore integration time:
-
Permalink:
warreee/fluvius-energy-api@db20960ed650f597de0302dc0b06dfb678a097b3 -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/warreee
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@db20960ed650f597de0302dc0b06dfb678a097b3 -
Trigger Event:
release
-
Statement type:
File details
Details for the file fluvius_energy_api-0.2.2-py3-none-any.whl.
File metadata
- Download URL: fluvius_energy_api-0.2.2-py3-none-any.whl
- Upload date:
- Size: 34.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ef3a901a9e4a99bed217bff7b8a4aa853b6cfc66ed398d097232067979ba6e4
|
|
| MD5 |
49a43f9a13296f79d65a19e81617fbc0
|
|
| BLAKE2b-256 |
d5741eb73c00f8ef4cb0b26dac2dca4afe168da70139d6ab1a26006e91643717
|
Provenance
The following attestation bundles were made for fluvius_energy_api-0.2.2-py3-none-any.whl:
Publisher:
publish.yml on warreee/fluvius-energy-api
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fluvius_energy_api-0.2.2-py3-none-any.whl -
Subject digest:
9ef3a901a9e4a99bed217bff7b8a4aa853b6cfc66ed398d097232067979ba6e4 - Sigstore transparency entry: 938225320
- Sigstore integration time:
-
Permalink:
warreee/fluvius-energy-api@db20960ed650f597de0302dc0b06dfb678a097b3 -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/warreee
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@db20960ed650f597de0302dc0b06dfb678a097b3 -
Trigger Event:
release
-
Statement type: