mirror of
https://github.com/andrewthetechie/py-healthchecks.io.git
synced 2025-12-06 09:38:33 +01:00
creates and updates and a start on docs
This commit is contained in:
@@ -1,3 +0,0 @@
|
|||||||
# py-healthchecks.io
|
|
||||||
|
|
||||||
A python client for healthchecks.io. Supports the management api and ping api
|
|
||||||
14
README.rst
14
README.rst
@@ -35,18 +35,22 @@ Py Healthchecks.Io
|
|||||||
:target: https://github.com/psf/black
|
:target: https://github.com/psf/black
|
||||||
:alt: Black
|
:alt: Black
|
||||||
|
|
||||||
A python client for healthchecks.io. Supports the management api and ping api
|
A python client for healthchecks.io. Supports the management api and ping api.
|
||||||
|
|
||||||
Features
|
Features
|
||||||
--------
|
--------
|
||||||
|
|
||||||
* TODO
|
* Sync and Async clients based on HTTPX
|
||||||
|
* Supports the management api and the ping api
|
||||||
|
* Supports Healthchecks.io SAAS and self-hosted instances
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
|
|
||||||
* TODO
|
* httpx
|
||||||
|
* pytz
|
||||||
|
* pydantic
|
||||||
|
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
@@ -62,7 +66,7 @@ You can install *Py Healthchecks.Io* via pip_ from PyPI_:
|
|||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
Please see the `Command-line Reference <Usage_>`_ for details.
|
Please see the `Usage <Usage_>`_ for details.
|
||||||
|
|
||||||
|
|
||||||
Contributing
|
Contributing
|
||||||
@@ -100,4 +104,4 @@ This project was generated from `@cjolowicz`_'s `Hypermodern Python Cookiecutter
|
|||||||
.. _pip: https://pip.pypa.io/
|
.. _pip: https://pip.pypa.io/
|
||||||
.. github-only
|
.. github-only
|
||||||
.. _Contributor Guide: CONTRIBUTING.rst
|
.. _Contributor Guide: CONTRIBUTING.rst
|
||||||
.. _Usage: https://py-healthchecks.io.readthedocs.io/en/latest/usage.html
|
.. _Usage: https://py-healthchecksio.readthedocs.io/en/latest/usage.html
|
||||||
|
|||||||
@@ -1,2 +1,4 @@
|
|||||||
Usage
|
Usage
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
After installation, you can import and instantiate a client and then use the
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ from .client.exceptions import HCAPIAuthError # noqa: F401, E402
|
|||||||
from .client.exceptions import HCAPIError # noqa: F401, E402
|
from .client.exceptions import HCAPIError # noqa: F401, E402
|
||||||
from .client.exceptions import HCAPIRateLimitError # noqa: F401, E402
|
from .client.exceptions import HCAPIRateLimitError # noqa: F401, E402
|
||||||
from .client.exceptions import NonUniqueSlugError # noqa: F401, E402
|
from .client.exceptions import NonUniqueSlugError # noqa: F401, E402
|
||||||
|
from .schemas import Check, CheckCreate, CheckPings, CheckStatuses # noqa: F401, E402
|
||||||
|
from .schemas import Integration, Badges, CheckUpdate # noqa: F401, E402
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"AsyncClient",
|
"AsyncClient",
|
||||||
@@ -20,4 +22,11 @@ __all__ = [
|
|||||||
"CheckNotFoundError",
|
"CheckNotFoundError",
|
||||||
"HCAPIRateLimitError",
|
"HCAPIRateLimitError",
|
||||||
"NonUniqueSlugError",
|
"NonUniqueSlugError",
|
||||||
|
"Check",
|
||||||
|
"CheckCreate",
|
||||||
|
"CheckUpdate",
|
||||||
|
"CheckPings",
|
||||||
|
"CheckStatuses",
|
||||||
|
"Integration",
|
||||||
|
"Badges",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -9,9 +9,12 @@ from httpx import AsyncClient as HTTPXAsyncClient
|
|||||||
|
|
||||||
from ._abstract import AbstractClient
|
from ._abstract import AbstractClient
|
||||||
from healthchecks_io import VERSION
|
from healthchecks_io import VERSION
|
||||||
from healthchecks_io.schemas import badges
|
from healthchecks_io.schemas import Badges
|
||||||
from healthchecks_io.schemas import checks
|
from healthchecks_io.schemas import Check
|
||||||
from healthchecks_io.schemas import integrations
|
from healthchecks_io.schemas import CheckCreate
|
||||||
|
from healthchecks_io.schemas import CheckPings
|
||||||
|
from healthchecks_io.schemas import CheckStatuses
|
||||||
|
from healthchecks_io.schemas import Integration
|
||||||
|
|
||||||
|
|
||||||
class AsyncClient(AbstractClient):
|
class AsyncClient(AbstractClient):
|
||||||
@@ -59,7 +62,47 @@ class AsyncClient(AbstractClient):
|
|||||||
"""Finalizer coroutine that closes our client connections."""
|
"""Finalizer coroutine that closes our client connections."""
|
||||||
await self._client.aclose()
|
await self._client.aclose()
|
||||||
|
|
||||||
async def get_checks(self, tags: Optional[List[str]] = None) -> List[checks.Check]:
|
async def create_check(self, new_check: CheckCreate) -> Check:
|
||||||
|
"""Creates a new check and returns it.
|
||||||
|
|
||||||
|
With this API call, you can create both Simple and Cron checks:
|
||||||
|
* To create a Simple check, specify the timeout parameter.
|
||||||
|
* To create a Cron check, specify the schedule and tz parameters.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
new_check (CheckCreate): New check you are wanting to create
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Check: check that was just created
|
||||||
|
"""
|
||||||
|
request_url = self._get_api_request_url("checks/")
|
||||||
|
response = self.check_response(
|
||||||
|
await self._client.post(request_url, json=new_check.dict())
|
||||||
|
)
|
||||||
|
return Check.from_api_result(response.json())
|
||||||
|
|
||||||
|
async def update_check(self, uuid: str, update_check: CheckCreate) -> Check:
|
||||||
|
"""Updates an existing check.
|
||||||
|
|
||||||
|
If you omit any parameter in update_check, Healthchecks.io will leave
|
||||||
|
its value unchanged.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
uuid (str): UUID for the check to update
|
||||||
|
update_check (CheckCreate): Check values you want to update
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Check: check that was just updated
|
||||||
|
"""
|
||||||
|
request_url = self._get_api_request_url(f"checks/{uuid}")
|
||||||
|
response = self.check_response(
|
||||||
|
await self._client.post(
|
||||||
|
request_url, json=update_check.dict(exclude_unset=True)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return Check.from_api_result(response.json())
|
||||||
|
|
||||||
|
async def get_checks(self, tags: Optional[List[str]] = None) -> List[Check]:
|
||||||
"""Get a list of checks from the healthchecks api.
|
"""Get a list of checks from the healthchecks api.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -73,7 +116,7 @@ class AsyncClient(AbstractClient):
|
|||||||
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[checks.Check]: [description]
|
List[Check]: [description]
|
||||||
"""
|
"""
|
||||||
request_url = self._get_api_request_url("checks/")
|
request_url = self._get_api_request_url("checks/")
|
||||||
if tags is not None:
|
if tags is not None:
|
||||||
@@ -85,11 +128,11 @@ class AsyncClient(AbstractClient):
|
|||||||
response = self.check_response(await self._client.get(request_url))
|
response = self.check_response(await self._client.get(request_url))
|
||||||
|
|
||||||
return [
|
return [
|
||||||
checks.Check.from_api_result(check_data)
|
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:
|
async def get_check(self, check_id: str) -> 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
|
check_id can either be a check uuid if using a read/write api key
|
||||||
@@ -99,7 +142,7 @@ class AsyncClient(AbstractClient):
|
|||||||
check_id (str): check's uuid or unique id
|
check_id (str): check's uuid or unique id
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
checks.Check: the check
|
Check: the check
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
HCAPIAuthError: Raised when status_code == 401 or 403
|
HCAPIAuthError: Raised when status_code == 401 or 403
|
||||||
@@ -111,9 +154,9 @@ class AsyncClient(AbstractClient):
|
|||||||
"""
|
"""
|
||||||
request_url = self._get_api_request_url(f"checks/{check_id}")
|
request_url = self._get_api_request_url(f"checks/{check_id}")
|
||||||
response = self.check_response(await self._client.get(request_url))
|
response = self.check_response(await self._client.get(request_url))
|
||||||
return checks.Check.from_api_result(response.json())
|
return Check.from_api_result(response.json())
|
||||||
|
|
||||||
async def pause_check(self, check_id: str) -> checks.Check:
|
async def pause_check(self, check_id: str) -> Check:
|
||||||
"""Disables monitoring for a check without removing it.
|
"""Disables monitoring for a check without removing it.
|
||||||
|
|
||||||
The check goes into a "paused" state.
|
The check goes into a "paused" state.
|
||||||
@@ -125,7 +168,7 @@ class AsyncClient(AbstractClient):
|
|||||||
check_id (str): check's uuid
|
check_id (str): check's uuid
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
checks.Check: the check just paused
|
Check: the check just paused
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
HCAPIAuthError: Raised when status_code == 401 or 403
|
HCAPIAuthError: Raised when status_code == 401 or 403
|
||||||
@@ -135,9 +178,9 @@ class AsyncClient(AbstractClient):
|
|||||||
"""
|
"""
|
||||||
request_url = self._get_api_request_url(f"checks/{check_id}/pause")
|
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())
|
return Check.from_api_result(response.json())
|
||||||
|
|
||||||
async def delete_check(self, check_id: str) -> checks.Check:
|
async def delete_check(self, check_id: str) -> 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
|
check_id must be a uuid, not a unique id
|
||||||
@@ -146,7 +189,7 @@ class AsyncClient(AbstractClient):
|
|||||||
check_id (str): check's uuid
|
check_id (str): check's uuid
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
checks.Check: the check just deleted
|
Check: the check just deleted
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
HCAPIAuthError: Raised when status_code == 401 or 403
|
HCAPIAuthError: Raised when status_code == 401 or 403
|
||||||
@@ -157,9 +200,9 @@ class AsyncClient(AbstractClient):
|
|||||||
"""
|
"""
|
||||||
request_url = self._get_api_request_url(f"checks/{check_id}")
|
request_url = self._get_api_request_url(f"checks/{check_id}")
|
||||||
response = self.check_response(await self._client.delete(request_url))
|
response = self.check_response(await self._client.delete(request_url))
|
||||||
return checks.Check.from_api_result(response.json())
|
return Check.from_api_result(response.json())
|
||||||
|
|
||||||
async def get_check_pings(self, check_id: str) -> List[checks.CheckPings]:
|
async def get_check_pings(self, check_id: str) -> List[CheckPings]:
|
||||||
"""Returns a list of pings this check has received.
|
"""Returns a list of pings this check has received.
|
||||||
|
|
||||||
This endpoint returns pings in reverse order (most recent first),
|
This endpoint returns pings in reverse order (most recent first),
|
||||||
@@ -170,7 +213,7 @@ class AsyncClient(AbstractClient):
|
|||||||
check_id (str): check's uuid
|
check_id (str): check's uuid
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[checks.CheckPings]: list of pings this check has received
|
List[CheckPings]: list of pings this check has received
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
HCAPIAuthError: Raised when status_code == 401 or 403
|
HCAPIAuthError: Raised when status_code == 401 or 403
|
||||||
@@ -183,7 +226,7 @@ class AsyncClient(AbstractClient):
|
|||||||
request_url = self._get_api_request_url(f"checks/{check_id}/pings/")
|
request_url = self._get_api_request_url(f"checks/{check_id}/pings/")
|
||||||
response = self.check_response(await self._client.get(request_url))
|
response = self.check_response(await self._client.get(request_url))
|
||||||
return [
|
return [
|
||||||
checks.CheckPings.from_api_result(check_data)
|
CheckPings.from_api_result(check_data)
|
||||||
for check_data in response.json()["pings"]
|
for check_data in response.json()["pings"]
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -193,7 +236,7 @@ class AsyncClient(AbstractClient):
|
|||||||
seconds: Optional[int] = None,
|
seconds: Optional[int] = None,
|
||||||
start: Optional[int] = None,
|
start: Optional[int] = None,
|
||||||
end: Optional[int] = None,
|
end: Optional[int] = None,
|
||||||
) -> List[checks.CheckStatuses]:
|
) -> List[CheckStatuses]:
|
||||||
"""Returns a list of "flips" this check has experienced.
|
"""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").
|
A flip is a change of status (from "down" to "up," or from "up" to "down").
|
||||||
@@ -213,7 +256,7 @@ class AsyncClient(AbstractClient):
|
|||||||
end (Optional[int], optional): Returns flips that are older 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:
|
Returns:
|
||||||
List[checks.CheckStatuses]: List of status flips for this check
|
List[CheckStatuses]: List of status flips for this check
|
||||||
|
|
||||||
"""
|
"""
|
||||||
params = dict()
|
params = dict()
|
||||||
@@ -226,9 +269,9 @@ class AsyncClient(AbstractClient):
|
|||||||
|
|
||||||
request_url = self._get_api_request_url(f"checks/{check_id}/flips/", params)
|
request_url = self._get_api_request_url(f"checks/{check_id}/flips/", params)
|
||||||
response = self.check_response(await self._client.get(request_url))
|
response = self.check_response(await self._client.get(request_url))
|
||||||
return [checks.CheckStatuses(**status_data) for status_data in response.json()]
|
return [CheckStatuses(**status_data) for status_data in response.json()]
|
||||||
|
|
||||||
async def get_integrations(self) -> List[Optional[integrations.Integration]]:
|
async def get_integrations(self) -> List[Optional[Integration]]:
|
||||||
"""Returns a list of integrations belonging to the project.
|
"""Returns a list of integrations belonging to the project.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
@@ -237,17 +280,17 @@ class AsyncClient(AbstractClient):
|
|||||||
HCAPIRateLimitError: Raised when status code is 429
|
HCAPIRateLimitError: Raised when status code is 429
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[Optional[integrations.Integration]]: List of integrations for the project
|
List[Optional[Integration]]: List of integrations for the project
|
||||||
|
|
||||||
"""
|
"""
|
||||||
request_url = self._get_api_request_url("channels/")
|
request_url = self._get_api_request_url("channels/")
|
||||||
response = self.check_response(await self._client.get(request_url))
|
response = self.check_response(await self._client.get(request_url))
|
||||||
return [
|
return [
|
||||||
integrations.Integration.from_api_result(integration_dict)
|
Integration.from_api_result(integration_dict)
|
||||||
for integration_dict in response.json()["channels"]
|
for integration_dict in response.json()["channels"]
|
||||||
]
|
]
|
||||||
|
|
||||||
async def get_badges(self) -> Dict[str, badges.Badges]:
|
async def get_badges(self) -> Dict[str, Badges]:
|
||||||
"""Returns a dict of all tags in the project, with badge URLs for each tag.
|
"""Returns a dict of all tags in the project, with badge URLs for each tag.
|
||||||
|
|
||||||
Healthchecks.io provides badges in a few different formats:
|
Healthchecks.io provides badges in a few different formats:
|
||||||
@@ -268,12 +311,12 @@ class AsyncClient(AbstractClient):
|
|||||||
HCAPIRateLimitError: Raised when status code is 429
|
HCAPIRateLimitError: Raised when status code is 429
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Dict[str, badges.Badges]: Dictionary of all tags in the project with badges
|
Dict[str, 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))
|
response = self.check_response(await self._client.get(request_url))
|
||||||
return {
|
return {
|
||||||
key: badges.Badges.from_api_result(item)
|
key: Badges.from_api_result(item)
|
||||||
for key, item in response.json()["badges"].items()
|
for key, item in response.json()["badges"].items()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ from httpx import Client as HTTPXClient
|
|||||||
from ._abstract import AbstractClient
|
from ._abstract import AbstractClient
|
||||||
from healthchecks_io import VERSION
|
from healthchecks_io import VERSION
|
||||||
from healthchecks_io.schemas import badges
|
from healthchecks_io.schemas import badges
|
||||||
|
from healthchecks_io.schemas import Check
|
||||||
|
from healthchecks_io.schemas import CheckCreate
|
||||||
from healthchecks_io.schemas import checks
|
from healthchecks_io.schemas import checks
|
||||||
from healthchecks_io.schemas import integrations
|
from healthchecks_io.schemas import integrations
|
||||||
|
|
||||||
@@ -102,6 +104,50 @@ class Client(AbstractClient):
|
|||||||
response = self.check_response(self._client.get(request_url))
|
response = self.check_response(self._client.get(request_url))
|
||||||
return checks.Check.from_api_result(response.json())
|
return checks.Check.from_api_result(response.json())
|
||||||
|
|
||||||
|
def create_check(self, new_check: CheckCreate) -> Check:
|
||||||
|
"""Creates a new check and returns it.
|
||||||
|
|
||||||
|
With this API call, you can create both Simple and Cron checks:
|
||||||
|
* To create a Simple check, specify the timeout parameter.
|
||||||
|
* To create a Cron check, specify the schedule and tz parameters.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
new_check (CheckCreate): New check you are wanting to create
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Check: check that was just created
|
||||||
|
"""
|
||||||
|
request_url = self._get_api_request_url("checks/")
|
||||||
|
response = self.check_response(
|
||||||
|
self._client.post(request_url, json=new_check.dict())
|
||||||
|
)
|
||||||
|
return Check.from_api_result(response.json())
|
||||||
|
|
||||||
|
def update_check(self, uuid: str, update_check: CheckCreate) -> Check:
|
||||||
|
"""Updates an existing check.
|
||||||
|
|
||||||
|
If you omit any parameter in update_check, Healthchecks.io will leave
|
||||||
|
its value unchanged.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
With this API call, you can create both Simple and Cron checks:
|
||||||
|
* To create a Simple check, specify the timeout parameter.
|
||||||
|
* To create a Cron check, specify the schedule and tz parameters.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
uuid (str): UUID for the check to update
|
||||||
|
update_check (CheckCreate): Check values you want to update
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Check: check that was just updated
|
||||||
|
"""
|
||||||
|
request_url = self._get_api_request_url(f"checks/{uuid}")
|
||||||
|
response = self.check_response(
|
||||||
|
self._client.post(request_url, json=update_check.dict(exclude_unset=True))
|
||||||
|
)
|
||||||
|
return Check.from_api_result(response.json())
|
||||||
|
|
||||||
def pause_check(self, check_id: str) -> checks.Check:
|
def pause_check(self, check_id: str) -> checks.Check:
|
||||||
"""Disables monitoring for a check without removing it.
|
"""Disables monitoring for a check without removing it.
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,18 @@
|
|||||||
"""Schemas for healthchecks_io."""
|
"""Schemas for healthchecks_io."""
|
||||||
|
from .badges import Badges
|
||||||
|
from .checks import Check
|
||||||
|
from .checks import CheckCreate
|
||||||
|
from .checks import CheckPings
|
||||||
|
from .checks import CheckStatuses
|
||||||
|
from .checks import CheckUpdate
|
||||||
|
from .integrations import Integration
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Check",
|
||||||
|
"CheckCreate",
|
||||||
|
"CheckPings",
|
||||||
|
"CheckUpdate",
|
||||||
|
"CheckStatuses",
|
||||||
|
"Badges",
|
||||||
|
"Integration",
|
||||||
|
]
|
||||||
|
|||||||
@@ -163,6 +163,73 @@ class CheckCreate(BaseModel):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
class CheckUpdate(CheckCreate):
|
||||||
|
"""Pydantic object for updating a check."""
|
||||||
|
|
||||||
|
name: Optional[str] = Field(None, description="Name of the check")
|
||||||
|
tags: Optional[str] = Field(
|
||||||
|
None, description="String separated list of tags to apply"
|
||||||
|
)
|
||||||
|
timeout: Optional[int] = Field(
|
||||||
|
None,
|
||||||
|
description="The expected period of this check in seconds.",
|
||||||
|
gte=60,
|
||||||
|
lte=31536000,
|
||||||
|
)
|
||||||
|
grace: Optional[int] = Field(
|
||||||
|
None,
|
||||||
|
description="The grace period for this check in seconds.",
|
||||||
|
gte=60,
|
||||||
|
lte=31536000,
|
||||||
|
)
|
||||||
|
schedule: Optional[str] = Field(
|
||||||
|
None,
|
||||||
|
description="A cron expression defining this check's schedule. "
|
||||||
|
"If you specify both timeout and schedule parameters, "
|
||||||
|
"Healthchecks.io will create a Cron check and ignore the "
|
||||||
|
"timeout value.",
|
||||||
|
)
|
||||||
|
tz: Optional[str] = Field(
|
||||||
|
None,
|
||||||
|
description="Server's timezone. This setting only has an effect "
|
||||||
|
"in combination with the schedule parameter.",
|
||||||
|
)
|
||||||
|
manual_resume: Optional[bool] = Field(
|
||||||
|
None,
|
||||||
|
description="Controls whether a paused check automatically resumes "
|
||||||
|
"when pinged (the default) or not. If set to false, a paused "
|
||||||
|
"check will leave the paused state when it receives a ping. "
|
||||||
|
"If set to true, a paused check will ignore pings and stay "
|
||||||
|
"paused until you manually resume it from the web dashboard.",
|
||||||
|
)
|
||||||
|
methods: Optional[str] = Field(
|
||||||
|
None,
|
||||||
|
description="Specifies the allowed HTTP methods for making "
|
||||||
|
"ping requests. Must be one of the two values: an empty "
|
||||||
|
"string or POST. Set this field to an empty string to "
|
||||||
|
"allow HEAD, GET, and POST requests. Set this field to "
|
||||||
|
"POST to allow only POST requests.",
|
||||||
|
)
|
||||||
|
channels: Optional[str] = Field(
|
||||||
|
None,
|
||||||
|
description="By default, this API call assigns no integrations"
|
||||||
|
"to the newly created check. By default, this API call "
|
||||||
|
"assigns no integrations to the newly created check. "
|
||||||
|
"To assign specific integrations, use a comma-separated list "
|
||||||
|
"of integration UUIDs.",
|
||||||
|
)
|
||||||
|
unique: Optional[List[Optional[str]]] = Field(
|
||||||
|
None,
|
||||||
|
description="Enables upsert functionality. Before creating a check, "
|
||||||
|
"Healthchecks.io looks for existing checks, filtered by fields listed "
|
||||||
|
"in unique. If Healthchecks.io does not find a matching check, it "
|
||||||
|
"creates a new check and returns it with the HTTP status code 201 "
|
||||||
|
"If Healthchecks.io finds a matching check, it updates the existing "
|
||||||
|
"check and returns it with HTTP status code 200. The accepted values "
|
||||||
|
"for the unique field are name, tags, timeout, and grace.",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CheckPings(BaseModel):
|
class CheckPings(BaseModel):
|
||||||
"""A Pydantic schema for a check's Pings."""
|
"""A Pydantic schema for a check's Pings."""
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import respx
|
|||||||
from httpx import AsyncClient as HTTPXAsyncClient
|
from httpx import AsyncClient as HTTPXAsyncClient
|
||||||
from httpx import Response
|
from httpx import Response
|
||||||
|
|
||||||
|
from healthchecks_io import CheckCreate
|
||||||
|
from healthchecks_io import CheckUpdate
|
||||||
from healthchecks_io.client import AsyncClient
|
from healthchecks_io.client import AsyncClient
|
||||||
from healthchecks_io.client.exceptions import BadAPIRequestError
|
from healthchecks_io.client.exceptions import BadAPIRequestError
|
||||||
from healthchecks_io.client.exceptions import CheckNotFoundError
|
from healthchecks_io.client.exceptions import CheckNotFoundError
|
||||||
@@ -12,6 +14,72 @@ from healthchecks_io.client.exceptions import HCAPIAuthError
|
|||||||
from healthchecks_io.client.exceptions import HCAPIError
|
from healthchecks_io.client.exceptions import HCAPIError
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
@pytest.mark.respx
|
||||||
|
async def test_acreate_check_200(fake_check_api_result, respx_mock, test_async_client):
|
||||||
|
checks_url = urljoin(test_async_client._api_url, "checks/")
|
||||||
|
respx_mock.post(checks_url).mock(
|
||||||
|
return_value=Response(
|
||||||
|
status_code=200,
|
||||||
|
json={
|
||||||
|
"channels": "",
|
||||||
|
"desc": "",
|
||||||
|
"grace": 60,
|
||||||
|
"last_ping": None,
|
||||||
|
"n_pings": 0,
|
||||||
|
"name": "Backups",
|
||||||
|
"slug": "backups",
|
||||||
|
"next_ping": None,
|
||||||
|
"manual_resume": False,
|
||||||
|
"methods": "",
|
||||||
|
"pause_url": "https://healthchecks.io/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/pause",
|
||||||
|
"ping_url": "https://hc-ping.com/f618072a-7bde-4eee-af63-71a77c5723bc",
|
||||||
|
"status": "new",
|
||||||
|
"tags": "prod www",
|
||||||
|
"timeout": 3600,
|
||||||
|
"update_url": "https://healthchecks.io/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
check = await test_async_client.create_check(
|
||||||
|
CheckCreate(name="test", tags="test", desc="test")
|
||||||
|
)
|
||||||
|
assert check.name == "Backups"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
@pytest.mark.respx
|
||||||
|
async def test_aupdate_check_200(fake_check_api_result, respx_mock, test_async_client):
|
||||||
|
checks_url = urljoin(test_async_client._api_url, "checks/test")
|
||||||
|
respx_mock.post(checks_url).mock(
|
||||||
|
return_value=Response(
|
||||||
|
status_code=200,
|
||||||
|
json={
|
||||||
|
"channels": "",
|
||||||
|
"desc": "",
|
||||||
|
"grace": 60,
|
||||||
|
"last_ping": None,
|
||||||
|
"n_pings": 0,
|
||||||
|
"name": "Backups",
|
||||||
|
"slug": "backups",
|
||||||
|
"next_ping": None,
|
||||||
|
"manual_resume": False,
|
||||||
|
"methods": "",
|
||||||
|
"pause_url": "https://healthchecks.io/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/pause",
|
||||||
|
"ping_url": "https://hc-ping.com/f618072a-7bde-4eee-af63-71a77c5723bc",
|
||||||
|
"status": "new",
|
||||||
|
"tags": "prod www",
|
||||||
|
"timeout": 3600,
|
||||||
|
"update_url": "https://healthchecks.io/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
check = await test_async_client.update_check(
|
||||||
|
"test", CheckUpdate(name="test", desc="test")
|
||||||
|
)
|
||||||
|
assert check.name == "Backups"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.respx
|
@pytest.mark.respx
|
||||||
async def test_aget_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):
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import respx
|
|||||||
from httpx import Client as HTTPXClient
|
from httpx import Client as HTTPXClient
|
||||||
from httpx import Response
|
from httpx import Response
|
||||||
|
|
||||||
|
from healthchecks_io import CheckCreate
|
||||||
|
from healthchecks_io import CheckUpdate
|
||||||
from healthchecks_io import Client
|
from healthchecks_io import Client
|
||||||
from healthchecks_io.client.exceptions import BadAPIRequestError
|
from healthchecks_io.client.exceptions import BadAPIRequestError
|
||||||
from healthchecks_io.client.exceptions import CheckNotFoundError
|
from healthchecks_io.client.exceptions import CheckNotFoundError
|
||||||
@@ -12,6 +14,66 @@ from healthchecks_io.client.exceptions import HCAPIAuthError
|
|||||||
from healthchecks_io.client.exceptions import HCAPIError
|
from healthchecks_io.client.exceptions import HCAPIError
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.respx
|
||||||
|
def test_create_check_200(fake_check_api_result, respx_mock, test_client):
|
||||||
|
checks_url = urljoin(test_client._api_url, "checks/")
|
||||||
|
respx_mock.post(checks_url).mock(
|
||||||
|
return_value=Response(
|
||||||
|
status_code=200,
|
||||||
|
json={
|
||||||
|
"channels": "",
|
||||||
|
"desc": "",
|
||||||
|
"grace": 60,
|
||||||
|
"last_ping": None,
|
||||||
|
"n_pings": 0,
|
||||||
|
"name": "Backups",
|
||||||
|
"slug": "backups",
|
||||||
|
"next_ping": None,
|
||||||
|
"manual_resume": False,
|
||||||
|
"methods": "",
|
||||||
|
"pause_url": "https://healthchecks.io/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/pause",
|
||||||
|
"ping_url": "https://hc-ping.com/f618072a-7bde-4eee-af63-71a77c5723bc",
|
||||||
|
"status": "new",
|
||||||
|
"tags": "prod www",
|
||||||
|
"timeout": 3600,
|
||||||
|
"update_url": "https://healthchecks.io/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
check = test_client.create_check(CheckCreate(name="test", tags="test", desc="test"))
|
||||||
|
assert check.name == "Backups"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.respx
|
||||||
|
def test_update_check_200(fake_check_api_result, respx_mock, test_client):
|
||||||
|
checks_url = urljoin(test_client._api_url, "checks/test")
|
||||||
|
respx_mock.post(checks_url).mock(
|
||||||
|
return_value=Response(
|
||||||
|
status_code=200,
|
||||||
|
json={
|
||||||
|
"channels": "",
|
||||||
|
"desc": "",
|
||||||
|
"grace": 60,
|
||||||
|
"last_ping": None,
|
||||||
|
"n_pings": 0,
|
||||||
|
"name": "Backups",
|
||||||
|
"slug": "backups",
|
||||||
|
"next_ping": None,
|
||||||
|
"manual_resume": False,
|
||||||
|
"methods": "",
|
||||||
|
"pause_url": "https://healthchecks.io/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/pause",
|
||||||
|
"ping_url": "https://hc-ping.com/f618072a-7bde-4eee-af63-71a77c5723bc",
|
||||||
|
"status": "new",
|
||||||
|
"tags": "prod www",
|
||||||
|
"timeout": 3600,
|
||||||
|
"update_url": "https://healthchecks.io/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
check = test_client.update_check("test", CheckUpdate(name="test", desc="test"))
|
||||||
|
assert check.name == "Backups"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.respx
|
@pytest.mark.respx
|
||||||
def test_get_checks_200(fake_check_api_result, respx_mock, test_client):
|
def test_get_checks_200(fake_check_api_result, respx_mock, test_client):
|
||||||
assert test_client._client is not None
|
assert test_client._client is not None
|
||||||
|
|||||||
Reference in New Issue
Block a user