Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatic API retry on failure #77

Open
iloveitaly opened this issue Nov 22, 2022 · 1 comment
Open

Automatic API retry on failure #77

iloveitaly opened this issue Nov 22, 2022 · 1 comment
Labels
enhancement New feature or request

Comments

@iloveitaly
Copy link
Contributor

Enhancement description

Like the Stripe API bindings, it would be great if you could configure network and system retries when intermittent network failures occur or server errors on the todoist side of things.

The problem it solves

Script failing out because of something that isn't the developers fault.

Alternatives

NA

Use case / screenshots

NA

Additional information

@iloveitaly iloveitaly added the enhancement New feature or request label Nov 22, 2022
@jkawamoto
Copy link
Contributor

If I'm not mistaken, we can use requests’ HTTPAdapter with urllib3’s Retry to retry requests.
For example, this code retries requests ten times if connecting to the server fails or the server returns 500:

from todoist_api_python.api import TodoistAPI
from todoist_api_python.endpoints import BASE_URL
from requests import Session
from requests.adapters import HTTPAdapter, Retry

s = Session()
s.mount(BASE_URL, HTTPAdapter(max_retries=Retry(status_forcelist=[500])))

api = TodoistAPI("my token", s)
try:
    tasks = api.get_tasks()
    print(tasks)
except Exception as error:
    print(error)

This patch also adds a test that checks if the retry works with a mock server.

diff --git a/tests/test_http_requests.py b/tests/test_http_requests.py
index 9cbe87d..33c9da0 100644
--- a/tests/test_http_requests.py
+++ b/tests/test_http_requests.py
@@ -4,6 +4,8 @@ from typing import Any, Dict
 import pytest
 import responses
 from requests import HTTPError, Session
+from requests.adapters import HTTPAdapter, Retry
+from responses.registries import OrderedRegistry
 
 from tests.conftest import DEFAULT_TOKEN
 from todoist_api_python.endpoints import BASE_URL, TASKS_ENDPOINT
@@ -47,6 +49,27 @@ def test_get_raise_for_status():
         get(Session(), DEFAULT_URL, DEFAULT_TOKEN)
 
 
+@responses.activate(registry=OrderedRegistry)
+def test_get_retry(default_task_response: Dict[str, Any]):
+    responses.add(
+        responses.GET,
+        DEFAULT_URL,
+        status=500,
+    )
+    responses.add(
+        responses.GET,
+        DEFAULT_URL,
+        json=default_task_response,
+        status=200,
+    )
+
+    s = Session()
+    s.mount(BASE_URL, HTTPAdapter(max_retries=Retry(status_forcelist=[500])))
+
+    res = get(s, DEFAULT_URL, DEFAULT_TOKEN)
+    assert res == default_task_response
+
+
 @responses.activate
 def test_post_with_data(default_task_response: Dict[str, Any]):
     request_id = "12345"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants