Skip to main content

CLI and Python API to fetch air quality index (AQI) data from the Montreal open data portal

Project description

AQI monitoring for the city of Montréal (Québec, Canada)

Latest Release Python CI PyPI Downloads License

A Python library and CLI tool to fetch, process, and expose air quality index (AQI) data from the City of Montréal open data platform.

The project is designed to be:

  • scriptable (JSON output by default)
  • embeddable as a Python library
  • suitable for automation (Home Assistant, cron jobs, data pipelines)

Features

  • Fetches the latest air quality data from Montréal’s open data portal
  • Lists currently active air quality monitoring stations
  • Computes the AQI based on RSQA methodology
  • Estimates pollutant concentrations from reported AQI contributions¹
  • Exposes structured station and pollutant data via Python models
  • Outputs machine-readable JSON from the CLI
  • Structured logging with optional debug mode
  • Test suite covering core logic, JSON contract, and CLI behavior

¹ Estimated concentrations are derived from rounded AQI values and should be treated as approximations.


Requirements

  • Python 3.11 or newer
  • requests

Installation

From PyPI (recommended)

pip install montreal-aqi-api

From source

git clone https://github.com/normcyr/montreal-aqi-api.git
cd montreal-aqi-api
python3 -m venv venv
source venv/bin/activate
pip install .

CLI Usage

The CLI always outputs JSON on stdout. Logs and diagnostics are written to stderr.

Fetch AQI for a specific station

montreal-aqi --station <station_id>

List available monitoring stations

montreal-aqi --list

Enable debug logging

montreal-aqi --station <station_id> --debug

Print the JSON in a pretty format

montreal-aqi --station <station_id> --pretty

or

montreal-aqi --list --pretty

No arguments

If no arguments are provided, the CLI returns a JSON error payload. Interactive prompts are intentionally avoided to keep behavior predictable in automated environments.


Integrations

This library is designed to be consumed by automated systems and integrations.

Home Assistant

Used by the custom Home Assistant integration:

Other Use Cases

  • Cron jobs
  • Data ingestion pipelines
  • Monitoring dashboards
  • Research / environmental analysis

JSON Contract — Version 1 (Frozen)

As of v0.4.0, the JSON output contract is explicitly versioned and frozen. The output format is formally specified in: docs/json_contract_v1.md.

The JSON output is governed by the official JSON Schema v1 and all payloads include:

{
  "version": 1,
  "type": "..."
}

Error Payload

{
  "version": 1,
  "type": "error",
  "error": {
    "code": "NO_DATA",
    "message": "No data available for this station"
  }
}

Stations List Payload

{
  "version": 1,
  "type": "stations",
  "stations": [
    {
      "station_id": "3",
      "name": "Saint-Jean-Baptiste",
      "borough": "Rivière-des-Prairies"
    }
  ]
}

Station AQI Payload

{
  "version": 1,
  "type": "station",
  "station_id": "80",
  "date": "2025-08-08",
  "hour": 10,
  "aqi": 49,
  "dominant_pollutant": "PM2.5",
  "pollutants": {
    "PM2.5": {
      "name": "PM2.5",
      "aqi": 49,
      "concentration": 34.3
    },
    "O3": {
      "name": "O3",
      "aqi": 22,
      "concentration": 70.4
    }
  }
}

Python Usage

from montreal_aqi_api.service import get_station_aqi

station = get_station_aqi("80")
if station:
    print(station.to_dict())

Domain objects (Station, Pollutant) expose explicit serialization helpers to ease downstream usage.


AQI Methodology

AQI values follow the methodology defined by the Réseau de surveillance de la qualité de l’air (RSQA).

Reference Values

Pollutant Full Name Reference
SO₂ Sulfur Dioxide 500 µg/m³
CO Carbon Monoxide 35 mg/m³
O₃ Ozone 160 µg/m³
NO₂ Nitrogen Dioxide 400 µg/m³
PM2.5 Particulate Matter 35 µg/m³

Project Status

  • JSON contract v1 frozen and validated by tests
  • Suitable for automation and integration
  • API stability guaranteed within v1

Contributing

Contributions are welcome.

Please ensure that:

  • tests pass (pytest)
  • the JSON contract remains backward compatible
  • any change affecting output is covered by tests

Open an issue before proposing breaking changes.


Data Source

Data is retrieved from the Ville de Montréal Open Data Portal.


License

This project is licensed under the MIT License.

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

montreal_aqi_api-0.4.1.tar.gz (13.9 kB view details)

Uploaded Source

Built Distribution

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

montreal_aqi_api-0.4.1-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

File details

Details for the file montreal_aqi_api-0.4.1.tar.gz.

File metadata

  • Download URL: montreal_aqi_api-0.4.1.tar.gz
  • Upload date:
  • Size: 13.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for montreal_aqi_api-0.4.1.tar.gz
Algorithm Hash digest
SHA256 da07aa1160ad736c545328185e6826cca7c5106cab4f096fbd6c613951e2d505
MD5 64e5ab3d3fc6a08d4c59cc2b5f25fe32
BLAKE2b-256 520f9d0c548a52adc247fe72d7f2c6ee86fcb6918fd72e35110ae8fc83906a1e

See more details on using hashes here.

File details

Details for the file montreal_aqi_api-0.4.1-py3-none-any.whl.

File metadata

File hashes

Hashes for montreal_aqi_api-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e1544bfa669f38f60fc26eb4605e1fcd39af1e025cf60d27132fa64bb990bd16
MD5 167931421fb6990623632d3f82e34a31
BLAKE2b-256 76681cbc532a0d10486f627248dfa434726acea2ee846061d7ee854caf13ff98

See more details on using hashes here.

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