1313from apify_client ._consts import (
1414 DEFAULT_MAX_RETRIES ,
1515 DEFAULT_MIN_DELAY_BETWEEN_RETRIES ,
16- DEFAULT_TIMEOUT ,
1716 DEFAULT_TIMEOUT_LONG ,
1817 DEFAULT_TIMEOUT_MAX ,
18+ DEFAULT_TIMEOUT_MEDIUM ,
1919 DEFAULT_TIMEOUT_SHORT ,
20- Timeout ,
2120)
2221from apify_client ._docs import docs_group
2322from apify_client ._statistics import ClientStatistics
23+ from apify_client ._utils import to_seconds
2424
2525if TYPE_CHECKING :
2626 from collections .abc import AsyncIterator , Iterator , Mapping
2727
28- from apify_client ._consts import JsonSerializable , Timeout
28+ from apify_client ._types import JsonSerializable , Timeout
2929
3030
3131@docs_group ('HTTP clients' )
@@ -93,7 +93,7 @@ def __init__(
9393 * ,
9494 token : str | None = None ,
9595 timeout_short : timedelta = DEFAULT_TIMEOUT_SHORT ,
96- timeout : timedelta = DEFAULT_TIMEOUT ,
96+ timeout_medium : timedelta = DEFAULT_TIMEOUT_MEDIUM ,
9797 timeout_long : timedelta = DEFAULT_TIMEOUT_LONG ,
9898 timeout_max : timedelta = DEFAULT_TIMEOUT_MAX ,
9999 max_retries : int = DEFAULT_MAX_RETRIES ,
@@ -106,7 +106,7 @@ def __init__(
106106 Args:
107107 token: Apify API token for authentication.
108108 timeout_short: Timeout for fast CRUD operations (e.g., get, update, delete).
109- timeout : Timeout for batch, list, and data transfer operations.
109+ timeout_medium : Timeout for batch, list, and data transfer operations.
110110 timeout_long: Timeout for long-polling, streaming, and other heavy operations.
111111 timeout_max: Maximum timeout cap for exponential timeout growth across retries.
112112 max_retries: Maximum number of retries for failed requests.
@@ -115,7 +115,7 @@ def __init__(
115115 headers: Additional HTTP headers to include in all requests.
116116 """
117117 self ._timeout_short = timeout_short
118- self ._timeout = timeout
118+ self ._timeout_medium = timeout_medium
119119 self ._timeout_long = timeout_long
120120 self ._timeout_max = timeout_max
121121 self ._max_retries = max_retries
@@ -141,45 +141,6 @@ def __init__(
141141
142142 self ._headers = {** default_headers , ** (headers or {})}
143143
144- @property
145- def timeout_short (self ) -> timedelta :
146- """Timeout for fast CRUD operations (e.g., get, update, delete)."""
147- return self ._timeout_short
148-
149- @property
150- def timeout (self ) -> timedelta :
151- """Timeout for batch, list, and data transfer operations."""
152- return self ._timeout
153-
154- @property
155- def timeout_long (self ) -> timedelta :
156- """Timeout for long-polling, streaming, and other heavy operations."""
157- return self ._timeout_long
158-
159- @property
160- def timeout_max (self ) -> timedelta :
161- """Maximum timeout cap for exponential timeout growth across retries."""
162- return self ._timeout_max
163-
164- def _resolve_timeout (self , timeout : Timeout ) -> timedelta | None :
165- """Resolve a timeout tier literal or value to a concrete timedelta.
166-
167- Args:
168- timeout: The timeout specification to resolve.
169-
170- Returns:
171- A `timedelta` for tier literals and explicit values, `None` for `'no_timeout'`.
172- """
173- if timeout == 'no_timeout' :
174- return None
175- if timeout == 'short' :
176- return self ._timeout_short
177- if timeout == 'default' :
178- return self ._timeout
179- if timeout == 'long' :
180- return self ._timeout_long
181- return timeout
182-
183144 @staticmethod
184145 def _parse_params (params : dict [str , Any ] | None ) -> dict [str , Any ] | None :
185146 """Convert request parameters to Apify API-compatible formats.
@@ -204,6 +165,34 @@ def _parse_params(params: dict[str, Any] | None) -> dict[str, Any] | None:
204165
205166 return parsed_params
206167
168+ def _compute_timeout (self , timeout : Timeout , attempt : int ) -> int | float | None :
169+ """Resolve a timeout tier and compute the timeout for a request attempt with exponential increase.
170+
171+ For `'no_timeout'`, returns `None`. For tier literals and explicit `timedelta` values, doubles the timeout
172+ with each attempt but caps at `timeout_max`.
173+
174+ Args:
175+ timeout: The timeout specification to resolve (tier literal or explicit `timedelta`).
176+ attempt: Current attempt number (1-indexed).
177+
178+ Returns:
179+ Timeout in seconds, or `None` for `'no_timeout'`.
180+ """
181+ if timeout == 'no_timeout' :
182+ return None
183+
184+ if timeout == 'short' :
185+ resolved = self ._timeout_short
186+ elif timeout == 'medium' :
187+ resolved = self ._timeout_medium
188+ elif timeout == 'long' :
189+ resolved = self ._timeout_long
190+ else :
191+ resolved = timeout
192+
193+ new_timeout = min (resolved * (2 ** (attempt - 1 )), self ._timeout_max )
194+ return to_seconds (new_timeout )
195+
207196 def _prepare_request_call (
208197 self ,
209198 headers : dict [str , str ] | None = None ,
@@ -268,7 +257,7 @@ def call(
268257 data : str | bytes | bytearray | None = None ,
269258 json : Any = None ,
270259 stream : bool | None = None ,
271- timeout : Timeout = 'default ' ,
260+ timeout : Timeout = 'medium ' ,
272261 ) -> HttpResponse :
273262 """Make an HTTP request.
274263
@@ -280,9 +269,9 @@ def call(
280269 data: Raw request body data. Cannot be used together with json.
281270 json: JSON-serializable data for the request body. Cannot be used together with data.
282271 stream: Whether to stream the response body.
283- timeout: Timeout for the API HTTP request.
284- Use `'short'`, `'default'`, or `'long '` tier literals for preconfigured timeouts.
285- A `timedelta` overrides it for this call, and `'no_timeout'` disables the timeout entirely.
272+ timeout: Timeout for the API HTTP request. Use `'short'`, `'medium'`, or `'long'` tier literals for
273+ preconfigured timeouts. A `timedelta` overrides it for this call, and `'no_timeout '` disables
274+ the timeout entirely.
286275
287276 Returns:
288277 The HTTP response object.
@@ -312,7 +301,7 @@ async def call(
312301 data : str | bytes | bytearray | None = None ,
313302 json : Any = None ,
314303 stream : bool | None = None ,
315- timeout : Timeout = 'default ' ,
304+ timeout : Timeout = 'medium ' ,
316305 ) -> HttpResponse :
317306 """Make an HTTP request.
318307
@@ -324,9 +313,9 @@ async def call(
324313 data: Raw request body data. Cannot be used together with json.
325314 json: JSON-serializable data for the request body. Cannot be used together with data.
326315 stream: Whether to stream the response body.
327- timeout: Timeout for the API HTTP request.
328- Use `'short'`, `'default'`, or `'long '` tier literals for preconfigured timeouts.
329- A `timedelta` overrides it for this call, and `'no_timeout'` disables the timeout entirely.
316+ timeout: Timeout for the API HTTP request. Use `'short'`, `'medium'`, or `'long'` tier literals for
317+ preconfigured timeouts. A `timedelta` overrides it for this call, and `'no_timeout '` disables
318+ the timeout entirely.
330319
331320 Returns:
332321 The HTTP response object.
0 commit comments