Skip to content

Commit b502193

Browse files
feat: Setup common default timeout (box/box-codegen#965) (#1507)
1 parent c083ad0 commit b502193

6 files changed

Lines changed: 39 additions & 30 deletions

File tree

‎.codegen.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ "engineHash": "6f9492d", "specHash": "131c54a", "version": "10.12.0" }
1+
{ "engineHash": "ed5236c", "specHash": "131c54a", "version": "10.12.0" }

‎box_sdk_gen/networking/box_network_client.py‎

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class APIRequest:
4242
data: Optional[Union[str, ByteStream, MultipartEncoder]]
4343
content_type: Optional[str] = None
4444
allow_redirects: bool = True
45-
timeout: Optional[Tuple[Optional[float], Optional[float]]] = None
45+
timeout: Optional[Union[float, Tuple[Optional[float], Optional[float]]]] = None
4646

4747

4848
@dataclass
@@ -189,36 +189,34 @@ def _prepare_request(
189189
@staticmethod
190190
def _get_request_timeout(
191191
options: 'FetchOptions',
192-
) -> Optional[Tuple[Optional[float], Optional[float]]]:
192+
) -> Optional[Union[float, Tuple[Optional[float], Optional[float]]]]:
193193
"""
194-
Derive requests timeout tuple (connect, read) in seconds.
194+
Derive requests timeout in seconds.
195195
196196
Uses `options.network_session.timeout_config` when present.
197197
The timeout config values are expected to be in milliseconds.
198+
199+
Returns a tuple (connect, read) when both timeouts are specified,
200+
a single float when only one is set, or None to use no timeout.
198201
"""
199202
network_session = options.network_session
200203
timeout_config = network_session.timeout_config if network_session else None
201204
if timeout_config is None:
202205
return None
203206

204-
connection_timeout_ms, read_timeout_ms = (
205-
timeout_config.connection_timeout_ms,
206-
timeout_config.read_timeout_ms,
207-
)
207+
connection_timeout_ms = timeout_config.connection_timeout_ms
208+
read_timeout_ms = timeout_config.read_timeout_ms
208209

209210
if connection_timeout_ms is None and read_timeout_ms is None:
210211
return None
211212

212-
connection_timeout_sec = (
213-
connection_timeout_ms / 1000.0
214-
if connection_timeout_ms is not None
215-
else None
216-
)
217-
read_timeout_sec = (
218-
read_timeout_ms / 1000.0 if read_timeout_ms is not None else None
219-
)
213+
if connection_timeout_ms is not None and read_timeout_ms is not None:
214+
return (connection_timeout_ms / 1000.0, read_timeout_ms / 1000.0)
215+
216+
if connection_timeout_ms is not None:
217+
return connection_timeout_ms / 1000.0
220218

221-
return (connection_timeout_sec, read_timeout_sec)
219+
return read_timeout_ms / 1000.0
222220

