From dffb9be1bfa8833ba3145a3ef39436fe5b9baa02 Mon Sep 17 00:00:00 2001 From: Andrew Herrington Date: Fri, 10 Dec 2021 22:43:32 -0600 Subject: [PATCH] linting --- .flake8 | 2 +- src/healthchecks_io/client/_abstract.py | 17 +++++--- src/healthchecks_io/client/asyncclient.py | 48 ++++++++++---------- src/healthchecks_io/client/exceptions.py | 4 +- tests/client/test_async.py | 53 +++++++++++++---------- tests/conftest.py | 45 ++++++++----------- 6 files changed, 90 insertions(+), 79 deletions(-) diff --git a/.flake8 b/.flake8 index 7bc6eae..2658dfb 100644 --- a/.flake8 +++ b/.flake8 @@ -1,6 +1,6 @@ [flake8] select = B,B9,C,D,DAR,E,F,N,RST,S,W -ignore = E203,E501,RST201,RST203,RST301,W503,B902,N805 +ignore = E203,E501,RST201,RST203,RST301,W503,B902,N805,DAR402 max-line-length = 119 max-complexity = 10 docstring-convention = google diff --git a/src/healthchecks_io/client/_abstract.py b/src/healthchecks_io/client/_abstract.py index 9cd8612..9797263 100644 --- a/src/healthchecks_io/client/_abstract.py +++ b/src/healthchecks_io/client/_abstract.py @@ -12,10 +12,14 @@ from urllib.parse import urljoin from urllib.parse import urlparse from weakref import finalize -from httpx import Client, Response +from httpx import Client +from httpx import Response +from .exceptions import BadAPIRequestError +from .exceptions import CheckNotFoundError +from .exceptions import HCAPIAuthError +from .exceptions import HCAPIError from healthchecks_io.schemas import checks -from .exceptions import HCAPIAuthError, HCAPIError, CheckNotFoundError, BadAPIRequestError class AbstractClient(ABC): @@ -91,6 +95,7 @@ class AbstractClient(ABC): HCAPIAuthError: Raised when status_code == 401 or 403 HCAPIError: Raised when status_code is 5xx CheckNotFoundError: Raised when status_code is 404 + BadAPIRequestError: Raised when status_code is 400 Returns: Response: the passed in response object @@ -103,12 +108,14 @@ class AbstractClient(ABC): f"Error when reaching out to HC API at {response.request.url}. " f"Status Code {response.status_code}. Response {response.text}" ) - + if response.status_code == 404: raise CheckNotFoundError(f"CHeck not found at {response.request.url}") - + if response.status_code == 400: - raise BadAPIRequestError(f"Bad request when requesting {response.request.url}. {response.text}") + raise BadAPIRequestError( + f"Bad request when requesting {response.request.url}. {response.text}" + ) return response diff --git a/src/healthchecks_io/client/asyncclient.py b/src/healthchecks_io/client/asyncclient.py index 54ca797..eb2b35f 100644 --- a/src/healthchecks_io/client/asyncclient.py +++ b/src/healthchecks_io/client/asyncclient.py @@ -73,9 +73,9 @@ class AsyncClient(AbstractClient): checks.Check.from_api_result(check_data) for check_data in response.json()["checks"] ] - + async def get_check(self, check_id: str) -> checks.Check: - """Get a single check by id. + """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. @@ -97,9 +97,9 @@ class AsyncClient(AbstractClient): return checks.Check.from_api_result(response.json()) async def pause_check(self, check_id: str) -> checks.Check: - """Disables monitoring for a check without removing it. - - The check goes into a "paused" state. + """Disables monitoring for a check without removing it. + + The check goes into a "paused" state. You can resume monitoring of the check by pinging it. check_id must be a uuid, not a unique id @@ -117,11 +117,11 @@ class AsyncClient(AbstractClient): """ request_url = self._get_api_request_url(f"checks/{check_id}/pause") - response = self.check_response(await self._client.post(request_url , data={})) + response = self.check_response(await self._client.post(request_url, data={})) return checks.Check.from_api_result(response.json()) async def delete_check(self, check_id: str) -> checks.Check: - """Permanently deletes the check from the user's account. + """Permanently deletes the check from the user's account. check_id must be a uuid, not a unique id @@ -143,9 +143,9 @@ class AsyncClient(AbstractClient): async def get_check_pings(self, check_id: str) -> List[checks.CheckPings]: """Returns a list of pings this check has received. - - This endpoint returns pings in reverse order (most recent first), - and the total number of returned pings depends on the account's + + This endpoint returns pings in reverse order (most recent first), + and the total number of returned pings depends on the account's billing plan: 100 for free accounts, 1000 for paid accounts. Args: @@ -167,10 +167,15 @@ class AsyncClient(AbstractClient): for check_data in response.json()["pings"] ] - async def get_check_flips(self, check_id: str, seconds: Optional[int] = None, start: Optional[int] = None, end: Optional[int] = None) -> List[checks.CheckStatuses]: - """ - Returns a list of "flips" this check has experienced. - + async def get_check_flips( + self, + check_id: str, + seconds: Optional[int] = None, + start: Optional[int] = None, + end: Optional[int] = None, + ) -> List[checks.CheckStatuses]: + """Returns a list of "flips" this check has experienced. + A flip is a change of status (from "down" to "up," or from "up" to "down"). Raises: @@ -187,19 +192,16 @@ class AsyncClient(AbstractClient): Returns: List[checks.CheckStatuses]: List of status flips for this check - + """ params = dict() - if seconds is not None and seconds >=0: - params['seconds'] = seconds + if seconds is not None and seconds >= 0: + params["seconds"] = seconds if start is not None and start >= 0: - params['start'] = start + params["start"] = start if end is not None and end >= 0: - params['end'] = end + params["end"] = end request_url = self._get_api_request_url(f"checks/{check_id}/flips/", params) response = self.check_response(await self._client.get(request_url)) - return [ - checks.CheckStatuses(**status_data) - for status_data in response.json() - ] + return [checks.CheckStatuses(**status_data) for status_data in response.json()] diff --git a/src/healthchecks_io/client/exceptions.py b/src/healthchecks_io/client/exceptions.py index 1737310..abc8d1d 100644 --- a/src/healthchecks_io/client/exceptions.py +++ b/src/healthchecks_io/client/exceptions.py @@ -12,12 +12,14 @@ class HCAPIAuthError(HCAPIError): ... + class CheckNotFoundError(HCAPIError): """Thrown when getting a check returns a 404.""" ... + class BadAPIRequestError(HCAPIError): """Thrown when an api request returns a 400.""" - ... \ No newline at end of file + ... diff --git a/tests/client/test_async.py b/tests/client/test_async.py index 0317d72..326d8b5 100644 --- a/tests/client/test_async.py +++ b/tests/client/test_async.py @@ -6,8 +6,10 @@ from httpx import AsyncClient as HTTPXAsyncClient from httpx import Response from healthchecks_io.client import AsyncClient +from healthchecks_io.client.exceptions import BadAPIRequestError +from healthchecks_io.client.exceptions import CheckNotFoundError from healthchecks_io.client.exceptions import HCAPIAuthError -from healthchecks_io.client.exceptions import HCAPIError, CheckNotFoundError, BadAPIRequestError +from healthchecks_io.client.exceptions import HCAPIError @pytest.mark.asyncio @@ -93,9 +95,7 @@ async def test_get_check_200(fake_check_api_result, respx_mock, test_async_clien async def test_check_get_404(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=404) - ) + respx_mock.get(checks_url).mock(return_value=Response(status_code=404)) with pytest.raises(CheckNotFoundError): await test_async_client.get_check("test") @@ -117,9 +117,7 @@ async def test_pause_check_200(fake_check_api_result, respx_mock, test_async_cli async def test_check_pause_404(respx_mock, test_async_client): assert test_async_client._client is not None checks_url = urljoin(test_async_client._api_url, "checks/test/pause") - respx_mock.post(checks_url).mock( - return_value=Response(status_code=404) - ) + respx_mock.post(checks_url).mock(return_value=Response(status_code=404)) with pytest.raises(CheckNotFoundError): await test_async_client.pause_check("test") @@ -141,28 +139,33 @@ async def test_delete_check_200(fake_check_api_result, respx_mock, test_async_cl async def test_delete_pause404(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.delete(checks_url).mock( - return_value=Response(status_code=404) - ) + respx_mock.delete(checks_url).mock(return_value=Response(status_code=404)) with pytest.raises(CheckNotFoundError): await test_async_client.delete_check("test") + @pytest.mark.asyncio @pytest.mark.respx -async def test_get_check_pings_200(fake_check_pings_api_result, respx_mock, test_async_client): +async def test_get_check_pings_200( + fake_check_pings_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/pings/") respx_mock.get(checks_url).mock( - return_value=Response(status_code=200, json={"pings": fake_check_pings_api_result}) + return_value=Response( + status_code=200, json={"pings": fake_check_pings_api_result} + ) ) pings = await test_async_client.get_check_pings("test") assert len(pings) == len(fake_check_pings_api_result) - assert pings[0].type == fake_check_pings_api_result[0]['type'] + assert pings[0].type == fake_check_pings_api_result[0]["type"] @pytest.mark.asyncio @pytest.mark.respx -async def test_get_check_flips_200(fake_check_flips_api_result, respx_mock, test_async_client): +async def test_get_check_flips_200( + fake_check_flips_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/flips/") respx_mock.get(checks_url).mock( @@ -170,29 +173,33 @@ async def test_get_check_flips_200(fake_check_flips_api_result, respx_mock, test ) flips = await test_async_client.get_check_flips("test") assert len(flips) == len(fake_check_flips_api_result) - assert flips[0].up == fake_check_flips_api_result[0]['up'] + assert flips[0].up == fake_check_flips_api_result[0]["up"] @pytest.mark.asyncio @pytest.mark.respx -async def test_get_check_flips_params_200(fake_check_flips_api_result, respx_mock, test_async_client): +async def test_get_check_flips_params_200( + fake_check_flips_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/flips/?seconds=1&start=1&end=1") + checks_url = urljoin( + test_async_client._api_url, "checks/test/flips/?seconds=1&start=1&end=1" + ) respx_mock.get(checks_url).mock( return_value=Response(status_code=200, json=fake_check_flips_api_result) ) flips = await test_async_client.get_check_flips("test", seconds=1, start=1, end=1) assert len(flips) == len(fake_check_flips_api_result) - assert flips[0].up == fake_check_flips_api_result[0]['up'] + assert flips[0].up == fake_check_flips_api_result[0]["up"] @pytest.mark.asyncio @pytest.mark.respx -async def test_get_check_flips_400(fake_check_flips_api_result, respx_mock, test_async_client): +async def test_get_check_flips_400( + fake_check_flips_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/flips/") - respx_mock.get(checks_url).mock( - return_value=Response(status_code=400) - ) + respx_mock.get(checks_url).mock(return_value=Response(status_code=400)) with pytest.raises(BadAPIRequestError): - await test_async_client.get_check_flips("test") \ No newline at end of file + await test_async_client.get_check_flips("test") diff --git a/tests/conftest.py b/tests/conftest.py index 3ddd00c..8162afc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -87,10 +87,11 @@ def test_async_client(): yield AsyncClient(api_key="test", api_url="https://localhost/api") + @pytest.fixture def fake_check_pings_api_result(): return [ - { + { "type": "success", "date": "2020-06-09T14:51:06.113073+00:00", "n": 4, @@ -98,18 +99,18 @@ def fake_check_pings_api_result(): "remote_addr": "192.0.2.0", "method": "GET", "ua": "curl/7.68.0", - "duration": 2.896736 - }, - { + "duration": 2.896736, + }, + { "type": "start", "date": "2020-06-09T14:51:03.216337+00:00", "n": 3, "scheme": "http", "remote_addr": "192.0.2.0", "method": "GET", - "ua": "curl/7.68.0" - }, - { + "ua": "curl/7.68.0", + }, + { "type": "success", "date": "2020-06-09T14:50:59.633577+00:00", "n": 2, @@ -117,32 +118,24 @@ def fake_check_pings_api_result(): "remote_addr": "192.0.2.0", "method": "GET", "ua": "curl/7.68.0", - "duration": 2.997976 - }, - { + "duration": 2.997976, + }, + { "type": "start", "date": "2020-06-09T14:50:56.635601+00:00", "n": 1, "scheme": "http", "remote_addr": "192.0.2.0", "method": "GET", - "ua": "curl/7.68.0" - } - ] + "ua": "curl/7.68.0", + }, + ] + @pytest.fixture def fake_check_flips_api_result(): return [ - { - "timestamp": "2020-03-23T10:18:23+00:00", - "up": 1 - }, - { - "timestamp": "2020-03-23T10:17:15+00:00", - "up": 0 - }, - { - "timestamp": "2020-03-23T10:16:18+00:00", - "up": 1 - } - ] \ No newline at end of file + {"timestamp": "2020-03-23T10:18:23+00:00", "up": 1}, + {"timestamp": "2020-03-23T10:17:15+00:00", "up": 0}, + {"timestamp": "2020-03-23T10:16:18+00:00", "up": 1}, + ]