mirror of
https://github.com/andrewthetechie/py-healthchecks.io.git
synced 2025-12-06 09:38:33 +01:00
passing nox
This commit is contained in:
@@ -158,7 +158,7 @@ def bandit(session: Session) -> None:
|
|||||||
def tests(session: Session) -> None:
|
def tests(session: Session) -> None:
|
||||||
"""Run the test suite."""
|
"""Run the test suite."""
|
||||||
session.install(".")
|
session.install(".")
|
||||||
session.install("coverage[toml]", "pytest", "pygments")
|
session.install("coverage[toml]", "pytest", "pygments", "respx", "pytest-asyncio")
|
||||||
try:
|
try:
|
||||||
session.run("coverage", "run", "--parallel", "-m", "pytest", *session.posargs)
|
session.run("coverage", "run", "--parallel", "-m", "pytest", *session.posargs)
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@@ -7,3 +7,12 @@ from .client.exceptions import BadAPIRequestError # noqa: F401, E402
|
|||||||
from .client.exceptions import CheckNotFoundError # noqa: F401, E402
|
from .client.exceptions import CheckNotFoundError # noqa: F401, E402
|
||||||
from .client.exceptions import HCAPIAuthError # noqa: F401, E402
|
from .client.exceptions import HCAPIAuthError # noqa: F401, E402
|
||||||
from .client.exceptions import HCAPIError # noqa: F401, E402
|
from .client.exceptions import HCAPIError # noqa: F401, E402
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"AsyncClient",
|
||||||
|
"Client",
|
||||||
|
"BadAPIRequestError",
|
||||||
|
"CheckNotFoundError",
|
||||||
|
"HCAPIAuthError",
|
||||||
|
"HCAPIError",
|
||||||
|
]
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
"""healthchecks_io clients."""
|
"""healthchecks_io clients."""
|
||||||
from .async_client import AsyncClient # noqa: F401
|
from .async_client import AsyncClient # noqa: F401
|
||||||
from .sync_client import Client # noqa: F401
|
from .sync_client import Client # noqa: F401
|
||||||
|
|
||||||
|
__all__ = ["AsyncClient", "Client"]
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
from abc import ABC
|
from abc import ABC
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from json import dumps
|
from typing import Any
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from typing import List
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
from typing import Union
|
||||||
from urllib.parse import parse_qsl
|
from urllib.parse import parse_qsl
|
||||||
from urllib.parse import ParseResult
|
from urllib.parse import ParseResult
|
||||||
from urllib.parse import unquote
|
from urllib.parse import unquote
|
||||||
@@ -12,16 +12,12 @@ 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 Response
|
from httpx import Response
|
||||||
|
|
||||||
from .exceptions import BadAPIRequestError
|
from .exceptions import BadAPIRequestError
|
||||||
from .exceptions import CheckNotFoundError
|
from .exceptions import CheckNotFoundError
|
||||||
from .exceptions import HCAPIAuthError
|
from .exceptions import HCAPIAuthError
|
||||||
from .exceptions import HCAPIError
|
from .exceptions import HCAPIError
|
||||||
from healthchecks_io.schemas import badges
|
|
||||||
from healthchecks_io.schemas import checks
|
|
||||||
from healthchecks_io.schemas import integrations
|
|
||||||
|
|
||||||
|
|
||||||
class AbstractClient(ABC):
|
class AbstractClient(ABC):
|
||||||
@@ -30,198 +26,29 @@ class AbstractClient(ABC):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
api_key: str,
|
api_key: str,
|
||||||
api_url: Optional[str] = "https://healthchecks.io/api/",
|
api_url: str = "https://healthchecks.io/api/",
|
||||||
api_version: Optional[int] = 1,
|
api_version: int = 1,
|
||||||
client: Optional[Client] = None,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""An AbstractClient that other clients can implement.
|
"""An AbstractClient that other clients can implement.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
api_key (str): Healthchecks.io API key
|
api_key (str): Healthchecks.io API key
|
||||||
api_url (Optional[str], optional): API URL. Defaults to "https://healthchecks.io/api/".
|
api_url (str): API URL. Defaults to "https://healthchecks.io/api/".
|
||||||
api_version (Optional[int], optional): Versiopn of the api to use. Defaults to 1.
|
api_version (int): Versiopn of the api to use. Defaults to 1.
|
||||||
client (Optional[Client], optional): A httpx.Client. If not
|
|
||||||
passed in, one will be created for this object. Defaults to None.
|
|
||||||
"""
|
"""
|
||||||
self._api_key = api_key
|
self._api_key = api_key
|
||||||
self._client = client
|
|
||||||
if not api_url.endswith("/"):
|
if not api_url.endswith("/"):
|
||||||
api_url = f"{api_url}/"
|
api_url = f"{api_url}/"
|
||||||
self._api_url = urljoin(api_url, f"v{api_version}/")
|
self._api_url = urljoin(api_url, f"v{api_version}/")
|
||||||
self._finalizer = finalize(self, self._finalizer_method)
|
self._finalizer = finalize(self, self._finalizer_method)
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def _finalizer_method(self): # pragma: no cover
|
def _finalizer_method(self) -> None: # pragma: no cover
|
||||||
"""Finalizer method is called by weakref.finalize when the object is dereferenced to do cleanup of clients."""
|
"""Finalizer method is called by weakref.finalize when the object is dereferenced to do cleanup of clients."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_checks(
|
|
||||||
self, tags: Optional[List[str]]
|
|
||||||
) -> List[checks.Check]: # pragma: no cover
|
|
||||||
"""Calls the API's /checks/ endpoint to get a list of checks."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_check(self, check_id: str) -> checks.Check: # pragma: no cover
|
|
||||||
"""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:
|
|
||||||
HCAPIAuthError: Raised when status_code == 401 or 403
|
|
||||||
HCAPIError: Raised when status_code is 5xx
|
|
||||||
CheckNotFoundError: Raised when status_code is 404
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def pause_check(self, check_id: str) -> checks.Check: # pragma: no cover
|
|
||||||
"""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
|
|
||||||
|
|
||||||
Args:
|
|
||||||
check_id (str): check's uuid
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
checks.Check: the check just paused
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
HCAPIAuthError: Raised when status_code == 401 or 403
|
|
||||||
HCAPIError: Raised when status_code is 5xx
|
|
||||||
CheckNotFoundError: Raised when status_code is 404
|
|
||||||
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_check(self, check_id: str) -> checks.Check: # pragma: no cover
|
|
||||||
"""Permanently deletes the check from the user's account.
|
|
||||||
|
|
||||||
check_id must be a uuid, not a unique id
|
|
||||||
|
|
||||||
Args:
|
|
||||||
check_id (str): check's uuid
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
checks.Check: the check just deleted
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
HCAPIAuthError: Raised when status_code == 401 or 403
|
|
||||||
HCAPIError: Raised when status_code is 5xx
|
|
||||||
CheckNotFoundError: Raised when status_code is 404
|
|
||||||
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_check_pings(
|
|
||||||
self, check_id: str
|
|
||||||
) -> List[checks.CheckPings]: # pragma: no cover
|
|
||||||
"""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
|
|
||||||
billing plan: 100 for free accounts, 1000 for paid accounts.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
check_id (str): check's uuid
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
List[checks.CheckPings]: list of pings this check has received
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
HCAPIAuthError: Raised when status_code == 401 or 403
|
|
||||||
HCAPIError: Raised when status_code is 5xx
|
|
||||||
CheckNotFoundError: Raised when status_code is 404
|
|
||||||
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_check_flips(
|
|
||||||
self,
|
|
||||||
check_id: str,
|
|
||||||
seconds: Optional[int] = None,
|
|
||||||
start: Optional[int] = None,
|
|
||||||
end: Optional[int] = None,
|
|
||||||
) -> List[checks.CheckStatuses]: # pragma: no cover
|
|
||||||
"""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:
|
|
||||||
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
|
|
||||||
|
|
||||||
Args:
|
|
||||||
check_id (str): check uuid
|
|
||||||
seconds (Optional[int], optional): Returns the flips from the last value seconds. Defaults to None.
|
|
||||||
start (Optional[int], optional): Returns flips that are newer than the specified UNIX timestamp.. Defaults to None.
|
|
||||||
end (Optional[int], optional): Returns flips that are older than the specified UNIX timestamp.. Defaults to None.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
List[checks.CheckStatuses]: List of status flips for this check
|
|
||||||
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_integrations(
|
|
||||||
self,
|
|
||||||
) -> List[Optional[integrations.Integration]]: # pragma: no cover
|
|
||||||
"""Returns a list of integrations belonging to the project.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
HCAPIAuthError: Raised when status_code == 401 or 403
|
|
||||||
HCAPIError: Raised when status_code is 5xx
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
List[Optional[integrations.Integration]]: List of integrations for the project
|
|
||||||
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_badges(self) -> Dict[str, badges.Badges]: # pragma: no cover
|
|
||||||
"""Returns a dict of all tags in the project, with badge URLs for each tag.
|
|
||||||
|
|
||||||
Healthchecks.io provides badges in a few different formats:
|
|
||||||
svg: returns the badge as a SVG document.
|
|
||||||
json: returns a JSON document which you can use to generate a custom badge yourself.
|
|
||||||
shields: returns JSON in a Shields.io compatible format.
|
|
||||||
In addition, badges have 2-state and 3-state variations:
|
|
||||||
|
|
||||||
svg, json, shields: reports two states: "up" and "down". It considers any checks in the grace period as still "up".
|
|
||||||
svg3, json3, shields3: reports three states: "up", "late", and "down".
|
|
||||||
|
|
||||||
The response includes a special * entry: this pseudo-tag reports the overal status
|
|
||||||
of all checks in the project.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
HCAPIAuthError: Raised when status_code == 401 or 403
|
|
||||||
HCAPIError: Raised when status_code is 5xx
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Dict[str, badges.Badges]: Dictionary of all tags in the project with badges
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _get_api_request_url(
|
def _get_api_request_url(
|
||||||
self, path: str, params: Optional[Dict[str, str]] = None
|
self, path: str, params: Optional[Dict[str, Any]] = None
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Get a full request url for the healthchecks api.
|
"""Get a full request url for the healthchecks api.
|
||||||
|
|
||||||
@@ -242,7 +69,7 @@ class AbstractClient(ABC):
|
|||||||
Returns:
|
Returns:
|
||||||
bool: is the client closed
|
bool: is the client closed
|
||||||
"""
|
"""
|
||||||
return self._client.is_closed
|
return self._client.is_closed # type: ignore
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_response(response: Response) -> Response:
|
def check_response(response: Response) -> Response:
|
||||||
@@ -280,7 +107,9 @@ class AbstractClient(ABC):
|
|||||||
return response
|
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, Union[str, int, bool]], replace: bool = True
|
||||||
|
) -> str:
|
||||||
"""Add GET params to provided URL being aware of existing.
|
"""Add GET params to provided URL being aware of existing.
|
||||||
|
|
||||||
:param url: string of target URL
|
:param url: string of target URL
|
||||||
@@ -301,9 +130,13 @@ class AbstractClient(ABC):
|
|||||||
get_args = parsed_url.query
|
get_args = parsed_url.query
|
||||||
# Converting URL arguments to dict
|
# Converting URL arguments to dict
|
||||||
parsed_get_args = dict(parse_qsl(get_args))
|
parsed_get_args = dict(parse_qsl(get_args))
|
||||||
|
|
||||||
|
# we want all string values
|
||||||
|
parsed_params = {k: str(val) for k, val in params.items()}
|
||||||
|
|
||||||
if replace:
|
if replace:
|
||||||
# Merging URL arguments dict with new params
|
# Merging URL arguments dict with new params
|
||||||
parsed_get_args.update(params)
|
parsed_get_args.update(parsed_params)
|
||||||
extra_parameters = ""
|
extra_parameters = ""
|
||||||
else:
|
else:
|
||||||
# get all the duplicated keys from params and urlencode them, we'll concat this to the params string later
|
# get all the duplicated keys from params and urlencode them, we'll concat this to the params string later
|
||||||
@@ -311,7 +144,7 @@ class AbstractClient(ABC):
|
|||||||
# get all the args that aren't duplicated and add them to parsed_get_args
|
# get all the args that aren't duplicated and add them to parsed_get_args
|
||||||
parsed_get_args.update(
|
parsed_get_args.update(
|
||||||
{
|
{
|
||||||
key: params[key]
|
key: parsed_params[key]
|
||||||
for key in [x for x in params if x not in parsed_get_args]
|
for key in [x for x in params if x not in parsed_get_args]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -322,16 +155,6 @@ class AbstractClient(ABC):
|
|||||||
else ""
|
else ""
|
||||||
)
|
)
|
||||||
|
|
||||||
# Bool and Dict values should be converted to json-friendly values
|
|
||||||
# you may throw this part away if you don't like it :)
|
|
||||||
parsed_get_args.update(
|
|
||||||
{
|
|
||||||
k: dumps(v)
|
|
||||||
for k, v in parsed_get_args.items()
|
|
||||||
if isinstance(v, (bool, dict))
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Converting URL argument to proper query string
|
# Converting URL argument to proper query string
|
||||||
encoded_get_args = f"{urlencode(parsed_get_args, doseq=True)}{extra_parameters}"
|
encoded_get_args = f"{urlencode(parsed_get_args, doseq=True)}{extra_parameters}"
|
||||||
# Creating new parsed result object based on provided with new
|
# Creating new parsed result object based on provided with new
|
||||||
|
|||||||
@@ -19,33 +19,32 @@ class AsyncClient(AbstractClient):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
api_key: str,
|
api_key: str,
|
||||||
api_url: Optional[str] = "https://healthchecks.io/api/",
|
api_url: str = "https://healthchecks.io/api/",
|
||||||
api_version: Optional[int] = 1,
|
api_version: int = 1,
|
||||||
client: Optional[HTTPXAsyncClient] = None,
|
client: Optional[HTTPXAsyncClient] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""An AsyncClient can be used in code using asyncio to work with the Healthchecks.io api.
|
"""An AsyncClient can be used in code using asyncio to work with the Healthchecks.io api.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
api_key (str): Healthchecks.io API key
|
api_key (str): Healthchecks.io API key
|
||||||
api_url (Optional[str], optional): API URL. Defaults to "https://healthchecks.io/api/".
|
api_url (str): API URL. Defaults to "https://healthchecks.io/api/".
|
||||||
api_version (Optional[int], optional): Versiopn of the api to use. Defaults to 1.
|
api_version (int): Versiopn of the api to use. Defaults to 1.
|
||||||
client (Optional[HTTPXAsyncClient], optional): A httpx.Asyncclient. If not
|
client (Optional[HTTPXAsyncClient], optional): A httpx.Asyncclient. If not
|
||||||
passed in, one will be created for this object. Defaults to None.
|
passed in, one will be created for this object. Defaults to None.
|
||||||
"""
|
"""
|
||||||
if client is None:
|
self._client: HTTPXAsyncClient = (
|
||||||
client = HTTPXAsyncClient()
|
HTTPXAsyncClient() if client is None else client
|
||||||
super().__init__(
|
|
||||||
api_key=api_key, api_url=api_url, api_version=api_version, client=client
|
|
||||||
)
|
)
|
||||||
|
super().__init__(api_key=api_key, api_url=api_url, api_version=api_version)
|
||||||
self._client.headers["X-Api-Key"] = self._api_key
|
self._client.headers["X-Api-Key"] = self._api_key
|
||||||
self._client.headers["user-agent"] = f"py-healthchecks.io-async/{VERSION}"
|
self._client.headers["user-agent"] = f"py-healthchecks.io-async/{VERSION}"
|
||||||
self._client.headers["Content-type"] = "application/json"
|
self._client.headers["Content-type"] = "application/json"
|
||||||
|
|
||||||
def _finalizer_method(self):
|
def _finalizer_method(self) -> None:
|
||||||
"""Calls _afinalizer_method from a sync context to work with weakref.finalizer."""
|
"""Calls _afinalizer_method from a sync context to work with weakref.finalizer."""
|
||||||
asyncio.run(self._afinalizer_method())
|
asyncio.run(self._afinalizer_method())
|
||||||
|
|
||||||
async def _afinalizer_method(self):
|
async def _afinalizer_method(self) -> None:
|
||||||
"""Finalizer coroutine that closes our client connections."""
|
"""Finalizer coroutine that closes our client connections."""
|
||||||
await self._client.aclose()
|
await self._client.aclose()
|
||||||
|
|
||||||
@@ -250,7 +249,8 @@ class AsyncClient(AbstractClient):
|
|||||||
Dict[str, badges.Badges]: Dictionary of all tags in the project with badges
|
Dict[str, badges.Badges]: Dictionary of all tags in the project with badges
|
||||||
"""
|
"""
|
||||||
request_url = self._get_api_request_url("badges/")
|
request_url = self._get_api_request_url("badges/")
|
||||||
response = self.check_response(await self._client.get(request_url))
|
url = await self._client.get(request_url)
|
||||||
|
response = self.check_response(url)
|
||||||
return {
|
return {
|
||||||
key: badges.Badges.from_api_result(item)
|
key: badges.Badges.from_api_result(item)
|
||||||
for key, item in response.json()["badges"].items()
|
for key, item in response.json()["badges"].items()
|
||||||
|
|||||||
@@ -18,29 +18,26 @@ class Client(AbstractClient):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
api_key: str,
|
api_key: str,
|
||||||
api_url: Optional[str] = "https://healthchecks.io/api/",
|
api_url: str = "https://healthchecks.io/api/",
|
||||||
api_version: Optional[int] = 1,
|
api_version: int = 1,
|
||||||
client: Optional[HTTPXClient] = None,
|
client: Optional[HTTPXClient] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""An AsyncClient can be used in code using asyncio to work with the Healthchecks.io api.
|
"""An AsyncClient can be used in code using asyncio to work with the Healthchecks.io api.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
api_key (str): Healthchecks.io API key
|
api_key (str): Healthchecks.io API key
|
||||||
api_url (Optional[str], optional): API URL. Defaults to "https://healthchecks.io/api/".
|
api_url (str): API URL. Defaults to "https://healthchecks.io/api/".
|
||||||
api_version (Optional[int], optional): Versiopn of the api to use. Defaults to 1.
|
api_version (int): Versiopn of the api to use. Defaults to 1.
|
||||||
client (Optional[HTTPXClient], optional): A httpx.Client. If not
|
client (Optional[HTTPXClient], optional): A httpx.Client. If not
|
||||||
passed in, one will be created for this object. Defaults to None.
|
passed in, one will be created for this object. Defaults to None.
|
||||||
"""
|
"""
|
||||||
if client is None:
|
self._client: HTTPXClient = HTTPXClient() if client is None else client
|
||||||
client = HTTPXClient()
|
super().__init__(api_key=api_key, api_url=api_url, api_version=api_version)
|
||||||
super().__init__(
|
|
||||||
api_key=api_key, api_url=api_url, api_version=api_version, client=client
|
|
||||||
)
|
|
||||||
self._client.headers["X-Api-Key"] = self._api_key
|
self._client.headers["X-Api-Key"] = self._api_key
|
||||||
self._client.headers["user-agent"] = f"py-healthchecks.io/{VERSION}"
|
self._client.headers["user-agent"] = f"py-healthchecks.io/{VERSION}"
|
||||||
self._client.headers["Content-type"] = "application/json"
|
self._client.headers["Content-type"] = "application/json"
|
||||||
|
|
||||||
def _finalizer_method(self):
|
def _finalizer_method(self) -> None:
|
||||||
"""Closes the httpx client."""
|
"""Closes the httpx client."""
|
||||||
self._client.close()
|
self._client.close()
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from healthchecks_io.client.exceptions import HCAPIError
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.respx
|
@pytest.mark.respx
|
||||||
async def test_get_checks_200(fake_check_api_result, respx_mock, test_async_client):
|
async def test_aget_checks_200(fake_check_api_result, respx_mock, test_async_client):
|
||||||
assert test_async_client._client is not None
|
assert test_async_client._client is not None
|
||||||
checks_url = urljoin(test_async_client._api_url, "checks/")
|
checks_url = urljoin(test_async_client._api_url, "checks/")
|
||||||
respx_mock.get(checks_url).mock(
|
respx_mock.get(checks_url).mock(
|
||||||
@@ -27,7 +27,7 @@ async def test_get_checks_200(fake_check_api_result, respx_mock, test_async_clie
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.respx
|
@pytest.mark.respx
|
||||||
async def test_get_checks_pass_in_client(fake_check_api_result, respx_mock):
|
async def test_aget_checks_pass_in_client(fake_check_api_result, respx_mock):
|
||||||
httpx_client = HTTPXAsyncClient()
|
httpx_client = HTTPXAsyncClient()
|
||||||
test_async_client = AsyncClient(
|
test_async_client = AsyncClient(
|
||||||
api_key="test", api_url="http://localhost/api/", client=httpx_client
|
api_key="test", api_url="http://localhost/api/", client=httpx_client
|
||||||
@@ -43,7 +43,7 @@ async def test_get_checks_pass_in_client(fake_check_api_result, respx_mock):
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.respx
|
@pytest.mark.respx
|
||||||
async def test_get_checks_exceptions(
|
async def test_aget_checks_exceptions(
|
||||||
fake_check_api_result, respx_mock, test_async_client
|
fake_check_api_result, respx_mock, test_async_client
|
||||||
):
|
):
|
||||||
checks_url = urljoin(test_async_client._api_url, "checks/")
|
checks_url = urljoin(test_async_client._api_url, "checks/")
|
||||||
@@ -59,7 +59,7 @@ async def test_get_checks_exceptions(
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.respx
|
@pytest.mark.respx
|
||||||
async def test_get_checks_tags(fake_check_api_result, respx_mock, test_async_client):
|
async def test_aget_checks_tags(fake_check_api_result, respx_mock, test_async_client):
|
||||||
"""Test get_checks with tags"""
|
"""Test get_checks with tags"""
|
||||||
checks_url = urljoin(test_async_client._api_url, "checks/")
|
checks_url = urljoin(test_async_client._api_url, "checks/")
|
||||||
respx_mock.get(f"{checks_url}?tag=test&tag=test2").mock(
|
respx_mock.get(f"{checks_url}?tag=test&tag=test2").mock(
|
||||||
@@ -80,7 +80,7 @@ def test_finalizer_closes(test_async_client):
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.respx
|
@pytest.mark.respx
|
||||||
async def test_get_check_200(fake_check_api_result, respx_mock, test_async_client):
|
async def test_aget_check_200(fake_check_api_result, respx_mock, test_async_client):
|
||||||
assert test_async_client._client is not None
|
assert test_async_client._client is not None
|
||||||
checks_url = urljoin(test_async_client._api_url, "checks/test")
|
checks_url = urljoin(test_async_client._api_url, "checks/test")
|
||||||
respx_mock.get(checks_url).mock(
|
respx_mock.get(checks_url).mock(
|
||||||
@@ -92,7 +92,7 @@ async def test_get_check_200(fake_check_api_result, respx_mock, test_async_clien
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.respx
|
@pytest.mark.respx
|
||||||
async def test_check_get_404(respx_mock, test_async_client):
|
async def test_acheck_get_404(respx_mock, test_async_client):
|
||||||
assert test_async_client._client is not None
|
assert test_async_client._client is not None
|
||||||
checks_url = urljoin(test_async_client._api_url, "checks/test")
|
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))
|
||||||
@@ -113,7 +113,7 @@ async def test_pause_check_200(fake_check_api_result, respx_mock, test_async_cli
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.respx
|
@pytest.mark.respx
|
||||||
async def test_check_pause_404(respx_mock, test_async_client):
|
async def test_acheck_pause_404(respx_mock, test_async_client):
|
||||||
assert test_async_client._client is not None
|
assert test_async_client._client is not None
|
||||||
checks_url = urljoin(test_async_client._api_url, "checks/test/pause")
|
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))
|
||||||
@@ -123,7 +123,7 @@ async def test_check_pause_404(respx_mock, test_async_client):
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.respx
|
@pytest.mark.respx
|
||||||
async def test_delete_check_200(fake_check_api_result, respx_mock, test_async_client):
|
async def test_adelete_check_200(fake_check_api_result, respx_mock, test_async_client):
|
||||||
assert test_async_client._client is not None
|
assert test_async_client._client is not None
|
||||||
checks_url = urljoin(test_async_client._api_url, "checks/test")
|
checks_url = urljoin(test_async_client._api_url, "checks/test")
|
||||||
respx_mock.delete(checks_url).mock(
|
respx_mock.delete(checks_url).mock(
|
||||||
@@ -135,7 +135,7 @@ async def test_delete_check_200(fake_check_api_result, respx_mock, test_async_cl
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.respx
|
@pytest.mark.respx
|
||||||
async def test_delete_pause404(respx_mock, test_async_client):
|
async def test_adelete_pause404(respx_mock, test_async_client):
|
||||||
checks_url = urljoin(test_async_client._api_url, "checks/test")
|
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):
|
with pytest.raises(CheckNotFoundError):
|
||||||
@@ -144,7 +144,7 @@ async def test_delete_pause404(respx_mock, test_async_client):
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.respx
|
@pytest.mark.respx
|
||||||
async def test_get_check_pings_200(
|
async def test_aget_check_pings_200(
|
||||||
fake_check_pings_api_result, respx_mock, test_async_client
|
fake_check_pings_api_result, respx_mock, test_async_client
|
||||||
):
|
):
|
||||||
checks_url = urljoin(test_async_client._api_url, "checks/test/pings/")
|
checks_url = urljoin(test_async_client._api_url, "checks/test/pings/")
|
||||||
@@ -160,7 +160,7 @@ async def test_get_check_pings_200(
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.respx
|
@pytest.mark.respx
|
||||||
async def test_get_check_flips_200(
|
async def test_aget_check_flips_200(
|
||||||
fake_check_flips_api_result, respx_mock, test_async_client
|
fake_check_flips_api_result, respx_mock, test_async_client
|
||||||
):
|
):
|
||||||
checks_url = urljoin(test_async_client._api_url, "checks/test/flips/")
|
checks_url = urljoin(test_async_client._api_url, "checks/test/flips/")
|
||||||
@@ -190,7 +190,7 @@ async def test_get_check_flips_params_200(
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.respx
|
@pytest.mark.respx
|
||||||
async def test_get_check_flips_400(
|
async def test_aget_check_flips_400(
|
||||||
fake_check_flips_api_result, respx_mock, test_async_client
|
fake_check_flips_api_result, respx_mock, test_async_client
|
||||||
):
|
):
|
||||||
flips_url = urljoin(test_async_client._api_url, "checks/test/flips/")
|
flips_url = urljoin(test_async_client._api_url, "checks/test/flips/")
|
||||||
@@ -201,7 +201,7 @@ async def test_get_check_flips_400(
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.respx
|
@pytest.mark.respx
|
||||||
async def test_get_integrations(
|
async def test_aget_integrations(
|
||||||
fake_integrations_api_result, respx_mock, test_async_client
|
fake_integrations_api_result, respx_mock, test_async_client
|
||||||
):
|
):
|
||||||
channels_url = urljoin(test_async_client._api_url, "channels/")
|
channels_url = urljoin(test_async_client._api_url, "channels/")
|
||||||
@@ -215,7 +215,7 @@ async def test_get_integrations(
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.respx
|
@pytest.mark.respx
|
||||||
async def test_get_badges(fake_badges_api_result, respx_mock, test_async_client):
|
async def test_aget_badges(fake_badges_api_result, respx_mock, test_async_client):
|
||||||
channels_url = urljoin(test_async_client._api_url, "badges/")
|
channels_url = urljoin(test_async_client._api_url, "badges/")
|
||||||
respx_mock.get(channels_url).mock(
|
respx_mock.get(channels_url).mock(
|
||||||
return_value=Response(status_code=200, json=fake_badges_api_result)
|
return_value=Response(status_code=200, json=fake_badges_api_result)
|
||||||
|
|||||||
Reference in New Issue
Block a user