Skip to content

Commit 2ecbeea

Browse files
committed
docs: Clarify timeout_max honors a base timeout larger than the cap
1 parent 9af53e3 commit 2ecbeea

5 files changed

Lines changed: 15 additions & 6 deletions

File tree

docs/02_concepts/11_timeouts.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Every client method has a pre-assigned tier that matches the expected duration o
2525

2626
## Configuring default timeouts
2727

28-
You can override the default values for each tier in the <ApiLink to="class/ApifyClient">`ApifyClient`</ApiLink> or <ApiLink to="class/ApifyClientAsync">`ApifyClientAsync`</ApiLink> constructor. The `timeout_max` parameter sets an upper cap on the timeout for any individual API request, limiting exponential growth during retries.
28+
You can override the default values for each tier in the <ApiLink to="class/ApifyClient">`ApifyClient`</ApiLink> or <ApiLink to="class/ApifyClientAsync">`ApifyClientAsync`</ApiLink> constructor. The `timeout_max` parameter caps the exponential timeout growth during retries. A base timeout that's already larger than `timeout_max`, whether an explicit `timedelta` or a tier configured above the cap, is honored as-is.
2929

3030
<Tabs>
3131
<TabItem value="AsyncExample" label="Async client" default>

src/apify_client/_apify_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def __init__(
146146
timeout_short: Default timeout for short-duration API operations (simple CRUD operations, ...).
147147
timeout_medium: Default timeout for medium-duration API operations (batch operations, listing, ...).
148148
timeout_long: Default timeout for long-duration API operations (long-polling, streaming, ...).
149-
timeout_max: Maximum timeout cap for exponential timeout growth across retries.
149+
timeout_max: Caps exponential timeout growth across retries. A larger base timeout is honored, not clamped.
150150
headers: Additional HTTP headers to include in all API requests.
151151
compression: Compression algorithm for request bodies. Pass a string literal to select an algorithm,
152152
or an `HttpCompressor` instance for finer-grained control.
@@ -508,7 +508,7 @@ def __init__(
508508
timeout_short: Default timeout for short-duration API operations (simple CRUD operations, ...).
509509
timeout_medium: Default timeout for medium-duration API operations (batch operations, listing, ...).
510510
timeout_long: Default timeout for long-duration API operations (long-polling, streaming, ...).
511-
timeout_max: Maximum timeout cap for exponential timeout growth across retries.
511+
timeout_max: Caps exponential timeout growth across retries. A larger base timeout is honored, not clamped.
512512
headers: Additional HTTP headers to include in all API requests.
513513
compression: Compression algorithm for request bodies. Pass a string literal to select an algorithm,
514514
or an `HttpCompressor` instance for finer-grained control.

src/apify_client/http_clients/_base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def __init__(
110110
timeout_short: Default timeout for short-duration API operations (simple CRUD operations, ...).
111111
timeout_medium: Default timeout for medium-duration API operations (batch operations, listing, ...).
112112
timeout_long: Default timeout for long-duration API operations (long-polling, streaming, ...).
113-
timeout_max: Maximum timeout cap for exponential timeout growth across retries.
113+
timeout_max: Caps exponential timeout growth across retries. A larger base timeout is honored, not clamped.
114114
max_retries: Maximum number of retries for failed requests.
115115
min_delay_between_retries: Minimum delay between retries.
116116
statistics: Statistics tracker for API calls. Created automatically if not provided.

src/apify_client/http_clients/_impit.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def __init__(
8383
timeout_short: Default timeout for short-duration API operations (simple CRUD operations, ...).
8484
timeout_medium: Default timeout for medium-duration API operations (batch operations, listing, ...).
8585
timeout_long: Default timeout for long-duration API operations (long-polling, streaming, ...).
86-
timeout_max: Maximum timeout cap for exponential timeout growth across retries.
86+
timeout_max: Caps exponential timeout growth across retries. A larger base timeout is honored, not clamped.
8787
max_retries: Maximum number of retry attempts for failed requests.
8888
min_delay_between_retries: Minimum delay between retries (increases exponentially with each attempt).
8989
statistics: Statistics tracker for API calls. Created automatically if not provided.
@@ -332,7 +332,7 @@ def __init__(
332332
timeout_short: Default timeout for short-duration API operations (simple CRUD operations, ...).
333333
timeout_medium: Default timeout for medium-duration API operations (batch operations, listing, ...).
334334
timeout_long: Default timeout for long-duration API operations (long-polling, streaming, ...).
335-
timeout_max: Maximum timeout cap for exponential timeout growth across retries.
335+
timeout_max: Caps exponential timeout growth across retries. A larger base timeout is honored, not clamped.
336336
max_retries: Maximum number of retry attempts for failed requests.
337337
min_delay_between_retries: Minimum delay between retries (increases exponentially with each attempt).
338338
statistics: Statistics tracker for API calls. Created automatically if not provided.

tests/unit/test_client_timeouts.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,15 @@ def test_compute_timeout_explicit_timedelta_above_max_not_clamped() -> None:
158158
assert client._compute_timeout(timedelta(minutes=30), attempt=2) == 1800.0
159159

160160

161+
def test_compute_timeout_tier_above_max_not_clamped() -> None:
162+
"""Test a configured tier larger than timeout_max is honored, not clamped."""
163+
client = ImpitHttpClient(timeout_long=timedelta(seconds=600), timeout_max=timedelta(seconds=360))
164+
165+
assert client._compute_timeout('long', attempt=1) == 600.0
166+
# Exponential growth stays bounded by the tier's base value itself.
167+
assert client._compute_timeout('long', attempt=2) == 600.0
168+
169+
161170
async def test_dynamic_timeout_async_client(monkeypatch: pytest.MonkeyPatch) -> None:
162171
"""Tests timeout values for request with retriable errors.
163172

0 commit comments

Comments
 (0)