Skip to content

Commit a5a6cdc

Browse files
committed
add logger for retries
1 parent f2a0114 commit a5a6cdc

File tree

5 files changed

+54
-17
lines changed

5 files changed

+54
-17
lines changed

_test_unstructured_client/test_utils_retries.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import os
21
import pytest
2+
import logging
33

44
import requests_mock
55

@@ -8,15 +8,11 @@
88
from unstructured_client.utils.retries import BackoffStrategy, RetryConfig
99

1010

11-
def get_api_key():
12-
api_key = os.getenv("UNS_API_KEY")
13-
if api_key is None:
14-
raise ValueError("""UNS_API_KEY environment variable not set.
15-
Set it in your current shell session with `export UNS_API_KEY=<api_key>`""")
16-
return api_key
11+
FAKE_KEY = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1712

18-
# this test requires UNS_API_KEY be set in your shell session. Ex: `export UNS_API_KEY=<api_key>`
19-
def test_backoff_strategy():
13+
14+
def test_retry_with_backoff_does_retry(caplog):
15+
caplog.set_level(logging.INFO)
2016
filename = "README.md"
2117
backoff_strategy = BackoffStrategy(
2218
initial_interval=100, max_interval=1000, exponent=1.5, max_elapsed_time=3000
@@ -28,7 +24,7 @@ def test_backoff_strategy():
2824
with requests_mock.Mocker() as mock:
2925
# mock a 500 status code for POST requests to the api
3026
mock.post("https://api.unstructured.io/general/v0/general", status_code=500)
31-
session = UnstructuredClient(api_key_auth=get_api_key())
27+
session = UnstructuredClient(api_key_auth=FAKE_KEY)
3228

3329
with open(filename, "rb") as f:
3430
files=shared.Files(
@@ -45,3 +41,32 @@ def test_backoff_strategy():
4541

4642
# the number of retries varies
4743
assert len(mock.request_history) > 1
44+
45+
46+
def test_backoff_strategy_logs_retries(caplog):
47+
caplog.set_level(logging.INFO)
48+
filename = "README.md"
49+
backoff_strategy = BackoffStrategy(
50+
initial_interval=100, max_interval=1000, exponent=1.5, max_elapsed_time=3000
51+
)
52+
retries = RetryConfig(
53+
strategy="backoff", backoff=backoff_strategy, retry_connection_errors=True
54+
)
55+
56+
with requests_mock.Mocker() as mock:
57+
# mock a 500 status code for POST requests to the api
58+
mock.post("https://api.unstructured.io/general/v0/general", status_code=500)
59+
session = UnstructuredClient(api_key_auth=FAKE_KEY)
60+
61+
with open(filename, "rb") as f:
62+
files=shared.Files(
63+
content=f.read(),
64+
file_name=filename,
65+
)
66+
67+
req = shared.PartitionParameters(files=files)
68+
with pytest.raises(Exception):
69+
session.general.partition(req, retries=retries)
70+
71+
72+
assert "seconds before retry" in caplog.text

src/unstructured_client/general.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import Any, List, Optional
55
from unstructured_client import utils
66
from unstructured_client.models import errors, operations, shared
7-
from unstructured_client.utils._decorators import suggest_defining_url_if_401 # human code
7+
from unstructured_client.utils._human_utils import suggest_defining_url_if_401 # human code
88

99
class General:
1010
sdk_configuration: SDKConfiguration

src/unstructured_client/sdk.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from typing import Callable, Dict, Union
77
from unstructured_client import utils
88
from unstructured_client.models import shared
9-
from unstructured_client.utils._decorators import clean_server_url # human code
9+
from unstructured_client.utils._human_utils import clean_server_url # human code
1010

1111
class UnstructuredClient:
1212
r"""Unstructured Pipeline API: Partition documents with the Unstructured library"""

src/unstructured_client/utils/_decorators.py renamed to src/unstructured_client/utils/_human_utils.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
from __future__ import annotations
22

33
import functools
4-
from typing import cast, Callable, TYPE_CHECKING, Optional
4+
import logging
5+
import sys
6+
from typing import Callable, Optional, TYPE_CHECKING, cast
57
from typing_extensions import ParamSpec
6-
from urllib.parse import urlparse, urlunparse, ParseResult
8+
from urllib.parse import ParseResult, urlparse, urlunparse
79
import warnings
810

9-
from unstructured_client.models import errors, operations
10-
1111
if TYPE_CHECKING:
1212
from unstructured_client.general import General
13+
from unstructured_client.models import operations
1314

1415

1516
_P = ParamSpec("_P")
@@ -75,6 +76,8 @@ def suggest_defining_url_if_401(
7576

7677
@functools.wraps(func)
7778
def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> operations.PartitionResponse:
79+
from unstructured_client.models import errors
80+
7881
try:
7982
return func(*args, **kwargs)
8083
except errors.SDKError as error:
@@ -86,5 +89,11 @@ def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> operations.PartitionResponse
8689
)
8790

8891
return func(*args, **kwargs)
89-
92+
9093
return wrapper
94+
95+
96+
def log_retries(retry_count, sleep):
97+
"""Function for logging retries to give users visibility into requests."""
98+
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
99+
logging.info(f"Retry attempt {retry_count}. Sleeping {round(sleep, 1)} seconds before retry.")

src/unstructured_client/utils/retries.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import requests
88

9+
from unstructured_client.utils._human_utils import log_retries # human code
10+
911

1012
class BackoffStrategy:
1113
initial_interval: int
@@ -116,5 +118,6 @@ def retry_with_backoff(func, initial_interval=500, max_interval=60000, exponent=
116118
exponent**retries + random.uniform(0, 1))
117119
if sleep > max_interval/1000:
118120
sleep = max_interval/1000
121+
log_retries(retry_count=retries, sleep=sleep) # human code
119122
time.sleep(sleep)
120123
retries += 1

0 commit comments

Comments
 (0)