Skip to main content

Async Python client for National Grid built on aiohttp

Project description

aionatgrid

Asynchronous Python client for communicating with National Grid's GraphQL and REST APIs using aiohttp. The package provides pre-built query helpers for common operations, automatic OIDC authentication, and multi-endpoint routing.

Features

  • Async NationalGridClient with context-manager support and connection reuse
  • Pre-built query helpers for linked accounts, billing info, and energy usage data
  • Automatic OIDC authentication via Azure AD B2C with token caching and refresh
  • Multi-endpoint GraphQL routing (user, billing account, energy usage endpoints)
  • REST API support with shared authentication
  • Configurable via NationalGridConfig dataclass
  • JWT token verification and automatic expiration handling

Requirements

  • Python 3.10+
  • uv for dependency management (install from Astral)

Installation

uv sync

The command creates a .venv managed by uv and installs runtime plus development dependencies declared in pyproject.toml.

Usage

Quick Start

import asyncio
from aionatgrid import NationalGridClient, NationalGridConfig

async def main() -> None:
    config = NationalGridConfig(
        username="user@example.com",
        password="your-password",
    )

    async with NationalGridClient(config=config) as client:
        # Get linked billing accounts
        response = await client.linked_billing_accounts()
        print(response.data)

if __name__ == "__main__":
    asyncio.run(main())

Available Query Methods

The client provides convenience methods for common National Grid API operations:

Method Description Endpoint
linked_billing_accounts() Get user's linked billing account IDs user-cu-uwp-gql
billing_account_info() Get account details (region, meters, address) billingaccount-cu-uwp-gql
energy_usage_costs() Get energy costs for a billing period energyusage-cu-uwp-gql
energy_usages() Get historical usage data energyusage-cu-uwp-gql
realtime_meter_info() Get real-time meter readings (REST) REST endpoint

Example: Fetching Energy Usage Data

import asyncio
from datetime import date
from aionatgrid import NationalGridClient, NationalGridConfig

async def main() -> None:
    config = NationalGridConfig(
        username="user@example.com",
        password="your-password",
    )

    async with NationalGridClient(config=config) as client:
        # Step 1: Get linked accounts
        accounts = await client.linked_billing_accounts()
        account_id = accounts.data["user"]["accountLinks"]["nodes"][0]["billingAccountId"]

        # Step 2: Get account info (for region/companyCode)
        info = await client.billing_account_info(
            variables={"accountNumber": account_id}
        )
        region = info.data["billingAccount"]["region"]

        # Step 3: Fetch energy usage costs
        costs = await client.energy_usage_costs(
            variables={
                "accountNumber": account_id,
                "date": date.today().isoformat(),
                "companyCode": region,
            }
        )
        print(costs.data)

        # Step 4: Fetch historical usage (last 12 months)
        from_month = (date.today().year - 1) * 100 + date.today().month
        usages = await client.energy_usages(
            variables={
                "accountNumber": account_id,
                "from": from_month,
                "first": 12,
            }
        )
        print(usages.data)

if __name__ == "__main__":
    asyncio.run(main())

Custom GraphQL Queries

For custom queries, use the execute() method directly:

from aionatgrid import GraphQLRequest

request = GraphQLRequest(
    query="query MyQuery { ... }",
    variables={"key": "value"},
    endpoint="https://myaccount.nationalgrid.com/api/custom-endpoint"
)
response = await client.execute(request)

REST API Access

response = await client.request_rest("GET", "/api/endpoint")
print(response.status, response.data)

Examples

Run the included example scripts:

uv run python examples/list-accounts.py --username user@example.com --password secret
uv run python examples/account-info.py --username user@example.com --password secret
uv run python examples/energy-usage.py --username user@example.com --password secret
uv run python examples/interval-reads.py --username user@example.com --password secret

Testing and Linting

uv run pytest          # run unit tests
uv run ruff check .    # lint
uv run ruff format .   # format
uv run mypy src        # type-check

All commands above also have Makefile shortcuts (see Makefile).

Project Layout

.
├── examples/
│   ├── account-info.py      # Billing account details example
│   ├── energy-usage.py      # Energy costs and usage example
│   ├── interval-reads.py    # Interval meter readings example
│   └── list-accounts.py     # Account listing example
├── src/aionatgrid/
│   ├── __init__.py          # Public exports
│   ├── auth.py              # Authentication helpers
│   ├── client.py            # NationalGridClient implementation
│   ├── config.py            # NationalGridConfig and RetryConfig
│   ├── exceptions.py        # Custom exception classes
│   ├── graphql.py           # GraphQL request/response types
│   ├── helpers.py           # Utility functions
│   ├── oidchelper.py        # OIDC authentication flow
│   ├── queries.py           # GraphQL query builders
│   ├── rest.py              # REST request/response types
│   └── rest_queries.py      # REST query builders
├── tests/
│   ├── test_client.py       # Client unit tests
│   ├── test_config.py       # Configuration tests
│   └── test_retry.py        # Retry logic tests
├── Makefile                 # Developer shortcuts
└── pyproject.toml           # Packaging metadata

Architecture

Multi-Endpoint Routing

National Grid uses separate GraphQL endpoints for different data domains. The query helpers automatically route requests to the correct endpoint:

  • user-cu-uwp-gql: User account links
  • billingaccount-cu-uwp-gql: Billing account metadata
  • energyusage-cu-uwp-gql: Energy usage and cost data

Authentication

The client handles OIDC authentication automatically:

  1. First API call triggers authentication
  2. Tokens are cached with thread-safe locking
  3. Expired tokens are refreshed automatically (5-minute buffer)
  4. JWT signatures are verified cryptographically

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

aionatgrid-0.1.0.tar.gz (34.8 kB view details)

Uploaded Source

Built Distribution

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

aionatgrid-0.1.0-py3-none-any.whl (30.2 kB view details)

Uploaded Python 3

File details

Details for the file aionatgrid-0.1.0.tar.gz.

File metadata

  • Download URL: aionatgrid-0.1.0.tar.gz
  • Upload date:
  • Size: 34.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for aionatgrid-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ab49146b7587f16a93946136652791377bc189ad9d113cc0c39f0be4eaf6031a
MD5 8dc44bff4fa5a5b6a3a4792d790a85f0
BLAKE2b-256 d94a7b2bec74c1ed95f12f9fa69d8ad357b8cb164de67597320c958c6268beeb

See more details on using hashes here.

Provenance

The following attestation bundles were made for aionatgrid-0.1.0.tar.gz:

Publisher: release.yml on RyanMorash/aionatgrid

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

File details

Details for the file aionatgrid-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: aionatgrid-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 30.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for aionatgrid-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4be77aba73adde6f3e5eeb718beeb3078bbd32f2fb41ec508fa2e90bfd1f2b98
MD5 79c6906f5c48d64ee3d3d2d27fb2931d
BLAKE2b-256 901c96340c24f2577235d0ef345206166f95315345bcb2682fd9c364b5083dd9

See more details on using hashes here.

Provenance

The following attestation bundles were made for aionatgrid-0.1.0-py3-none-any.whl:

Publisher: release.yml on RyanMorash/aionatgrid

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