Fix memory leak #29
9 changed files with 117 additions and 40 deletions
23
README.md
23
README.md
|
@ -8,7 +8,12 @@ This package was developed to configure Uptime Kuma with Ansible. The Ansible co
|
||||||
|
|
||||||
Python version 3.7+ is required.
|
Python version 3.7+ is required.
|
||||||
|
|
||||||
Supported Uptime Kuma versions: 1.17.0 - 1.21.2
|
Supported Uptime Kuma versions:
|
||||||
|
|
||||||
|
| uptime-kuma-api | Uptime Kuma |
|
||||||
|
|-----------------|-----------------|
|
||||||
|
| 1.0.0 | 1.21.3 |
|
||||||
|
| 0.1.0 - 0.13.0 | 1.17.0 - 1.21.2 |
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
---
|
---
|
||||||
|
@ -24,7 +29,7 @@ Documentation
|
||||||
---
|
---
|
||||||
The API Reference is available on [Read the Docs](https://uptime-kuma-api.readthedocs.io).
|
The API Reference is available on [Read the Docs](https://uptime-kuma-api.readthedocs.io).
|
||||||
|
|
||||||
Examples
|
Example
|
||||||
---
|
---
|
||||||
Once you have installed the python package, you can use it to communicate with an Uptime Kuma instance.
|
Once you have installed the python package, you can use it to communicate with an Uptime Kuma instance.
|
||||||
|
|
||||||
|
@ -49,3 +54,17 @@ At the end, the connection to the API must be disconnected so that the program d
|
||||||
```python
|
```python
|
||||||
>>> api.disconnect()
|
>>> api.disconnect()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
With a context manager, the disconnect method is called automatically:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from uptime_kuma_api import UptimeKumaApi
|
||||||
|
|
||||||
|
with UptimeKumaApi('INSERT_URL') as api:
|
||||||
|
api.login('INSERT_USERNAME', 'INSERT_PASSWORD')
|
||||||
|
api.add_monitor(
|
||||||
|
type=MonitorType.HTTP,
|
||||||
|
name="Google",
|
||||||
|
url="https://google.com"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
|
@ -39,3 +39,5 @@ Exceptions
|
||||||
----------
|
----------
|
||||||
|
|
||||||
.. autoexception:: UptimeKumaException
|
.. autoexception:: UptimeKumaException
|
||||||
|
|
||||||
|
.. autoexception:: Timeout
|
||||||
|
|
|
@ -5,7 +5,7 @@ if [ $version ]
|
||||||
then
|
then
|
||||||
versions=("$version")
|
versions=("$version")
|
||||||
else
|
else
|
||||||
versions=(1.21.2 1.21.1 1.20.2 1.19.6 1.18.5 1.17.1)
|
versions=(1.21.3)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for version in ${versions[*]}
|
for version in ${versions[*]}
|
||||||
|
|
3
setup.py
3
setup.py
|
@ -29,7 +29,7 @@ setup(
|
||||||
author_email="lucasheld@hotmail.de",
|
author_email="lucasheld@hotmail.de",
|
||||||
license=info["__license__"],
|
license=info["__license__"],
|
||||||
packages=["uptime_kuma_api"],
|
packages=["uptime_kuma_api"],
|
||||||
python_requires=">=3.6, <4",
|
python_requires=">=3.7, <4",
|
||||||
install_requires=[
|
install_requires=[
|
||||||
"python-socketio[client]>=5.0.0",
|
"python-socketio[client]>=5.0.0",
|
||||||
"packaging"
|
"packaging"
|
||||||
|
@ -43,7 +43,6 @@ setup(
|
||||||
"Operating System :: OS Independent",
|
"Operating System :: OS Independent",
|
||||||
"Programming Language :: Python",
|
"Programming Language :: Python",
|
||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
"Programming Language :: Python :: 3.6",
|
|
||||||
"Programming Language :: Python :: 3.7",
|
"Programming Language :: Python :: 3.7",
|
||||||
"Programming Language :: Python :: 3.8",
|
"Programming Language :: Python :: 3.8",
|
||||||
"Programming Language :: Python :: 3.9",
|
"Programming Language :: Python :: 3.9",
|
||||||
|
|
|
@ -30,7 +30,7 @@ class TestMaintenance(UptimeKumaTestCase):
|
||||||
|
|
||||||
if parse_version(self.api.version) >= parse_version("1.21.2"):
|
if parse_version(self.api.version) >= parse_version("1.21.2"):
|
||||||
expected_maintenance.update({
|
expected_maintenance.update({
|
||||||
"timezone": "Europe/Berlin"
|
"timezoneOption": "Europe/Berlin"
|
||||||
})
|
})
|
||||||
|
|
||||||
# add maintenance
|
# add maintenance
|
||||||
|
@ -242,7 +242,7 @@ class TestMaintenance(UptimeKumaTestCase):
|
||||||
"daysOfMonth": [],
|
"daysOfMonth": [],
|
||||||
"cron": "50 5 * * *",
|
"cron": "50 5 * * *",
|
||||||
"durationMinutes": 120,
|
"durationMinutes": 120,
|
||||||
"timezone": "Europe/Berlin"
|
"timezoneOption": "Europe/Berlin"
|
||||||
}
|
}
|
||||||
self.do_test_maintenance_strategy(expected_maintenance)
|
self.do_test_maintenance_strategy(expected_maintenance)
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
from .__version__ import __title__, __version__, __author__, __copyright__
|
from .__version__ import __title__, __version__, __author__, __copyright__
|
||||||
from .auth_method import AuthMethod
|
from .auth_method import AuthMethod
|
||||||
|
from .monitor_status import MonitorStatus
|
||||||
from .monitor_type import MonitorType
|
from .monitor_type import MonitorType
|
||||||
from .notification_providers import NotificationType, notification_provider_options, notification_provider_conditions
|
from .notification_providers import NotificationType, notification_provider_options, notification_provider_conditions
|
||||||
from .proxy_protocol import ProxyProtocol
|
from .proxy_protocol import ProxyProtocol
|
||||||
from .incident_style import IncidentStyle
|
from .incident_style import IncidentStyle
|
||||||
from .docker_type import DockerType
|
from .docker_type import DockerType
|
||||||
from .maintenance_strategy import MaintenanceStrategy
|
from .maintenance_strategy import MaintenanceStrategy
|
||||||
from .exceptions import UptimeKumaException
|
from .exceptions import UptimeKumaException, Timeout
|
||||||
from .event import Event
|
from .event import Event
|
||||||
from .api import UptimeKumaApi
|
from .api import UptimeKumaApi
|
||||||
|
|
|
@ -18,9 +18,11 @@ from . import (AuthMethod,
|
||||||
Event,
|
Event,
|
||||||
IncidentStyle,
|
IncidentStyle,
|
||||||
MaintenanceStrategy,
|
MaintenanceStrategy,
|
||||||
|
MonitorStatus,
|
||||||
MonitorType,
|
MonitorType,
|
||||||
NotificationType,
|
NotificationType,
|
||||||
ProxyProtocol,
|
ProxyProtocol,
|
||||||
|
Timeout,
|
||||||
UptimeKumaException,
|
UptimeKumaException,
|
||||||
notification_provider_conditions,
|
notification_provider_conditions,
|
||||||
notification_provider_options)
|
notification_provider_options)
|
||||||
|
@ -33,6 +35,7 @@ from .docstrings import (append_docstring,
|
||||||
proxy_docstring,
|
proxy_docstring,
|
||||||
tag_docstring)
|
tag_docstring)
|
||||||
|
|
||||||
|
|
||||||
def int_to_bool(data, keys) -> None:
|
def int_to_bool(data, keys) -> None:
|
||||||
if isinstance(data, list):
|
if isinstance(data, list):
|
||||||
for d in data:
|
for d in data:
|
||||||
|
@ -43,6 +46,20 @@ def int_to_bool(data, keys) -> None:
|
||||||
data[key] = True if data[key] == 1 else False
|
data[key] = True if data[key] == 1 else False
|
||||||
|
|
||||||
|
|
||||||
|
def parse_value(data, func) -> None:
|
||||||
|
if isinstance(data, list):
|
||||||
|
for d in data:
|
||||||
|
parse_value(d, func)
|
||||||
|
else:
|
||||||
|
func(data)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_monitor_status(data) -> None:
|
||||||
|
def parse(x):
|
||||||
|
x["status"] = MonitorStatus(x["status"])
|
||||||
|
parse_value(data, parse)
|
||||||
|
|
||||||
|
|
||||||
def gen_secret(length: int) -> str:
|
def gen_secret(length: int) -> str:
|
||||||
chars = string.ascii_uppercase + string.ascii_lowercase + string.digits
|
chars = string.ascii_uppercase + string.ascii_lowercase + string.digits
|
||||||
return ''.join(random.choice(chars) for _ in range(length))
|
return ''.join(random.choice(chars) for _ in range(length))
|
||||||
|
@ -147,7 +164,7 @@ def _build_status_page_data(
|
||||||
|
|
||||||
icon: str = "/icon.svg",
|
icon: str = "/icon.svg",
|
||||||
publicGroupList: list = None
|
publicGroupList: list = None
|
||||||
) -> tuple(str, dict, str, list):
|
) -> tuple[str, dict, str, list]:
|
||||||
if theme not in ["light", "dark"]:
|
if theme not in ["light", "dark"]:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
if not domainNameList:
|
if not domainNameList:
|
||||||
|
@ -381,7 +398,8 @@ class UptimeKumaApi(object):
|
||||||
)
|
)
|
||||||
|
|
||||||
:param str url: The url to the Uptime Kuma instance. For example ``http://127.0.0.1:3001``
|
:param str url: The url to the Uptime Kuma instance. For example ``http://127.0.0.1:3001``
|
||||||
:param float wait_timeout: How many seconds the client should wait for the connection., defaults to 1
|
:param float timeout: How many seconds the client should wait for the connection, an expected event or a server
|
||||||
|
response. Default is ``10``.
|
||||||
:param dict headers: Headers that are passed to the socketio connection, defaults to None
|
:param dict headers: Headers that are passed to the socketio connection, defaults to None
|
||||||
:param bool ssl_verify: ``True`` to verify SSL certificates, or ``False`` to skip SSL certificate
|
:param bool ssl_verify: ``True`` to verify SSL certificates, or ``False`` to skip SSL certificate
|
||||||
verification, allowing connections to servers with self signed certificates.
|
verification, allowing connections to servers with self signed certificates.
|
||||||
|
@ -395,13 +413,13 @@ class UptimeKumaApi(object):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
url: str,
|
url: str,
|
||||||
wait_timeout: float = 1,
|
timeout: float = 10,
|
||||||
headers: dict = None,
|
headers: dict = None,
|
||||||
ssl_verify: bool = True,
|
ssl_verify: bool = True,
|
||||||
wait_events: float = 0.2
|
wait_events: float = 0.2
|
||||||
) -> None:
|
) -> None:
|
||||||
self.url = url
|
self.url = url
|
||||||
self.wait_timeout = wait_timeout
|
self.timeout = timeout
|
||||||
self.headers = headers
|
self.headers = headers
|
||||||
self.wait_events = wait_events
|
self.wait_events = wait_events
|
||||||
self.sio = socketio.Client(ssl_verify=ssl_verify)
|
self.sio = socketio.Client(ssl_verify=ssl_verify)
|
||||||
|
@ -453,26 +471,25 @@ class UptimeKumaApi(object):
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def wait_for_event(self, event: Event) -> None:
|
def wait_for_event(self, event: Event) -> None:
|
||||||
# 200 * 0.05 seconds = 10 seconds
|
# waits for the first event of the given type to arrive
|
||||||
retries = 200
|
|
||||||
sleep = 0.05
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
yield
|
yield
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
counter = 0
|
timestamp = time.time()
|
||||||
while self._event_data[event] is None:
|
while self._event_data[event] is None:
|
||||||
time.sleep(sleep)
|
if time.time() - timestamp > self.timeout:
|
||||||
counter += 1
|
raise Timeout(f"Timed out while waiting for event {event}")
|
||||||
if counter >= retries:
|
time.sleep(0.01)
|
||||||
print(f"wait_for_event {event} timeout")
|
|
||||||
break
|
|
||||||
|
|
||||||
def _get_event_data(self, event) -> Any:
|
def _get_event_data(self, event) -> Any:
|
||||||
monitor_events = [Event.AVG_PING, Event.UPTIME, Event.HEARTBEAT_LIST, Event.IMPORTANT_HEARTBEAT_LIST, Event.CERT_INFO, Event.HEARTBEAT]
|
monitor_events = [Event.AVG_PING, Event.UPTIME, Event.HEARTBEAT_LIST, Event.IMPORTANT_HEARTBEAT_LIST, Event.CERT_INFO, Event.HEARTBEAT]
|
||||||
|
timestamp = time.time()
|
||||||
while self._event_data[event] is None:
|
while self._event_data[event] is None:
|
||||||
|
if time.time() - timestamp > self.timeout:
|
||||||
|
raise Timeout(f"Timed out while waiting for event {event}")
|
||||||
# do not wait for events that are not sent
|
# do not wait for events that are not sent
|
||||||
if self._event_data[Event.MONITOR_LIST] == {} and event in monitor_events:
|
if self._event_data[Event.MONITOR_LIST] == {} and event in monitor_events:
|
||||||
return []
|
return []
|
||||||
|
@ -481,7 +498,7 @@ class UptimeKumaApi(object):
|
||||||
return deepcopy(self._event_data[event].copy())
|
return deepcopy(self._event_data[event].copy())
|
||||||
|
|
||||||
def _call(self, event, data=None) -> Any:
|
def _call(self, event, data=None) -> Any:
|
||||||
r = self.sio.call(event, data)
|
r = self.sio.call(event, data, timeout=self.timeout)
|
||||||
if isinstance(r, dict) and "ok" in r:
|
if isinstance(r, dict) and "ok" in r:
|
||||||
if not r["ok"]:
|
if not r["ok"]:
|
||||||
raise UptimeKumaException(r.get("msg"))
|
raise UptimeKumaException(r.get("msg"))
|
||||||
|
@ -599,7 +616,7 @@ class UptimeKumaApi(object):
|
||||||
"""
|
"""
|
||||||
url = self.url.rstrip("/")
|
url = self.url.rstrip("/")
|
||||||
try:
|
try:
|
||||||
self.sio.connect(f'{url}/socket.io/', wait_timeout=self.wait_timeout, headers=self.headers)
|
self.sio.connect(f'{url}/socket.io/', wait_timeout=self.timeout, headers=self.headers)
|
||||||
except:
|
except:
|
||||||
raise UptimeKumaException("unable to connect")
|
raise UptimeKumaException("unable to connect")
|
||||||
|
|
||||||
|
@ -860,7 +877,7 @@ class UptimeKumaApi(object):
|
||||||
timeRange: list = None,
|
timeRange: list = None,
|
||||||
cron: str = "30 3 * * *",
|
cron: str = "30 3 * * *",
|
||||||
durationMinutes: int = 60,
|
durationMinutes: int = 60,
|
||||||
timezone: str = None
|
timezoneOption: str = None
|
||||||
) -> dict:
|
) -> dict:
|
||||||
if not dateRange:
|
if not dateRange:
|
||||||
dateRange = [
|
dateRange = [
|
||||||
|
@ -895,7 +912,7 @@ class UptimeKumaApi(object):
|
||||||
data.update({
|
data.update({
|
||||||
"cron": cron,
|
"cron": cron,
|
||||||
"durationMinutes": durationMinutes,
|
"durationMinutes": durationMinutes,
|
||||||
"timezone": timezone,
|
"timezoneOption": timezoneOption,
|
||||||
})
|
})
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
@ -1136,7 +1153,7 @@ class UptimeKumaApi(object):
|
||||||
'monitor_id': 1,
|
'monitor_id': 1,
|
||||||
'msg': '200 - OK',
|
'msg': '200 - OK',
|
||||||
'ping': 201,
|
'ping': 201,
|
||||||
'status': True,
|
'status': <MonitorStatus.UP: 1>,
|
||||||
'time': '2022-12-15 12:38:42.661'
|
'time': '2022-12-15 12:38:42.661'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1147,14 +1164,15 @@ class UptimeKumaApi(object):
|
||||||
'monitor_id': 1,
|
'monitor_id': 1,
|
||||||
'msg': '200 - OK',
|
'msg': '200 - OK',
|
||||||
'ping': 193,
|
'ping': 193,
|
||||||
'status': True,
|
'status': <MonitorStatus.UP: 1>,
|
||||||
'time': '2022-12-15 12:39:42.878'
|
'time': '2022-12-15 12:39:42.878'
|
||||||
},
|
},
|
||||||
...
|
...
|
||||||
]
|
]
|
||||||
"""
|
"""
|
||||||
r = self._call('getMonitorBeats', (id_, hours))["data"]
|
r = self._call('getMonitorBeats', (id_, hours))["data"]
|
||||||
int_to_bool(r, ["important", "status"])
|
int_to_bool(r, ["important"])
|
||||||
|
parse_monitor_status(r)
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def get_game_list(self) -> list[dict]:
|
def get_game_list(self) -> list[dict]:
|
||||||
|
@ -1739,7 +1757,10 @@ class UptimeKumaApi(object):
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
r1 = self._call('getStatusPage', slug)
|
r1 = self._call('getStatusPage', slug)
|
||||||
r2 = requests.get(f"{self.url}/api/status-page/{slug}").json()
|
try:
|
||||||
|
r2 = requests.get(f"{self.url}/api/status-page/{slug}", timeout=self.timeout).json()
|
||||||
|
except requests.exceptions.Timeout as e:
|
||||||
|
raise Timeout(e)
|
||||||
|
|
||||||
config = r1["config"]
|
config = r1["config"]
|
||||||
config.update(r2["config"])
|
config.update(r2["config"])
|
||||||
|
@ -1975,7 +1996,8 @@ class UptimeKumaApi(object):
|
||||||
"""
|
"""
|
||||||
r = self._get_event_data(Event.HEARTBEAT_LIST)
|
r = self._get_event_data(Event.HEARTBEAT_LIST)
|
||||||
for i in r:
|
for i in r:
|
||||||
int_to_bool(r[i], ["important", "status"])
|
int_to_bool(r[i], ["important"])
|
||||||
|
parse_monitor_status(r[i])
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def get_important_heartbeats(self) -> dict:
|
def get_important_heartbeats(self) -> dict:
|
||||||
|
@ -2004,7 +2026,8 @@ class UptimeKumaApi(object):
|
||||||
"""
|
"""
|
||||||
r = self._get_event_data(Event.IMPORTANT_HEARTBEAT_LIST)
|
r = self._get_event_data(Event.IMPORTANT_HEARTBEAT_LIST)
|
||||||
for i in r:
|
for i in r:
|
||||||
int_to_bool(r[i], ["important", "status"])
|
int_to_bool(r[i], ["important"])
|
||||||
|
parse_monitor_status(r[i])
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def get_heartbeat(self) -> dict:
|
def get_heartbeat(self) -> dict:
|
||||||
|
@ -2032,7 +2055,8 @@ class UptimeKumaApi(object):
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
r = self._get_event_data(Event.HEARTBEAT)
|
r = self._get_event_data(Event.HEARTBEAT)
|
||||||
int_to_bool(r, ["important", "status"])
|
int_to_bool(r, ["important"])
|
||||||
|
parse_monitor_status(r)
|
||||||
return r
|
return r
|
||||||
|
|
||||||
# avg ping
|
# avg ping
|
||||||
|
@ -3054,7 +3078,7 @@ class UptimeKumaApi(object):
|
||||||
],
|
],
|
||||||
"cron": "",
|
"cron": "",
|
||||||
"durationMinutes": null,
|
"durationMinutes": null,
|
||||||
"timezone": "Europe/Berlin",
|
"timezoneOption": "Europe/Berlin",
|
||||||
"timezoneOffset": "+02:00",
|
"timezoneOffset": "+02:00",
|
||||||
"status": "ended"
|
"status": "ended"
|
||||||
}
|
}
|
||||||
|
@ -3106,7 +3130,7 @@ class UptimeKumaApi(object):
|
||||||
"cron": null,
|
"cron": null,
|
||||||
"duration": null,
|
"duration": null,
|
||||||
"durationMinutes": 0,
|
"durationMinutes": 0,
|
||||||
"timezone": "Europe/Berlin",
|
"timezoneOption": "Europe/Berlin",
|
||||||
"timezoneOffset": "+02:00",
|
"timezoneOffset": "+02:00",
|
||||||
"status": "ended"
|
"status": "ended"
|
||||||
}
|
}
|
||||||
|
@ -3155,7 +3179,7 @@ class UptimeKumaApi(object):
|
||||||
... ],
|
... ],
|
||||||
... weekdays=[],
|
... weekdays=[],
|
||||||
... daysOfMonth=[],
|
... daysOfMonth=[],
|
||||||
... timezone="Europe/Berlin"
|
... timezoneOption="Europe/Berlin"
|
||||||
... )
|
... )
|
||||||
{
|
{
|
||||||
"msg": "Added Successfully.",
|
"msg": "Added Successfully.",
|
||||||
|
@ -3188,7 +3212,7 @@ class UptimeKumaApi(object):
|
||||||
... ],
|
... ],
|
||||||
... weekdays=[],
|
... weekdays=[],
|
||||||
... daysOfMonth=[],
|
... daysOfMonth=[],
|
||||||
... timezone="Europe/Berlin"
|
... timezoneOption="Europe/Berlin"
|
||||||
... )
|
... )
|
||||||
{
|
{
|
||||||
"msg": "Added Successfully.",
|
"msg": "Added Successfully.",
|
||||||
|
@ -3226,7 +3250,7 @@ class UptimeKumaApi(object):
|
||||||
... 0
|
... 0
|
||||||
... ],
|
... ],
|
||||||
... daysOfMonth=[],
|
... daysOfMonth=[],
|
||||||
... timezone="Europe/Berlin"
|
... timezoneOption="Europe/Berlin"
|
||||||
... )
|
... )
|
||||||
{
|
{
|
||||||
"msg": "Added Successfully.",
|
"msg": "Added Successfully.",
|
||||||
|
@ -3265,7 +3289,7 @@ class UptimeKumaApi(object):
|
||||||
... 30,
|
... 30,
|
||||||
... "lastDay1"
|
... "lastDay1"
|
||||||
... ],
|
... ],
|
||||||
... timezone="Europe/Berlin"
|
... timezoneOption="Europe/Berlin"
|
||||||
... )
|
... )
|
||||||
{
|
{
|
||||||
"msg": "Added Successfully.",
|
"msg": "Added Successfully.",
|
||||||
|
@ -3288,7 +3312,7 @@ class UptimeKumaApi(object):
|
||||||
... daysOfMonth=[],
|
... daysOfMonth=[],
|
||||||
... cron="50 5 * * *",
|
... cron="50 5 * * *",
|
||||||
... durationMinutes=120,
|
... durationMinutes=120,
|
||||||
... timezone="Europe/Berlin"
|
... timezoneOption="Europe/Berlin"
|
||||||
... )
|
... )
|
||||||
{
|
{
|
||||||
"msg": "Added Successfully.",
|
"msg": "Added Successfully.",
|
||||||
|
@ -3680,3 +3704,13 @@ class UptimeKumaApi(object):
|
||||||
"""
|
"""
|
||||||
with self.wait_for_event(Event.API_KEY_LIST):
|
with self.wait_for_event(Event.API_KEY_LIST):
|
||||||
return self._call('deleteAPIKey', id_)
|
return self._call('deleteAPIKey', id_)
|
||||||
|
|
||||||
|
# helper methods
|
||||||
|
|
||||||
|
def get_monitor_status(self, monitor_id: int) -> MonitorStatus:
|
||||||
|
heartbeats = self.get_heartbeats()
|
||||||
|
for heartbeat in heartbeats:
|
||||||
|
if int(heartbeat["id"]) == monitor_id:
|
||||||
|
status = heartbeat["data"][-1]["status"]
|
||||||
|
return MonitorStatus(status)
|
||||||
|
raise UptimeKumaException("monitor does not exist")
|
||||||
|
|
|
@ -2,4 +2,9 @@ class UptimeKumaException(Exception):
|
||||||
"""
|
"""
|
||||||
There was an exception that occurred while communicating with Uptime Kuma.
|
There was an exception that occurred while communicating with Uptime Kuma.
|
||||||
"""
|
"""
|
||||||
pass
|
|
||||||
|
|
||||||
|
class Timeout(UptimeKumaException):
|
||||||
|
"""
|
||||||
|
A timeout has occurred while communicating with Uptime Kuma.
|
||||||
|
"""
|
||||||
|
|
17
uptime_kuma_api/monitor_status.py
Normal file
17
uptime_kuma_api/monitor_status.py
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class MonitorStatus(int, Enum):
|
||||||
|
"""Enumerate monitor statuses."""
|
||||||
|
|
||||||
|
DOWN = 0
|
||||||
|
"""DOWN"""
|
||||||
|
|
||||||
|
UP = 1
|
||||||
|
"""UP"""
|
||||||
|
|
||||||
|
PENDING = 2
|
||||||
|
"""PENDING"""
|
||||||
|
|
||||||
|
MAINTENANCE = 3
|
||||||
|
"""MAINTENANCE"""
|
Loading…
Reference in a new issue