Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions example.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
"""Example for getting the data from a station."""
import asyncio

import httpx

from luftdaten import Luftdaten

SENSOR_ID = 152
SENSOR_IDS = (152, 153)


async def main():
Expand All @@ -28,5 +31,27 @@ async def main():
)


async def main_with_httpx_client():
"""Sample code using an existing HTTPX client for multiple sensors."""
async with httpx.AsyncClient() as httpx_client:
# Reuse the same HTTPX session for all sensors.
for sensor_id in SENSOR_IDS:
data = Luftdaten(sensor_id, httpx_client=httpx_client)
await data.get_data()

if not await data.validate_sensor():
print("Station is not available:", data.sensor_id)
continue

if data.values and data.meta:
print("Sensor values:", data.values)
print(
"Location:",
data.meta["latitude"],
data.meta["longitude"],
data.meta["altitude"],
)


if __name__ == "__main__":
asyncio.run(main())
10 changes: 7 additions & 3 deletions luftdaten/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,25 @@
class Luftdaten(object):
"""A class for handling the data retrieval."""

def __init__(self, sensor_id):
def __init__(self, sensor_id, httpx_client=None):
"""Initialize the connection."""
self.sensor_id = sensor_id
self.data = None
self.values = {}
self.meta = {}
self.url = "{}/{}".format(_RESOURCE, "sensor")
self._httpx_client = httpx_client

async def get_data(self):
"""Retrieve the data."""
url = "{}/{}/".format(self.url, self.sensor_id)

try:
async with httpx.AsyncClient() as client:
response = await client.get(str(url))
if self._httpx_client is not None:
response = await self._httpx_client.get(str(url))
else:
async with httpx.AsyncClient() as client:
response = await client.get(str(url))
except httpx.ConnectError:
raise exceptions.LuftdatenConnectionError(f"Connection to {url} failed")
except httpx.ConnectTimeout:
Expand Down
25 changes: 25 additions & 0 deletions tests/test_data.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
"""Test the interaction with the Luftdaten API."""
from unittest.mock import AsyncMock, MagicMock

import httpx
import pytest
from pytest_httpx import HTTPXMock

Expand Down Expand Up @@ -67,6 +70,28 @@ async def test_sensor_values(httpx_mock: HTTPXMock):
assert client.values == {"temperature": 10.5, "humidity": 79.3}


@pytest.mark.asyncio
async def test_injected_client():
"""Test that an injected HTTPX client is used and not closed."""
httpx_client = AsyncMock(spec=httpx.AsyncClient)
response = MagicMock(spec=httpx.Response)
response.status_code = httpx.codes.OK
response.json.return_value = RESPONSE_VALID
httpx_client.get.return_value = response

client = Luftdaten(SENSOR_ID, httpx_client=httpx_client)
await client.get_data()

httpx_client.get.assert_awaited_once_with(
"https://data.sensor.community/airrohr/v1/sensor/1/"
)
httpx_client.__aenter__.assert_not_awaited()
httpx_client.__aexit__.assert_not_awaited()
httpx_client.aclose.assert_not_awaited()

assert client.values == {"temperature": 10.5, "humidity": 79.3}


@pytest.mark.asyncio
async def test_meta(httpx_mock: HTTPXMock):
"""Test the meta information."""
Expand Down
Loading