Skip to content

Commit 23c4375

Browse files
feat: Support HTTP retries (#108)
* Add retry_config option for setting up http retries * Add retry option to SeamMultiWorkspace * ci: Format code * Mount the adapter with retries * Assign config to retries * Assign retries only when config is passed * Rename retry_config to retires * Default retries to Retry() --------- Co-authored-by: Seam Bot <devops@getseam.com>
1 parent 2126245 commit 23c4375

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

seam/client.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
from typing import Dict
1+
from typing import Dict, Optional
22
from urllib.parse import urljoin
33
import niquests as requests
44
from importlib.metadata import version
5+
from urllib3.util import Retry
56

67
from .constants import LTS_VERSION
78
from .exceptions import (
@@ -17,16 +18,27 @@
1718
"seam-lts-version": LTS_VERSION,
1819
}
1920

21+
DEFAULT_RETRIES = Retry()
22+
2023

2124
class SeamHttpClient(requests.Session, AbstractSeamHttpClient):
22-
def __init__(self, base_url: str, auth_headers: Dict[str, str], **kwargs):
25+
def __init__(
26+
self,
27+
base_url: str,
28+
auth_headers: Dict[str, str],
29+
retries: Optional[Retry] = DEFAULT_RETRIES,
30+
**kwargs
31+
):
2332
super().__init__(**kwargs)
2433

2534
self.base_url = base_url
26-
headers = {**auth_headers, **kwargs.get("headers", {}), **SDK_HEADERS}
2735

36+
headers = {**auth_headers, **kwargs.get("headers", {}), **SDK_HEADERS}
2837
self.headers.update(headers)
2938

39+
if retries:
40+
self.retries = retries
41+
3042
def request(self, method, url, *args, **kwargs):
3143
url = urljoin(self.base_url, url)
3244
response = super().request(method, url, *args, **kwargs)

seam/seam.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from typing import Any, Optional, Union, Dict
22
from typing_extensions import Self
3+
from urllib3.util.retry import Retry
34

45
from .constants import LTS_VERSION
56
from .parse_options import parse_options
@@ -24,6 +25,7 @@ def __init__(
2425
workspace_id: Optional[str] = None,
2526
endpoint: Optional[str] = None,
2627
wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = True,
28+
retries: Optional[Retry] = None,
2729
):
2830
"""
2931
Parameters
@@ -38,6 +40,8 @@ def __init__(
3840
The API endpoint to which the request should be sent.
3941
wait_for_action_attempt : bool or dict, optional
4042
Controls whether to wait for an action attempt to complete, either as a boolean or as a dictionary specifying `timeout` and `poll_interval`. Defaults to `False`.
43+
retries : urllib3.util.Retry, optional
44+
Configuration for retry behavior on failed requests.
4145
"""
4246

4347
self.lts_version = Seam.lts_version
@@ -50,7 +54,9 @@ def __init__(
5054
)
5155
defaults = {"wait_for_action_attempt": wait_for_action_attempt}
5256

53-
self.client = SeamHttpClient(base_url=endpoint, auth_headers=auth_headers)
57+
self.client = SeamHttpClient(
58+
base_url=endpoint, auth_headers=auth_headers, retries=retries
59+
)
5460

5561
Routes.__init__(self, client=self.client, defaults=defaults)
5662

@@ -61,9 +67,13 @@ def from_api_key(
6167
*,
6268
endpoint: Optional[str] = None,
6369
wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = True,
70+
retries: Optional[Retry] = None,
6471
) -> Self:
6572
return cls(
66-
api_key, endpoint=endpoint, wait_for_action_attempt=wait_for_action_attempt
73+
api_key,
74+
endpoint=endpoint,
75+
wait_for_action_attempt=wait_for_action_attempt,
76+
retries=retries,
6777
)
6878

6979
@classmethod
@@ -74,10 +84,12 @@ def from_personal_access_token(
7484
*,
7585
endpoint: Optional[str] = None,
7686
wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = True,
87+
retries: Optional[Retry] = None,
7788
) -> Self:
7889
return cls(
7990
personal_access_token=personal_access_token,
8091
workspace_id=workspace_id,
8192
endpoint=endpoint,
8293
wait_for_action_attempt=wait_for_action_attempt,
94+
retries=retries,
8395
)

seam/seam_multi_workspace.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import Any, Dict, Optional, Union
22
import niquests as requests
33
from typing_extensions import Self
4+
from urllib3.util import Retry
45

56
from .auth import get_auth_headers_for_multi_workspace_personal_access_token
67
from .constants import LTS_VERSION
@@ -36,6 +37,7 @@ def __init__(
3637
*,
3738
endpoint: Optional[str] = None,
3839
wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = True,
40+
retries: Optional[Retry] = None,
3941
):
4042
"""
4143
Parameters
@@ -46,6 +48,8 @@ def __init__(
4648
The API endpoint to which the request should be sent.
4749
wait_for_action_attempt : bool or dict, optional
4850
Controls whether to wait for an action attempt to complete, either as a boolean or as a dictionary specifying `timeout` and `poll_interval`. Defaults to `False`.
51+
retries : urllib3.util.Retry, optional
52+
Configuration for retry behavior on failed requests.
4953
"""
5054

5155
self.lts_version = SeamMultiWorkspace.lts_version
@@ -58,6 +62,7 @@ def __init__(
5862
self.client = SeamHttpClient(
5963
base_url=endpoint,
6064
auth_headers=auth_headers,
65+
retries=retries,
6166
)
6267

6368
defaults = {"wait_for_action_attempt": wait_for_action_attempt}
@@ -72,9 +77,11 @@ def from_personal_access_token(
7277
*,
7378
endpoint: Optional[str] = None,
7479
wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = True,
80+
retries: Optional[Retry] = None,
7581
) -> Self:
7682
return cls(
7783
personal_access_token=personal_access_token,
7884
endpoint=endpoint,
7985
wait_for_action_attempt=wait_for_action_attempt,
86+
retries=retries,
8087
)

0 commit comments

Comments
 (0)