mirror of
https://github.com/andrewthetechie/py-healthchecks.io.git
synced 2025-12-06 17:48:30 +01:00
generic response checking method and get_check
This commit is contained in:
@@ -12,9 +12,10 @@ from urllib.parse import urljoin
|
|||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
from weakref import finalize
|
from weakref import finalize
|
||||||
|
|
||||||
from httpx import Client
|
from httpx import Client, Response
|
||||||
|
|
||||||
from healthchecks_io.schemas import checks
|
from healthchecks_io.schemas import checks
|
||||||
|
from .exceptions import HCAPIAuthError, HCAPIError, CheckNotFoundError
|
||||||
|
|
||||||
|
|
||||||
class AbstractClient(ABC):
|
class AbstractClient(ABC):
|
||||||
@@ -79,6 +80,31 @@ class AbstractClient(ABC):
|
|||||||
"""
|
"""
|
||||||
return self._client.is_closed
|
return self._client.is_closed
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def check_response(response: Response) -> Response:
|
||||||
|
"""Checks a healthchecks.io response.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
response (Response): a response from the healthchecks.io api
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
HCAPIAuthError: Raised when status_code == 401 or 403
|
||||||
|
HCAPIError: Raised when status_code is 5xx
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response: the passed in response object
|
||||||
|
"""
|
||||||
|
if response.status_code == 401 or response.status_code == 403:
|
||||||
|
raise HCAPIAuthError("Auth failure when getting checks")
|
||||||
|
|
||||||
|
if str(response.status_code).startswith("5"):
|
||||||
|
raise HCAPIError(
|
||||||
|
f"Error when reaching out to HC API at {response.request.url}. "
|
||||||
|
f"Status Code {response.status_code}. Response {response.text}"
|
||||||
|
)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _add_url_params(url: str, params: Dict[str, str], replace: bool = True):
|
def _add_url_params(url: str, params: Dict[str, str], replace: bool = True):
|
||||||
"""Add GET params to provided URL being aware of existing.
|
"""Add GET params to provided URL being aware of existing.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from typing import Optional
|
|||||||
from httpx import AsyncClient as HTTPXAsyncClient
|
from httpx import AsyncClient as HTTPXAsyncClient
|
||||||
|
|
||||||
from ._abstract import AbstractClient
|
from ._abstract import AbstractClient
|
||||||
from .exceptions import HCAPIAuthError
|
from .exceptions import HCAPIAuthError, CheckNotFoundError
|
||||||
from .exceptions import HCAPIError
|
from .exceptions import HCAPIError
|
||||||
from healthchecks_io import VERSION
|
from healthchecks_io import VERSION
|
||||||
from healthchecks_io.schemas import checks
|
from healthchecks_io.schemas import checks
|
||||||
@@ -69,18 +69,31 @@ class AsyncClient(AbstractClient):
|
|||||||
request_url, {"tag": tag}, replace=False
|
request_url, {"tag": tag}, replace=False
|
||||||
)
|
)
|
||||||
|
|
||||||
response = await self._client.get(request_url)
|
response = self.check_response(await self._client.get(request_url))
|
||||||
|
|
||||||
if response.status_code == 401:
|
|
||||||
raise HCAPIAuthError("Auth failure when getting checks")
|
|
||||||
|
|
||||||
if response.status_code != 200:
|
|
||||||
raise HCAPIError(
|
|
||||||
f"Error when reaching out to HC API at {request_url}. "
|
|
||||||
f"Status Code {response.status_code}. Response {response.text}"
|
|
||||||
)
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
checks.Check.from_api_result(check_data)
|
checks.Check.from_api_result(check_data)
|
||||||
for check_data in response.json()["checks"]
|
for check_data in response.json()["checks"]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
async def get_check(self, check_id: str) -> checks.Check:
|
||||||
|
"""Get a single check by id.
|
||||||
|
|
||||||
|
check_id can either be a check uuid if using a read/write api key
|
||||||
|
or a unique key if using a read only api key.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
check_id (str): check's uuid or unique id
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
checks.Check: the check
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
CheckNotFoundError: when no check with check_id is found
|
||||||
|
"""
|
||||||
|
request_url = self._get_api_request_url(f"checks/{check_id}")
|
||||||
|
response = self.check_response(await self._client.get(request_url))
|
||||||
|
if response.status_code == 404:
|
||||||
|
raise CheckNotFoundError(f"{check_id} not found at {request_url}")
|
||||||
|
return checks.Check.from_api_result(response.json())
|
||||||
|
|
||||||
|
|||||||
@@ -11,3 +11,8 @@ class HCAPIAuthError(HCAPIError):
|
|||||||
"""Thrown when we fail to auth to the Healthchecks api."""
|
"""Thrown when we fail to auth to the Healthchecks api."""
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
class CheckNotFoundError(HCAPIError):
|
||||||
|
"""Thrown when getting a check returns a 404."""
|
||||||
|
|
||||||
|
...
|
||||||
@@ -74,3 +74,15 @@ def test_finalizer_closes(test_async_client):
|
|||||||
assert not test_async_client.is_closed
|
assert not test_async_client.is_closed
|
||||||
test_async_client._finalizer_method()
|
test_async_client._finalizer_method()
|
||||||
assert test_async_client.is_closed
|
assert test_async_client.is_closed
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
@pytest.mark.respx
|
||||||
|
async def test_get_check_200(fake_check_api_result, respx_mock, test_async_client):
|
||||||
|
assert test_async_client._client is not None
|
||||||
|
checks_url = urljoin(test_async_client._api_url, "checks/test")
|
||||||
|
respx_mock.get(checks_url).mock(
|
||||||
|
return_value=Response(status_code=200, json=fake_check_api_result)
|
||||||
|
)
|
||||||
|
check = await test_async_client.get_check(check_id="test")
|
||||||
|
assert check.name == fake_check_api_result["name"]
|
||||||
|
|||||||
Reference in New Issue
Block a user