From c680e1b60218e571208996fb0951a04a4ed7bfc4 Mon Sep 17 00:00:00 2001 From: Fred <323546+fguillot@users.noreply.github.com> Date: Tue, 24 Mar 2026 17:50:18 -0700 Subject: [PATCH] feat: add request timeout with 30-second default Prevent indefinite blocking when the server is unresponsive by passing a timeout to urllib.request.urlopen. Defaults to 30 seconds; set to None to disable. BREAKING CHANGE: requests now time out after 30 seconds by default --- kanboard.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kanboard.py b/kanboard.py index b4aac4c..f85dae5 100644 --- a/kanboard.py +++ b/kanboard.py @@ -63,6 +63,7 @@ def __init__( insecure: bool = False, ignore_hostname_verification: bool = False, user_agent: str = "Kanboard Python API Client", + timeout: Optional[int] = 30, loop: Optional[asyncio.AbstractEventLoop] = None, ) -> None: """ @@ -81,6 +82,7 @@ def __init__( Defaults to False. user_agent (str, optional): Custom User-Agent string for HTTP requests. Defaults to 'Kanboard Python API Client'. + timeout (Optional[int], optional): Request timeout in seconds. Defaults to 30. Set to None to disable. loop (Optional[asyncio.AbstractEventLoop], optional): Asyncio event loop to use. If None, uses the current event loop or creates a new one. """ @@ -91,6 +93,7 @@ def __init__( self._cafile = cafile self._insecure = insecure self._user_agent = user_agent + self._timeout = timeout self._ignore_hostname_verification = ignore_hostname_verification if not loop: @@ -160,7 +163,7 @@ def _do_request(self, headers: Dict[str, str], body: Dict[str, Any]) -> Any: if self._ignore_hostname_verification: ssl_context.check_hostname = False - response = http.urlopen(request, context=ssl_context).read() + response = http.urlopen(request, context=ssl_context, timeout=self._timeout).read() except Exception as e: raise ClientError(str(e)) return self._parse_response(response)