summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/api-usage.rst16
-rw-r--r--gitlab/__init__.py14
-rw-r--r--tools/python_test_v4.py2
3 files changed, 27 insertions, 5 deletions
diff --git a/docs/api-usage.rst b/docs/api-usage.rst
index 73d1377..a5afbda 100644
--- a/docs/api-usage.rst
+++ b/docs/api-usage.rst
@@ -299,7 +299,9 @@ Rate limits
python-gitlab obeys the rate limit of the GitLab server by default. On
receiving a 429 response (Too Many Requests), python-gitlab sleeps for the
-amount of time in the Retry-After header that GitLab sends back.
+amount of time in the Retry-After header that GitLab sends back. If GitLab
+does not return a response with the Retry-After header, python-gitlab will
+perform an exponential backoff.
If you don't want to wait, you can disable the rate-limiting feature, by
supplying the ``obey_rate_limit`` argument.
@@ -312,6 +314,18 @@ supplying the ``obey_rate_limit`` argument.
gl = gitlab.gitlab(url, token, api_version=4)
gl.projects.list(all=True, obey_rate_limit=False)
+If you do not disable the rate-limiting feature, you can supply a custom value
+for ``max_retries``; by default, this is set to 10. To retry without bound when
+throttled, you can set this parameter to -1. This parameter is ignored if
+``obey_rate_limit`` is set to ``False``.
+
+.. code-block:: python
+
+ import gitlab
+ import requests
+
+ gl = gitlab.gitlab(url, token, api_version=4)
+ gl.projects.list(all=True, max_retries=12)
.. warning::
diff --git a/gitlab/__init__.py b/gitlab/__init__.py
index 01f9426..c280974 100644
--- a/gitlab/__init__.py
+++ b/gitlab/__init__.py
@@ -477,6 +477,10 @@ class Gitlab(object):
# obey the rate limit by default
obey_rate_limit = kwargs.get("obey_rate_limit", True)
+ # set max_retries to 10 by default, disable by setting it to -1
+ max_retries = kwargs.get("max_retries", 10)
+ cur_retries = 0
+
while True:
result = self.session.send(prepped, timeout=timeout, **settings)
@@ -486,9 +490,13 @@ class Gitlab(object):
return result
if 429 == result.status_code and obey_rate_limit:
- wait_time = int(result.headers["Retry-After"])
- time.sleep(wait_time)
- continue
+ if max_retries == -1 or cur_retries < max_retries:
+ wait_time = 2 ** cur_retries * 0.1
+ if "Retry-After" in result.headers:
+ wait_time = int(result.headers["Retry-After"])
+ cur_retries += 1
+ time.sleep(wait_time)
+ continue
error_message = result.content
try:
diff --git a/tools/python_test_v4.py b/tools/python_test_v4.py
index 30e4456..aacb3e7 100644
--- a/tools/python_test_v4.py
+++ b/tools/python_test_v4.py
@@ -798,7 +798,7 @@ for i in range(20, 40):
except gitlab.GitlabCreateError as e:
error_message = e.error_message
break
-assert 'Retry later' in error_message.decode()
+assert 'Retry later' in error_message
[current_project.delete() for current_project in projects]
settings.throttle_authenticated_api_enabled = False
settings.save()