Skip to main content

Async Python client for National Grid built on aiohttp

Project description

py-nationalgrid

PyPI

Async Python client for National Grid's GraphQL and REST APIs.

Installation

pip install py-nationalgrid

Quick Start

import asyncio
from py_nationalgrid import NationalGridClient, NationalGridConfig

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

    async with NationalGridClient(config=config) as client:
        accounts = await client.get_linked_accounts()
        for account in accounts:
            print(account["billingAccountId"])

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

API Methods

Method Returns Description
get_linked_accounts() list[AccountLink] Get linked billing account IDs
get_billing_account() BillingAccount Get account details (region, meters, address)
get_energy_usage_costs() list[EnergyUsageCost] Get energy costs for a billing period
get_energy_usages() list[EnergyUsage] Get historical usage data
get_ami_energy_usages_15min() list[AmiEnergyUsage] Primary AMI method. 15-minute interval data for ELECTRIC & GAS. Auto-chunks large ranges, falls back to daily on API errors, and handles the ~45-day hot storage limit gracefully. See below.
get_ami_energy_usages() list[AmiEnergyUsage] AMI daily energy usage. Used as the fallback inside get_ami_energy_usages_15min(); call directly only if you want to bypass the 15-minute endpoint entirely.
get_interval_reads() list[IntervalRead] Real-time meter interval reads. Returns [] for meters with no interval data (e.g. GAS).

All methods return typed results using TypedDict models.

AMI 15-Minute Energy Usage

get_ami_energy_usages_15min() is the primary method for fetching AMI interval data and handles several National Grid API quirks automatically.

Chunking

The National Grid API imposes a hard limit of approximately 10,000 records per response, and the Azure Application Gateway enforces a backend timeout that cuts off requests spanning more than roughly 45 days of data regardless of record count.

To work around this, the method automatically splits any date range that exceeds 45 days into 45-day chunks and concatenates the results. Both ELECTRIC and GAS meters use 45-day chunks:

  • ELECTRIC: 96 records/day × 45 days = 4,320 records per chunk (well inside the 10k cap)
  • GAS: 24 records/day × 45 days = 1,080 records per chunk

Chunks are requested newest-first to ensure the most recent data is always fetched successfully before older chunks are attempted.

Hot Storage Window (~45 days)

National Grid's API only serves data from "hot" (immediately accessible) storage for approximately the last 45 days from today. Data older than that sits in cold/archive storage. Any query that touches cold storage — even a single-day range — will trigger a 504 Gateway Timeout from the Azure Application Gateway.

This is a server-side constraint. There is no client-side configuration that can change it.

Because chunks are fetched newest-first, a 504 on an older chunk does not discard the recent data already collected. The method logs a warning and returns whatever records were successfully retrieved:

WARNING amiEnergyUsages15Min: 504 on chunk 2/4 (2025-01-01 to 2025-02-14) —
data is likely beyond the ~45-day accessible window. Returning 135 record(s)
collected so far.

Callers should not assume the returned list covers the full requested date range. If you request 180 days, you will receive roughly the last 45 days of records without an exception being raised.

Fallback to Daily Endpoint

Some meters do not support the 15-minute (amiEnergyUsages15Min) GraphQL operation and return a GraphQL error response instead of data. When this happens on the first chunk, the method transparently falls back to a single full-range request against the standard daily endpoint (amiEnergyUsages). The fallback is automatic and invisible to the caller.

Example

from datetime import date, timedelta

date_to   = date.today()
date_from = date_to - timedelta(days=60)   # spans more than 45 days → auto-chunked

usages = await client.get_ami_energy_usages_15min(
    meter_number=meter["meterNumber"],
    premise_number=billing_account["premiseNumber"],
    service_point_number=meter["servicePointNumber"],
    meter_point_number=meter["meterPointNumber"],
    date_from=date_from,
    date_to=date_to,
    fuel_type=meter.get("fuelType"),   # "ELECTRIC" or "GAS"; controls chunk size
)
# usages covers only the accessible ~45-day window even though 60 days were requested

Examples

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
uv run python examples/ami-usage.py      --username user@example.com --password secret
uv run python examples/ami-usage.py      --username user@example.com --password secret --fuel-type ELECTRIC
uv run python examples/ami-usage.py      --username user@example.com --password secret --fuel-type GAS --days 30

Development

Requires Python 3.10+ and uv.

uv sync                # install dependencies
uv run pytest          # run tests
uv run ruff check .    # lint
uv run ruff format .   # format
uv run mypy src        # type-check

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

py_nationalgrid-0.5.0.tar.gz (41.2 kB view details)

Uploaded Source

Built Distribution

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

py_nationalgrid-0.5.0-py3-none-any.whl (34.5 kB view details)

Uploaded Python 3

File details

Details for the file py_nationalgrid-0.5.0.tar.gz.

File metadata

  • Download URL: py_nationalgrid-0.5.0.tar.gz
  • Upload date:
  • Size: 41.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for py_nationalgrid-0.5.0.tar.gz
Algorithm Hash digest
SHA256 ecda067eee8ff2b49129ade7d380050be655db0aa0a0abfcf49b243d294c60ed
MD5 c840cfb27d9a62cd46fc045fa2e45545
BLAKE2b-256 be0d14cd4477c1464ab69b0350e037f6ca70066ea02f04f2901fa6886703f303

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_nationalgrid-0.5.0.tar.gz:

Publisher: release.yml on virtitnerd/py-nationalgrid

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

File details

Details for the file py_nationalgrid-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: py_nationalgrid-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 34.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for py_nationalgrid-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 832de33de884741895f85dc038a6fd5747ab75c11e10b388cad9b58aa4aaa3e9
MD5 b2111c4390be02974b7d4b05739c2b38
BLAKE2b-256 d57dd567a055096a03a8316942244bcd73f4706b1c6c1edf64b12b84cf21f714

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_nationalgrid-0.5.0-py3-none-any.whl:

Publisher: release.yml on virtitnerd/py-nationalgrid

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