Skip to content

Commit 290d696

Browse files
authored
chore: add tobixen ideas
1 parent 80ce80b commit 290d696

1 file changed

Lines changed: 31 additions & 1 deletion

File tree

caldav/davclient.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
For async code, use: from caldav import aio
99
"""
1010

11+
import time
1112
import logging
1213
import sys
1314
import warnings
@@ -208,6 +209,9 @@ def __init__(
208209
features: FeatureSet | dict | str = None,
209210
enable_rfc6764: bool = True,
210211
require_tls: bool = True,
212+
rate_limit_handle: bool = False,
213+
rate_limit_default_sleep: int = None,
214+
rate_limit_max_sleep: int = None,
211215
) -> None:
212216
"""
213217
Sets up a HTTPConnection object towards the server in the url.
@@ -245,6 +249,13 @@ def __init__(
245249
redirect to unencrypted HTTP. Set to False ONLY if you need to
246250
support non-TLS servers and trust your DNS infrastructure.
247251
This parameter has no effect if enable_rfc6764=False.
252+
rate_limit_handle: boolean, a parameter that determines whether the rate limit response
253+
should be handled. Default: False.
254+
rate_limit_default_sleep: integer, the default number of seconds to sleep if the server
255+
response cannot be parsed, or if no retry-after is specified
256+
and the HTTP response status code is 429. Default: None.
257+
rate_limit_max_sleep: integer, the maximum number of seconds the script will sleep
258+
when encountering a rate limit. Default: None.
248259
249260
The niquests library will honor a .netrc-file, if such a file exists
250261
username and password may be omitted.
@@ -343,6 +354,10 @@ def __init__(
343354

344355
self._principal = None
345356

357+
self.rate_limit_handle = rate_limit_handle
358+
self.rate_limit_default_sleep = rate_limit_default_sleep
359+
self.rate_limit_max_sleep = rate_limit_max_sleep
360+
346361
def __enter__(self) -> Self:
347362
## Used for tests, to set up a temporarily test server
348363
if hasattr(self, "setup"):
@@ -933,7 +948,22 @@ def request(
933948
Returns:
934949
DAVResponse
935950
"""
936-
return self._sync_request(url, method, body, headers)
951+
try:
952+
return self._sync_request(url, method, body, headers)
953+
except error.RateLimitError as e:
954+
if self.rate_limit_handle:
955+
retry_after_seconds = self.rate_limit_default_sleep
956+
if e.retry_after_seconds is not None:
957+
retry_after_seconds = e.retry_after_seconds
958+
retry_after_seconds = max(
959+
[retry_after_seconds or 0, self.rate_limit_max_sleep or 0]
960+
)
961+
if retry_after_seconds <= 0:
962+
raise e
963+
time.sleep(retry_after_seconds)
964+
return self._sync_request(url, method, body, headers)
965+
966+
raise e
937967

938968
def _sync_request(
939969
self,

0 commit comments

Comments
 (0)