aeolus.portals¶
Functions for working with global data portals (OpenAQ, PurpleAir).
Functions¶
Search for monitoring locations in a portal.
Portals are global data platforms aggregating from multiple sources with potentially millions of locations. They require filters to narrow searches.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
portal
|
str
|
Portal name ("OPENAQ", "PURPLEAIR", etc.) |
required |
**filters
|
Any
|
Portal-specific search filters (REQUIRED) Common filters: - country="GB" - Filter by country code - bbox=(min_lon, min_lat, max_lon, max_lat) - Bounding box (GeoJSON/shapely format) - city="London" - City name (OpenAQ) - sensor_type="SDS011" - Sensor type (Sensor.Community) |
{}
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with location metadata including:
- site_code: Unique location identifier (use for download)
- site_name: Human-readable name
- latitude: Location latitude
- longitude: Location longitude
- source_network: Original data source (raw adapter metadata; |
Raises:
| Type | Description |
|---|---|
ValueError
|
If portal is unknown, not a portal type, or no filters provided |
Examples:
>>> # Find OpenAQ locations in UK
>>> locations = aeolus.portals.find_sites("OPENAQ", country="GB")
>>>
>>> # Find locations in bounding box (min_lon, min_lat, max_lon, max_lat)
>>> locations = aeolus.portals.find_sites(
... "OPENAQ",
... bbox=(-0.51, 51.28, 0.34, 51.69)
... )
>>>
>>> # Extract site codes for download
>>> site_codes = locations["site_code"].tolist()
Source code in src/aeolus/portals/api.py
Download air quality data from a portal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
portal
|
str
|
Portal name ("OPENAQ", "PURPLEAIR", etc.) |
required |
sites
|
list[str]
|
List of site codes (obtained from find_sites()) |
required |
start_date
|
datetime | None
|
Start of date range (inclusive) |
None
|
end_date
|
datetime | None
|
End of date range (inclusive) |
None
|
last
|
str | None
|
Date range shorthand, e.g. "6h", "30d", "2w", "6m", "1y". Mutually exclusive with start_date/end_date. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with standardised schema:
- site_code: Location identifier
- date_time: Measurement timestamp
- measurand: Pollutant measured (e.g., "NO2", "PM2.5")
- value: Measured value
- units: Units of measurement
- network / backend / qa_code / qa_tier / ratification_stage: the 0.5 contract columns
- source_network, ratification: deprecated mirrors ( |
Raises:
| Type | Description |
|---|---|
ValueError
|
If portal is unknown or not a portal type |
Examples:
>>> from datetime import datetime
>>>
>>> # Step 1: Find locations
>>> locations = aeolus.portals.find_sites("OPENAQ", country="GB")
>>> site_codes = locations["site_code"].head(5).tolist()
>>>
>>> # Step 2: Download data
>>> data = aeolus.portals.download(
... "OPENAQ",
... site_codes,
... datetime(2024, 1, 1),
... datetime(2024, 1, 31)
... )
>>> # Or with last= shorthand
>>> data = aeolus.portals.download("OPENAQ", site_codes, last="30d")
Source code in src/aeolus/portals/api.py
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | |
List all available portals.
Returns:
| Type | Description |
|---|---|
list[str]
|
List of portal names |
Examples:
Source code in src/aeolus/portals/api.py
Usage Examples¶
Find Sites¶
import aeolus
# Find OpenAQ sites in a country
uk_sites = aeolus.portals.find_sites("OPENAQ", country="GB")
# Find sites within a bounding box
# bbox format: (min_lon, min_lat, max_lon, max_lat) - same as GeoJSON/shapely
london_sites = aeolus.portals.find_sites(
"OPENAQ",
bbox=(-0.51, 51.28, 0.34, 51.69)
)
# Find PurpleAir sensors in an area (using standard bbox format)
purpleair_sites = aeolus.portals.find_sites(
"PURPLEAIR",
bbox=(-0.5, 51.3, 0.3, 51.7)
)
Download Portal Data¶
import aeolus
from datetime import datetime
# First get site codes from find_sites
locations = aeolus.portals.find_sites("OPENAQ", country="GB")
site_codes = locations["site_code"].tolist()[:5]
# Download using sites parameter (consistent with networks API)
data = aeolus.portals.download(
portal="OPENAQ",
sites=site_codes,
start_date=datetime(2024, 1, 1),
end_date=datetime(2024, 1, 31)
)
List Available Portals¶
Supported Portals¶
| Portal | Description | API Key |
|---|---|---|
| OPENAQ | Global air quality data platform | Yes (OPENAQ_API_KEY) |
| PURPLEAIR | Global low-cost sensor network (30,000+) | Yes (PURPLEAIR_API_KEY) |