Skip to main content

pylondonair

Async Python client for the London Air hourly air-quality monitoring index, published by Imperial College London.

pylondonair fetches the hourly monitoring index for the Greater London monitoring network and parses it into clean, typed, immutable data models. It is the data layer behind the Home Assistant London Air integration, but it is a standalone library with no Home Assistant dependency and can be used from any async Python project.

  • Async-first — built on aiohttp; the only runtime dependency (plus tzdata on Windows).
  • Typed — mypy --strict clean, ships a py.typed marker, full type hints.
  • Immutable models — frozen dataclasses; safe to share across tasks.
  • No auth, no config — the public feed requires no credentials.

Installation

pip install pylondonair

Requires Python 3.12 or newer.

Quickstart

import asyncio

from pylondonair import LondonAirClient


async def main() -> None:
    async with LondonAirClient() as client:
        data = await client.async_update()

    print(data.group_name)          # "London"
    print(data.time_to_live)        # minutes until the feed is expected to refresh
    for authority in data.authorities.values():
        print(authority.name, authority.status)
        for site in authority.sites:
            print("  ", site.site_name, site.status, site.updated)
            for pollutant in site.pollutants:
                print("    ", pollutant.summary)  # e.g. "PM10 is Low"


asyncio.run(main())

Reusing an existing session

If you already manage an aiohttp.ClientSession (for example, Home Assistant passes its shared session), inject it. The client will not close a session it did not create:

import aiohttp
from pylondonair import LondonAirClient

async with aiohttp.ClientSession() as session:
    client = LondonAirClient(session=session)
    data = await client.async_update()
    # `session` is still open and owned by you.

Connection check

async_test_connection() performs a lightweight GET + status check without parsing the payload. It is intended for config-flow style validation:

await client.async_test_connection()  # raises LondonAirConnectionError on failure

Data model

async_update() returns a LondonAirData:

Model Description
LondonAirData Top level: group_name, time_to_live (minutes), authorities (dict keyed by authority name).
Authority A local authority: name, code, centre coordinates, sites, status.
Site A monitoring site: site_code, site_name, site_type, coordinates, updated (aware datetime), pollutants, status, number_of_pollutants.
Pollutant A single species reading: code, description, quality (band), index, summary (e.g. "PM10 is Low"), index_source.

All models are frozen dataclasses (immutable). Pollutant, Site, and Authority are also hashable; LondonAirData is not, because its authorities mapping is not hashable.

Status aggregation

  • Site.status is the most common pollutant quality band at that site. If a site has no usable species it is the sentinel string no_species_data (exported as NO_SPECIES_DATA).
  • Authority.status is the most common site status, excluding the sentinel. It is None when the authority has no sites or all sites are no_species_data.

Ties are broken by first appearance in the payload.

@TimeToLive

The feed carries a @TimeToLive attribute (minutes) indicating how long the data is expected to remain current. pylondonair parses it into LondonAirData.time_to_live. If the attribute is missing or non-numeric it defaults to 60 and a warning is logged.

WGS84 fields (footgun)

The API exposes @...WGS84 coordinate fields. Despite the name, these are projected metres (a projected coordinate system), not decimal degrees. pylondonair includes them verbatim under the API-faithful names (latitude_wgs84, longitude_wgs84, centre_latitude_wgs84, centre_longitude_wgs84) as str | None. Do not treat them as lat/long degrees; use the plain latitude/longitude fields (decimal degrees) for geographic purposes.

Error handling

pylondonair raises a small, dedicated hierarchy rooted at LondonAirError:

Exception Raised when
LondonAirConnectionError Network failure, timeout, or a non-2xx HTTP response.
LondonAirUpdateError The payload is malformed or structurally invalid (bad JSON, missing sections, unparseable dates).
from pylondonair import (
    LondonAirClient,
    LondonAirConnectionError,
    LondonAirUpdateError,
)

try:
    data = await client.async_update()
except LondonAirConnectionError:
    ...  # transient; retry later
except LondonAirUpdateError:
    ...  # unexpected payload shape; inspect and report

Attribution

Air quality data is provided by London Air and Imperial College London. The API is documented at https://www.imperial.ac.uk/londonair/api/.

License

MIT.

Metadata

Release files for pylondonair 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pylondonair 0.1.0
File Size Uploaded Provenance
pylondonair-0.1.0.tar.gz 17.1 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pylondonair 0.1.0
File Interpreter ABI Platform
pylondonair-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 30.4 kB

Release files / pylondonair-0.1.0.tar.gz

Download URL pylondonair-0.1.0.tar.gz
Size 17.1 kB
Tags Source
SHA-256 checksum
How to use checksums
e921b03a6b65755612ee9e206de36928b6eed0067770dc7c62557cbbc4cd0eb9
BLAKE2b-256 checksum
How to use checksums
5ae50c0814f843ab6787208718ebce450a062ca4215c92f5aa9236c70660276d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / pylondonair-0.1.0-py3-none-any.whl

Download URL pylondonair-0.1.0-py3-none-any.whl
Size 13.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8da2884c571f2633e407dc9c7c97b038264ffd7d865ab0b0b7c16ae0d769378c
BLAKE2b-256 checksum
How to use checksums
cf2e9d0a9aa0b8f13c2b8f491408a75960902959db9e8d9e005cd2474b18feca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Security for pylondonair 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pylondonair-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page