Skip to content

Commit d936b10

Browse files
committed
Expand example to demonstrate refresh token works
1 parent 50c9de3 commit d936b10

File tree

3 files changed

+48
-5
lines changed

3 files changed

+48
-5
lines changed

examples/example.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""Asynchronous Python client for the Tado API. This is an example file."""
22

3+
from __future__ import annotations
4+
35
import asyncio
46
import logging
57

@@ -10,13 +12,26 @@
1012

1113
async def main() -> None:
1214
"""Show example on how to use aiohttp.ClientSession."""
15+
refresh_token: str | None = None
1316
async with Tado(debug=True) as tado:
1417
print("Device activation status: ", tado.device_activation_status) # noqa: T201
1518
print("Device verification URL: ", tado.device_verification_url) # noqa: T201
1619

1720
print("Starting device activation") # noqa: T201
1821
await tado.device_activation()
22+
refresh_token = tado.refresh_token
23+
24+
print("Device activation status: ", tado.device_activation_status) # noqa: T201
25+
26+
devices = await tado.get_devices()
27+
28+
print("Devices: ", devices) # noqa: T201
29+
30+
print("Trying to use the stored refresh token for another run...") # noqa: T201
31+
await asyncio.sleep(1)
1932

33+
async with Tado(debug=True, refresh_token=refresh_token) as tado:
34+
print("Refresh token: ", tado.refresh_token) # noqa: T201
2035
print("Device activation status: ", tado.device_activation_status) # noqa: T201
2136

2237
devices = await tado.get_devices()

src/tadoasync/tadoasync.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ async def async_init(self) -> None:
123123
self._device_activation_status = await self.login_device_flow()
124124
else:
125125
self._device_ready()
126+
get_me = await self.get_me()
127+
self._home_id = get_me.homes[0].id
126128

127129
@property
128130
def device_activation_status(self) -> DeviceActivationStatus:
@@ -134,6 +136,11 @@ def device_verification_url(self) -> str | None:
134136
"""Return the device verification URL."""
135137
return self._device_verification_url
136138

139+
@property
140+
def refresh_token(self) -> str | None:
141+
"""Return the refresh token."""
142+
return self._refresh_token
143+
137144
async def login_device_flow(self) -> DeviceActivationStatus:
138145
"""Login using device flow."""
139146
if self._device_activation_status != DeviceActivationStatus.NOT_STARTED:
@@ -340,17 +347,15 @@ async def _refresh_auth(self) -> None:
340347
data = {
341348
"client_id": CLIENT_ID,
342349
"grant_type": "refresh_token",
343-
"scope": "home.user",
344350
"refresh_token": self._refresh_token,
345351
}
346352

347-
if self._session is None:
348-
self._session = ClientSession()
349-
self._close_session = True
353+
_LOGGER.debug("Refreshing Tado token")
350354

351355
try:
352356
async with asyncio.timeout(self._request_timeout):
353-
request = await self._session.post(url=TOKEN_URL, data=data)
357+
session = self._ensure_session()
358+
request = await session.post(url=TOKEN_URL, data=data)
354359
request.raise_for_status()
355360
except asyncio.TimeoutError as err:
356361
raise TadoConnectionError(
@@ -364,6 +369,8 @@ async def _refresh_auth(self) -> None:
364369
self._token_expiry = time.time() + float(response["expires_in"])
365370
self._refresh_token = response["refresh_token"]
366371

372+
_LOGGER.debug("Tado token refreshed")
373+
367374
async def get_me(self) -> GetMe:
368375
"""Get the user information."""
369376
if self._me is None:

tests/test_tado.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,27 @@ async def mock_post(*args: Any, **kwargs: Any) -> ClientResponse: # noqa: ARG00
188188
await tado.async_init()
189189

190190

191+
async def test_login_client_response_still_pending() -> None:
192+
"""Test login client response error."""
193+
mock_request_info = MagicMock(spec=RequestInfo)
194+
mock_response = MagicMock(spec=ClientResponse)
195+
mock_response.raise_for_status.side_effect = ClientResponseError(
196+
mock_request_info, (mock_response,), status=400
197+
)
198+
mock_response.status = 400
199+
mock_response.text = AsyncMock(return_value="authorization_pending")
200+
201+
async def mock_post(*args: Any, **kwargs: Any) -> ClientResponse: # noqa: ARG001 # pylint: disable=unused-argument
202+
return mock_response
203+
204+
async with aiohttp.ClientSession() as session:
205+
tado = Tado(session=session)
206+
with patch("aiohttp.ClientSession.post", new=mock_post), pytest.raises(
207+
TadoAuthenticationError
208+
):
209+
await tado.async_init()
210+
211+
191212
async def test_refresh_auth_success(responses: aioresponses) -> None:
192213
"""Test successful refresh of auth token."""
193214
responses.post(

0 commit comments

Comments
 (0)