Skip to main content

Lightweight Flowerhub portal client (synchronous and async)

Project description

Flowerhub Portal Python Client

CI Code Coverage Python 3.10+ License

A lightweight, Python client for the Flowerhub portal API with cookie-based JWT authentication.

Related Projects:

Features

  • Authentication: Cookie-based JWT with automatic token refresh and AuthenticationError on login failure
  • Async/await: Full async support via aiohttp with configurable timeouts and retries
  • API coverage: 12+ endpoints including assets, consumption, invoices, uptime metrics, revenue, and profiles
  • Type-safe: Fully typed with TypedDict result types extending StandardResult base 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 (default True), retry_5xx_attempts (controls 5xx/429 retries; None or 0 disables), and timeout_total (per-call aiohttp.ClientTimeout override; default is 10s, 0/None disables timeout).
  • Error handling: AuthenticationError is raised after a failed refresh retry on 401; ApiError is raised for other HTTP errors or validation issues when raise_on_error=True. Use on_auth_failed and on_api_error callbacks for integration-specific handling.
  • Lifecycle: Prefer async with AsyncFlowerhubClient(...) or call close() 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; pass 0/None to disable.
  • Retry/backoff: 5xx and 429 responses are retried with a small jitter; 429 honors Retry-After when 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 user
  • async_fetch_asset() - Fetch asset details and FlowerHub status
  • async_readout_sequence() - Convenient readout of: asset ID → asset info → uptime pie

Financial Data:

  • async_fetch_invoices() - Fetch billing invoices
  • async_fetch_consumption() - Fetch consumption records
  • async_fetch_revenue() - Fetch revenue/compensation data

Uptime Metrics:

  • async_fetch_uptime_pie(period=None) - Uptime distribution with automatic ratio calculation
  • async_fetch_uptime_history() - Monthly uptime percentages
  • async_fetch_available_uptime_months() - Available month options for uptime queries

User & System:

  • async_fetch_asset_owner_profile() - Fetch owner profile with contact info
  • async_fetch_asset_owner() - Fetch complete owner details (installer/distributor)
  • async_fetch_electricity_agreement() - Fetch consumption/production agreement states
  • async_fetch_system_notification() - System-level notifications (Flower/Zavann status)

Lifecycle & Monitoring:

  • start_periodic_asset_fetch(interval_seconds, ...) - Start background polling
  • stop_periodic_asset_fetch() - Stop background polling
  • is_asset_fetch_running() - Check polling status

Data Models and Types

Exceptions:

  • AuthenticationError - Raised on 401 authentication failures after refresh retry
  • ApiError - Raised for HTTP errors or validation issues (includes status_code, url, payload)

Result Types (all extend StandardResult):

  • Base: StandardResult - Common envelope with status_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 when raise_on_error=True).
  • Concurrency: set_max_concurrency(n) adds a semaphore-based rate limiter; 0/None disables.
  • Context manager: async with AsyncFlowerhubClient(...) or close() to stop periodic tasks; injected sessions are not closed by the client.

Modules

  • exceptions.py: AuthenticationError, ApiError (includes status_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

flowerhub_portal_api_client-1.0.0.tar.gz (34.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flowerhub_portal_api_client-1.0.0-py3-none-any.whl (24.9 kB view details)

Uploaded Python 3

File details

Details for the file flowerhub_portal_api_client-1.0.0.tar.gz.

File metadata

File hashes

Hashes for flowerhub_portal_api_client-1.0.0.tar.gz
Algorithm Hash digest
SHA256 36554545c131d0a4597cd44bfb24b415197a1fc2c2309103a1574839854c5073
MD5 e6b7eabdcb2ed24577d7afa4c6cffaf7
BLAKE2b-256 765c4d180b55cc655cc207476dd0891993491465935d659776d659c5394ef1a1

See more details on using hashes here.

Provenance

The following attestation bundles were made for flowerhub_portal_api_client-1.0.0.tar.gz:

Publisher: release.yml on MichaelPihlblad/flowerhub-portal-api_python-lib

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file flowerhub_portal_api_client-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for flowerhub_portal_api_client-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bc8b021a5d4f95c34523bde1d710f927cb1e14a69d7eb412b9c197f68171c3fb
MD5 4627f73982ca8c00b7c65293a510c461
BLAKE2b-256 d734ae64767b72b59f6fc1431391dfb9702d1c149e4c1596910d10aa73b22f8e

See more details on using hashes here.

Provenance

The following attestation bundles were made for flowerhub_portal_api_client-1.0.0-py3-none-any.whl:

Publisher: release.yml on MichaelPihlblad/flowerhub-portal-api_python-lib

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page