Skip to content

Commit

Permalink
Merge pull request #678 from appian/backoff-requests
Browse files Browse the repository at this point in the history
Fix missing "Retry-After" header and fix integration tests
  • Loading branch information
max-wittig committed Jan 13, 2019
2 parents ce2c835 + 16bda20 commit 89679ce
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 5 deletions.
16 changes: 15 additions & 1 deletion docs/api-usage.rst
Expand Up @@ -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.
Expand All @@ -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::

Expand Down
14 changes: 11 additions & 3 deletions gitlab/__init__.py
Expand Up @@ -477,6 +477,10 @@ def http_request(self, verb, path, query_data={}, post_data=None,
# 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)

Expand All @@ -486,9 +490,13 @@ def http_request(self, verb, path, query_data={}, post_data=None,
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:
Expand Down
2 changes: 1 addition & 1 deletion tools/python_test_v4.py
Expand Up @@ -798,7 +798,7 @@
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()
Expand Down

0 comments on commit 89679ce

Please sign in to comment.