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:
parent
8e841cd324
commit
9728cfdb34
4 changed files with 28 additions and 17 deletions
|
@ -39,3 +39,5 @@ Exceptions
|
||||||
----------
|
----------
|
||||||
|
|
||||||
.. autoexception:: UptimeKumaException
|
.. autoexception:: UptimeKumaException
|
||||||
|
|
||||||
|
.. autoexception:: Timeout
|
||||||
|
|
|
@ -6,6 +6,6 @@ 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
|
||||||
|
|
|
@ -21,6 +21,7 @@ from . import (AuthMethod,
|
||||||
MonitorType,
|
MonitorType,
|
||||||
NotificationType,
|
NotificationType,
|
||||||
ProxyProtocol,
|
ProxyProtocol,
|
||||||
|
Timeout,
|
||||||
UptimeKumaException,
|
UptimeKumaException,
|
||||||
notification_provider_conditions,
|
notification_provider_conditions,
|
||||||
notification_provider_options)
|
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 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.
|
||||||
|
@ -396,13 +398,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)
|
||||||
|
@ -454,26 +456,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 []
|
||||||
|
@ -482,7 +483,7 @@ class UptimeKumaApi(object):
|
||||||
return deepcopy(self._event_data[event])
|
return deepcopy(self._event_data[event])
|
||||||
|
|
||||||
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"))
|
||||||
|
@ -587,7 +588,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")
|
||||||
|
|
||||||
|
@ -1727,7 +1728,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"])
|
||||||
|
|
|
@ -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.
|
||||||
|
"""
|
||||||
|
|
Loading…
Reference in a new issue