Skip to content

Commit

Permalink
Implement rety logic on FreeAtHome _request method
Browse files Browse the repository at this point in the history
  • Loading branch information
kingsleyadam committed Jan 7, 2025
1 parent a5e4c4b commit 8c43fb9
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 13 deletions.
5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ classifiers = [
"Operating System :: OS Independent",
]
dependencies = [
"aiohttp", "packaging"
"aiohttp", "packaging", "backoff"
]

[project.urls]
Expand Down Expand Up @@ -164,5 +164,8 @@ pythonpath = [
"."
]

[tool.pytest_env]
FREEATHOME_MAX_REQUEST_TRIES = "1"

[tool.coverage.run]
omit = ["*/tests/*"]
28 changes: 17 additions & 11 deletions src/abbfreeathome/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@
from collections.abc import Callable
import inspect
import logging
import os
from typing import Any
from urllib.parse import urlparse

from aiohttp.client import ClientSession, ClientWebSocketResponse
from aiohttp.client_exceptions import (
ClientConnectionError as AioHttpClientConnectionError,
ClientResponseError as AioHttpClientResponseError,
InvalidUrlClientError as AioHttpInvalidUrlClientError,
WSServerHandshakeError as AioHttpWSServerHandshakeError,
)
from aiohttp.helpers import BasicAuth
from aiohttp.http import WSMsgType
import backoff
from packaging.version import Version

from .exceptions import (
Expand Down Expand Up @@ -222,6 +225,11 @@ def _get_client_session(self) -> ClientSession:

return self._client_session

@backoff.on_exception(
backoff.expo,
InvalidApiResponseException,
max_tries=int(os.environ.get("FREEATHOME_MAX_REQUEST_TRIES", 5)),
)
async def _request(self, path: str, method: str = "get", data: Any | None = None):
"""Make a request to the API."""

Expand All @@ -237,6 +245,7 @@ async def _request(self, path: str, method: str = "get", data: Any | None = None
url=f"{self._host}{_full_path}",
data=data,
auth=self._auth,
raise_for_status=True,
) as resp,
):
_response_status = resp.status
Expand All @@ -249,17 +258,14 @@ async def _request(self, path: str, method: str = "get", data: Any | None = None
raise InvalidHostException(self._host) from e
except AioHttpClientConnectionError as e:
raise ClientConnectionError(self._host) from e

# Check the status code and raise exception accordingly.
if _response_status == 401:
raise InvalidCredentialsException(self._auth.login)
if _response_status == 403:
raise ForbiddenAuthException(path)
if _response_status == 502:
raise ConnectionTimeoutException(self._host)

if _response_status != 200:
raise InvalidApiResponseException(_response_status) from None
except AioHttpClientResponseError as e:
if e.status == 401:
raise InvalidCredentialsException(self._auth.login) from e
if e.status == 403:
raise ForbiddenAuthException(path) from e
if e.status == 502:
raise ConnectionTimeoutException(self._host) from e
raise InvalidApiResponseException(e.status) from e

return _response_data

Expand Down
4 changes: 3 additions & 1 deletion src/abbfreeathome/dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
aiohttp!=3.11.0
aioresponses
backoff
packaging
pre-commit
pytest
pytest-asyncio
pytest-cov
ruff
pytest-env
ruff

0 comments on commit 8c43fb9

Please sign in to comment.