Skip to content

Commit b1fd31b

Browse files
committed
feat: Setup common default timeout (box/box-codegen#965)
1 parent 94ca5e9 commit b1fd31b

6 files changed

Lines changed: 37 additions & 31 deletions

File tree

.codegen.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ "engineHash": "9c2d390", "specHash": "131c54a", "version": "4.12.0" }
1+
{ "engineHash": "ed5236c", "specHash": "131c54a", "version": "4.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/box_sdk_gen/client.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,12 @@ new_client = client.with_custom_base_urls(base_urls=BaseUrls(
156156

157157
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.
158158

159+
All timeout values are in milliseconds.
160+
159161
```python
160162
timeout_config = TimeoutConfig(
161-
connection_timeout_ms=10000,
162-
read_timeout_ms=30000
163+
connection_timeout_ms=5000,
164+
read_timeout_ms=30000,
163165
)
164166
new_client = client.with_timeouts(timeout_config)
165167
```

docs/box_sdk_gen/configuration.md

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

185185
You can configure network timeouts with `TimeoutConfig` on `NetworkSession`.
186-
Python SDK supports separate connection and read timeout values in milliseconds.
186+
The SDK supports two timeout values, both in milliseconds:
187+
188+
| Parameter | Description |
189+
| ----------------------- | ------------------------------------------------------------------ |
190+
| `connection_timeout_ms` | Maximum time to wait for the TCP connection to be established. |
191+
| `read_timeout_ms` | Maximum idle time between data packets while reading the response. |
187192

188193
```python
189194
from box_sdk_gen import BoxClient, BoxDeveloperTokenAuth, NetworkSession, TimeoutConfig
190195

191196
auth = BoxDeveloperTokenAuth(token='DEVELOPER_TOKEN_GOES_HERE')
192197
timeout_config = TimeoutConfig(
193-
connection_timeout_ms=10000,
198+
connection_timeout_ms=5000,
194199
read_timeout_ms=30000,
195200
)
196201
network_session = NetworkSession(timeout_config=timeout_config)
@@ -200,9 +205,10 @@ client = BoxClient(auth=auth, network_session=network_session)
200205
How timeout handling works:
201206

202207
- Timeout values are configured in milliseconds and converted to seconds internally for HTTP requests.
203-
- If timeout config is not provided, the SDK uses default timeouts: `connection_timeout_ms=5000` (5 seconds) and `read_timeout_ms=60000` (60 seconds).
208+
- If timeout config is not provided, the SDK uses default timeouts: `connection_timeout_ms=10000` (10 seconds) and `read_timeout_ms=60000` (60 seconds).
209+
- 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.
210+
- When only one timeout is set, it applies as a single timeout value for the request.
204211
- To disable all SDK timeouts, pass `TimeoutConfig(connection_timeout_ms=None, read_timeout_ms=None)` explicitly to `NetworkSession`.
205-
- 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.
206212
- Timeout failures are treated as network exceptions, and retry behavior is controlled by the configured retry strategy.
207213
- Timeout applies to a single HTTP request attempt to the Box API (not the total time across all retries).
208214
- If retries are exhausted, the SDK raises `BoxSDKError` with the underlying request exception.

test/box_sdk_gen/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)