223221
@staticmethod
224222
def _prepare_headers(

‎box_sdk_gen/networking/network.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def __init__(
4242
data_sanitizer = DataSanitizer()
4343
if timeout_config is None:
4444
timeout_config = TimeoutConfig(
45-
connection_timeout_ms=5000,
45+
connection_timeout_ms=10000,
4646
read_timeout_ms=60000,
4747
)
4848
self.additional_headers = additional_headers

‎docs/client.md‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,13 @@ new_client = client.with_custom_base_urls(
158158

159159
In order to configure timeout for API calls, calling the `client.with_timeouts(config)` method creates a new client with timeout settings, leaving the original client unmodified.
160160

161+
All timeout values are in milliseconds.
162+
161163
```python
162-
timeout_config = TimeoutConfig(connection_timeout_ms=10000, read_timeout_ms=30000)
164+
timeout_config = TimeoutConfig(
165+
connection_timeout_ms=5000,
166+
read_timeout_ms=30000,
167+
)
163168
new_client = client.with_timeouts(timeout_config)
164169
```
165170

‎docs/configuration.md‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,14 +194,19 @@ client = BoxClient(auth=auth, network_session=network_session)
194194
## Timeouts
195195

196196
You can configure network timeouts with `TimeoutConfig` on `NetworkSession`.
197-
Python SDK supports separate connection and read timeout values in milliseconds.
197+
The SDK supports two timeout values, both in milliseconds:
198+
199+
| Parameter | Description |
200+
| ----------------------- | ------------------------------------------------------------------ |
201+
| `connection_timeout_ms` | Maximum time to wait for the TCP connection to be established. |
202+
| `read_timeout_ms` | Maximum idle time between data packets while reading the response. |
198203

199204
```python
200205
from box_sdk_gen import BoxClient, BoxDeveloperTokenAuth, NetworkSession, TimeoutConfig
201206

202207
auth = BoxDeveloperTokenAuth(token="DEVELOPER_TOKEN_GOES_HERE")
203208
timeout_config = TimeoutConfig(
204-
connection_timeout_ms=10000,
209+
connection_timeout_ms=5000,
205210
read_timeout_ms=30000,
206211
)
207212
network_session = NetworkSession(timeout_config=timeout_config)
@@ -211,9 +216,10 @@ client = BoxClient(auth=auth, network_session=network_session)
211216
How timeout handling works:
212217

213218
- Timeout values are configured in milliseconds and converted to seconds internally for HTTP requests.
214-
- If timeout config is not provided, the SDK uses default timeouts: `connection_timeout_ms=5000` (5 seconds) and `read_timeout_ms=60000` (60 seconds).
219+
- If timeout config is not provided, the SDK uses default timeouts: `connection_timeout_ms=10000` (10 seconds) and `read_timeout_ms=60000` (60 seconds).
220+
- When both `connection_timeout_ms` and `read_timeout_ms` are set, the SDK passes them as a `(connect, read)` tuple to the underlying `requests` library.
221+
- When only one timeout is set, it applies as a single timeout value for the request.
215222
- To disable all SDK timeouts, pass `TimeoutConfig(connection_timeout_ms=None, read_timeout_ms=None)` explicitly to `NetworkSession`.
216-
- You can also disable only one timeout by setting one value to `None` (for example, `connection_timeout_ms=None` or `read_timeout_ms=None`). If you provide only the other value (for example, `read_timeout_ms=30000`) and leave one unspecified, the unspecified field remains `None` and that timeout stays disabled.
217223
- Timeout failures are treated as network exceptions, and retry behavior is controlled by the configured retry strategy.
218224
- Timeout applies to a single HTTP request attempt to the Box API (not the total time across all retries).
219225
- If retries are exhausted, the SDK raises `BoxSDKError` with the underlying request exception.

‎test/box_network_client.py‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ def network_session_mock():
178178
def test_network_session_uses_default_timeout_config_values():
179179
network_session = NetworkSession()
180180

181-
assert network_session.timeout_config.connection_timeout_ms == 5000
181+
assert network_session.timeout_config.connection_timeout_ms == 10000
182182
assert network_session.timeout_config.read_timeout_ms == 60000
183183

184184

@@ -191,7 +191,7 @@ def test_prepare_request_uses_default_network_session_timeouts(network_client):
191191

192192
api_request = network_client._prepare_request(options=options)
193193

194-
assert api_request.timeout == (5, 60)
194+
assert api_request.timeout == (10, 60)
195195

196196

197197
@pytest.fixture
@@ -339,7 +339,7 @@ def test_prepare_json_request(network_client, network_session_mock):
339339
params={"param": "value"},
340340
data='{"key": "value"}',
341341
content_type="application/json",
342-
timeout=(5, 60),
342+
timeout=(10, 60),
343343
)
344344

345345

@@ -727,7 +727,7 @@ def test_retrying_401_response_with_new_token_and_auth_provided(
727727
data=None,
728728
stream=True,
729729
allow_redirects=True,
730-
timeout=(5, 60),
730+
timeout=(10, 60),
731731
),
732732
mock.call(
733733
method="GET",
@@ -742,7 +742,7 @@ def test_retrying_401_response_with_new_token_and_auth_provided(
742742
data=None,
743743
stream=True,
744744
allow_redirects=True,
745-
timeout=(5, 60),
745+
timeout=(10, 60),
746746
),
747747
],
748748
)
@@ -782,7 +782,7 @@ def test_not_retrying_401_when_auth_not_provided(
782782
data=None,
783783
stream=True,
784784
allow_redirects=True,
785-
timeout=(5, 60),
785+
timeout=(10, 60),
786786
)
787787

788788

@@ -1244,5 +1244,5 @@ def test_disable_follow_redirects(
12441244
data=None,
12451245
stream=True,
12461246
allow_redirects=False,
1247-
timeout=(5, 60),
1247+
timeout=(10, 60),
12481248
)

0 commit comments

Comments
 (0)