feat: implement timeouts for all methods (#34)

BREAKING CHANGE: Removed the `wait_timeout` parameter. Use the new `timeout` parameter instead. The `timeout` parameter specifies how many seconds the client should wait for the connection, an expected event or a server response.
This commit is contained in:
Lucas Held 2023-05-19 13:50:39 +02:00 committed by GitHub
parent 8e841cd324
commit 9728cfdb34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 17 deletions

View file

@ -39,3 +39,5 @@ Exceptions
----------
.. autoexception:: UptimeKumaException
.. autoexception:: Timeout

View file

@ -6,6 +6,6 @@ from .proxy_protocol import ProxyProtocol
from .incident_style import IncidentStyle
from .docker_type import DockerType
from .maintenance_strategy import MaintenanceStrategy
from .exceptions import UptimeKumaException
from .exceptions import UptimeKumaException, Timeout
from .event import Event
from .api import UptimeKumaApi

View file

@ -21,6 +21,7 @@ from . import (AuthMethod,
MonitorType,
NotificationType,
ProxyProtocol,
Timeout,
UptimeKumaException,
notification_provider_conditions,
notification_provider_options)
@ -382,7 +383,8 @@ class UptimeKumaApi(object):
)
: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 bool ssl_verify: ``True`` to verify SSL certificates, or ``False`` to skip SSL certificate
verification, allowing connections to servers with self signed certificates.
@ -396,13 +398,13 @@ class UptimeKumaApi(object):
def __init__(
self,
url: str,
wait_timeout: float = 1,
timeout: float = 10,
headers: dict = None,
ssl_verify: bool = True,
wait_events: float = 0.2
) -> None:
self.url = url
self.wait_timeout = wait_timeout
self.timeout = timeout
self.headers = headers
self.wait_events = wait_events
self.sio = socketio.Client(ssl_verify=ssl_verify)
@ -454,26 +456,25 @@ class UptimeKumaApi(object):
@contextmanager
def wait_for_event(self, event: Event) -> None:
# 200 * 0.05 seconds = 10 seconds
retries = 200
sleep = 0.05
# waits for the first event of the given type to arrive
try:
yield
except:
raise
else:
counter = 0
timestamp = time.time()
while self._event_data[event] is None:
time.sleep(sleep)
counter += 1
if counter >= retries:
print(f"wait_for_event {event} timeout")
break
if time.time() - timestamp > self.timeout:
raise Timeout(f"Timed out while waiting for event {event}")
time.sleep(0.01)
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]
timestamp = time.time()
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
if self._event_data[Event.MONITOR_LIST] == {} and event in monitor_events:
return []
@ -482,7 +483,7 @@ class UptimeKumaApi(object):
return deepcopy(self._event_data[event])
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 not r["ok"]:
raise UptimeKumaException(r.get("msg"))
@ -587,7 +588,7 @@ class UptimeKumaApi(object):
"""
url = self.url.rstrip("/")
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:
raise UptimeKumaException("unable to connect")
@ -1727,7 +1728,10 @@ class UptimeKumaApi(object):
}
"""
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.update(r2["config"])

View file

@ -2,4 +2,9 @@ class UptimeKumaException(Exception):
"""
There was an exception that occurred while communicating with Uptime Kuma.
"""
pass
class Timeout(UptimeKumaException):
"""
A timeout has occurred while communicating with Uptime Kuma.
"""