Skip to content

Commit 6e58da8

Browse files
committed
api: Add auto_retry_rate_limits option to Client to handle 429 errors.
1 parent 9960360 commit 6e58da8

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

zulip/zulip/__init__.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ def __init__(
393393
config_file: Optional[str] = None,
394394
verbose: bool = False,
395395
retry_on_errors: bool = True,
396+
auto_retry_rate_limits: bool = False,
396397
site: Optional[str] = None,
397398
client: Optional[str] = None,
398399
cert_bundle: Optional[str] = None,
@@ -476,6 +477,7 @@ def __init__(
476477
self.api_key = api_key
477478
self.email = email
478479
self.verbose = verbose
480+
self.auto_retry_rate_limits = auto_retry_rate_limits
479481
if site is not None:
480482
if site.startswith("localhost"):
481483
site = "http://" + site
@@ -655,6 +657,23 @@ def end_error_retry(succeeded: bool) -> None:
655657

656658
self.has_connected = True
657659

660+
# On Rate Limit (429) Errors, pause the current thread with time.sleep()
661+
# And only retry if the user opted in sucessfully
662+
if res.status_code == 429 and self.auto_retry_rate_limits:
663+
try:
664+
# Zulip will return the wait time in the either the (JSON) body or header
665+
wait_time = float(
666+
res.json().get("retry-after", res.headers.get("Retry-After", 1.0))
667+
)
668+
except Exception:
669+
wait_time = 1.0
670+
if self.verbose:
671+
print(
672+
f"Rate limit hit! Sleeping for {wait_time} seconds before retrying..."
673+
)
674+
time.sleep(wait_time)
675+
continue
676+
658677
# On 50x errors, try again after a short sleep
659678
if str(res.status_code).startswith("5") and error_retry(
660679
f" (server {res.status_code})"

0 commit comments

Comments
 (0)