Lightweight Flowerhub portal client (synchronous and async)
Project description
Flowerhub Portal Python Client
A lightweight, Python client for the Flowerhub portal API with cookie-based JWT authentication.
Related Projects:
- Home Assistant Custom Integration (known consumer)
Features
- Authentication: Cookie-based JWT with automatic token refresh and
AuthenticationErroron login failure - Async/await: Full async support via
aiohttpwith configurable timeouts and retries - API coverage: 12+ endpoints including assets, consumption, invoices, uptime metrics, revenue, and profiles
- Type-safe: Fully typed with
TypedDictresult types extendingStandardResultbase class - Designed for Home Assistant integrations and similar use cases with robust error handling
Installation
From PyPI
pip install flowerhub-portal-api-client
From Source
git clone https://github.com/MichaelPihlblad/flowerhub-portal-api_python-lib.git
cd flowerhub-portal-api_python-lib
pip install -e ".[async]"
Quick Start
import asyncio
from flowerhub_portal_api_client import AsyncFlowerhubClient
async def main():
async with aiohttp.ClientSession() as session:
client = AsyncFlowerhubClient(session=session)
# Login
result = await client.async_login("user@example.com", "password")
# Fetch asset information
await client.async_readout_sequence()
# Access asset status
if client.flowerhub_status:
print(f"Status: {client.flowerhub_status.status}")
print(f"Message: {client.flowerhub_status.message}")
asyncio.run(main())
Documentation
- Online: Library documentation — hosted on GitHub Pages, auto-published on push to
main. - Local preview:
pip install -r dev-requirements.txt
mkdocs serve
To build the static site locally:
mkdocs build --strict
Configuration
Credentials
⚠️ Security Warning: Never commit real credentials to the repository. The file examples/secrets.json is in .gitignore — use it as a template for local development only. Always use environment variables or secure credential managers in production. The pre-commit hook detect-private-key will block commits containing suspected private keys.
Development Setup
For contributors and local development:
# Clone and setup environment
git clone https://github.com/MichaelPihlblad/flowerhub-portal-api_python-lib.git
cd flowerhub-portal-api_python-lib
python -m venv .venv
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txt
pip install -r dev-requirements.txt
- `result_queue` (an `asyncio.Queue`) will receive `FlowerHubStatus` objects via non-blocking `put_nowait`.
- `interval_seconds` must be >= 5 (default 60).
Usage Guide
- Per-call options: All public fetch methods accept
raise_on_error(defaultTrue),retry_5xx_attempts(controls 5xx/429 retries;Noneor0disables), andtimeout_total(per-callaiohttp.ClientTimeoutoverride; default is 10s,0/Nonedisables timeout). - Error handling:
AuthenticationErroris raised after a failed refresh retry on401;ApiErroris raised for other HTTP errors or validation issues whenraise_on_error=True. Useon_auth_failedandon_api_errorcallbacks for integration-specific handling. - Lifecycle: Prefer
async with AsyncFlowerhubClient(...)or callclose()to stop background tasks. The client does not close an injected session. - Concurrency / rate limiting: Call
set_max_concurrency(n)to limit in-flight requests with a semaphore; pass0/Noneto disable. - Retry/backoff: 5xx and 429 responses are retried with a small jitter; 429 honors
Retry-Afterwhen provided.
Public Methods (async)
Authentication:
async_login(username, password)- Authenticate and establish session
Core Data Fetching:
async_fetch_asset_id()- Discover asset ID for the authenticated userasync_fetch_asset()- Fetch asset details and FlowerHub statusasync_readout_sequence()- Convenient readout of: asset ID → asset info → uptime pie
Financial Data:
async_fetch_invoices()- Fetch billing invoicesasync_fetch_consumption()- Fetch consumption recordsasync_fetch_revenue()- Fetch revenue/compensation data
Uptime Metrics:
async_fetch_uptime_pie(period=None)- Uptime distribution with automatic ratio calculationasync_fetch_uptime_history()- Monthly uptime percentagesasync_fetch_available_uptime_months()- Available month options for uptime queries
User & System:
async_fetch_asset_owner_profile()- Fetch owner profile with contact infoasync_fetch_asset_owner()- Fetch complete owner details (installer/distributor)async_fetch_electricity_agreement()- Fetch consumption/production agreement statesasync_fetch_system_notification()- System-level notifications (Flower/Zavann status)
Lifecycle & Monitoring:
start_periodic_asset_fetch(interval_seconds, ...)- Start background pollingstop_periodic_asset_fetch()- Stop background pollingis_asset_fetch_running()- Check polling status
Data Models and Types
Exceptions:
AuthenticationError- Raised on 401 authentication failures after refresh retryApiError- Raised for HTTP errors or validation issues (includesstatus_code,url,payload)
Result Types (all extend StandardResult):
- Base:
StandardResult- Common envelope withstatus_code,json,text,error - Asset:
AssetIdResult,AssetFetchResult - Financial:
InvoicesResult,ConsumptionResult,RevenueResult - Uptime:
UptimeAvailableMonthsResult,UptimeHistoryResult,UptimePieResult - User:
ProfileResult,AssetOwnerDetailsResult - Other:
AgreementResult,SystemNotificationResult(alias to StandardResult)
Data Classes:
- Status:
FlowerHubStatus(device status with age tracking) - Financial:
Invoice,InvoiceLine,ConsumptionRecord,Revenue - Uptime:
UptimeMonth,UptimeHistoryEntry - User:
AssetOwnerProfile,AssetOwnerDetails,SimpleInstaller,SimpleDistributor - Other:
ElectricityAgreement,AgreementState,Asset,Inverter,Battery
See types.py for complete type definitions.
Options, Callbacks, and Lifecycle
- Callbacks:
on_auth_failed(refresh failed + second 401),on_api_error(before raising ApiError whenraise_on_error=True). - Concurrency:
set_max_concurrency(n)adds a semaphore-based rate limiter;0/Nonedisables. - Context manager:
async with AsyncFlowerhubClient(...)orclose()to stop periodic tasks; injected sessions are not closed by the client.
Modules
exceptions.py:AuthenticationError,ApiError(includesstatus_code,url,payload).types.py: dataclasses and TypedDicts used by the client (FlowerHubStatus,ElectricityAgreement,Invoice,ConsumptionRecord,AssetIdResult,AssetFetchResult, etc.).parsers.py: pure helpers to parse/validate API payloads (used by the client but can be imported directly for advanced/standalone parsing).
Authentication Error Handling
The client automatically handles token refresh on 401 Unauthorized responses. If the refresh fails and the request still returns 401, an AuthenticationError is raised, indicating that the user needs to login again.
Exception-Based Handling
from flowerhub_portal_api_client import AsyncFlowerhubClient, AuthenticationError
try:
await client.async_fetch_asset_id()
except AuthenticationError:
# Token refresh failed, re-authentication required
await client.async_login(username, password)
await client.async_fetch_asset_id()
Callback-Based Handling
For Home Assistant integrations or event-driven architectures:
def on_auth_failed():
"""Called when authentication fails and re-login is needed."""
print("Re-authentication required")
# Trigger reauth flow, set flag, etc.
client = AsyncFlowerhubClient(
session=session,
on_auth_failed=on_auth_failed
)
See examples/auth_error_handling.py for complete examples including Home Assistant patterns.
Project details
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 flowerhub_portal_api_client-1.0.1.tar.gz.
File metadata
- Download URL: flowerhub_portal_api_client-1.0.1.tar.gz
- Upload date:
- Size: 34.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b29655e330e74dab6ef2c82ef4dcc3c7f83ba52ad310e29f91b67bfe252c5813
|
|
| MD5 |
8254853bc05f29acf1924e9361b796a4
|
|
| BLAKE2b-256 |
2e4b77544a79de43e90caefd602de515f0a78aa32bf4ea40bfa330887c7e5ddd
|
Provenance
The following attestation bundles were made for flowerhub_portal_api_client-1.0.1.tar.gz:
Publisher:
release.yml on MichaelPihlblad/flowerhub-portal-api_python-lib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
flowerhub_portal_api_client-1.0.1.tar.gz -
Subject digest:
b29655e330e74dab6ef2c82ef4dcc3c7f83ba52ad310e29f91b67bfe252c5813 - Sigstore transparency entry: 2187831888
- Sigstore integration time:
-
Permalink:
MichaelPihlblad/flowerhub-portal-api_python-lib@200d30f6cd4430afd6181593b1eeeee53a5e0b79 -
Branch / Tag:
refs/tags/1.0.1 - Owner: https://github.com/MichaelPihlblad
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@200d30f6cd4430afd6181593b1eeeee53a5e0b79 -
Trigger Event:
release
-
Statement type:
File details
Details for the file flowerhub_portal_api_client-1.0.1-py3-none-any.whl.
File metadata
- Download URL: flowerhub_portal_api_client-1.0.1-py3-none-any.whl
- Upload date:
- Size: 24.9 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 |
c6e43892f9dbb913fe18677ca0d34cbf2b071073d70851eaf2a7349596042d3a
|
|
| MD5 |
3960a41e6196c83394939d26ad8e536e
|
|
| BLAKE2b-256 |
cb54433c94fa7c9d83d32c40e88267a0ce629d8b16ba3ce3e06e953f555aa352
|
Provenance
The following attestation bundles were made for flowerhub_portal_api_client-1.0.1-py3-none-any.whl:
Publisher:
release.yml on MichaelPihlblad/flowerhub-portal-api_python-lib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
flowerhub_portal_api_client-1.0.1-py3-none-any.whl -
Subject digest:
c6e43892f9dbb913fe18677ca0d34cbf2b071073d70851eaf2a7349596042d3a - Sigstore transparency entry: 2187831894
- Sigstore integration time:
-
Permalink:
MichaelPihlblad/flowerhub-portal-api_python-lib@200d30f6cd4430afd6181593b1eeeee53a5e0b79 -
Branch / Tag:
refs/tags/1.0.1 - Owner: https://github.com/MichaelPihlblad
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@200d30f6cd4430afd6181593b1eeeee53a5e0b79 -
Trigger Event:
release
-
Statement type: