Skip to content

Commit 8094595

Browse files
committed
zulip.Client.call_endpoint: Add retry_on_rate_limit_error.
If the call_endpoint method is called with the "retry_on_rate_limit_error" parameter set to true, wait and retry automatically on rate limit errors. See https://chat.zulip.org/#narrow/stream/378-api-design/topic/ Rate.20limits/near/1217048 for the discussion.
1 parent 71d488e commit 8094595

File tree

1 file changed

+22
-8
lines changed

1 file changed

+22
-8
lines changed

zulip/zulip/__init__.py

+22-8
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,7 @@ def call_endpoint(
697697
method: str = "POST",
698698
request: Optional[Dict[str, Any]] = None,
699699
longpolling: bool = False,
700+
retry_on_rate_limit_error: bool = False,
700701
files: Optional[List[IO[Any]]] = None,
701702
timeout: Optional[float] = None,
702703
) -> Dict[str, Any]:
@@ -707,14 +708,27 @@ def call_endpoint(
707708
if v is not None:
708709
marshalled_request[k] = v
709710
versioned_url = API_VERSTRING + (url if url is not None else "")
710-
return self.do_api_query(
711-
marshalled_request,
712-
versioned_url,
713-
method=method,
714-
longpolling=longpolling,
715-
files=files,
716-
timeout=timeout,
717-
)
711+
712+
while True:
713+
result = self.do_api_query(
714+
marshalled_request,
715+
versioned_url,
716+
method=method,
717+
longpolling=longpolling,
718+
files=files,
719+
timeout=timeout,
720+
)
721+
if not retry_on_rate_limit_error or not (
722+
result["result"] == "error"
723+
and "code" in result
724+
and result["code"] == "RATE_LIMIT_HIT"
725+
):
726+
break
727+
secs: float = result["retry-after"]
728+
logger.warning("hit API rate limit, waiting for %f seconds...", secs)
729+
time.sleep(secs)
730+
731+
return result
718732

719733
def call_on_each_event(
720734
self,

0 commit comments

Comments
 (0)