11import json
2+ import time
23from collections .abc import AsyncIterator
34from contextlib import AbstractAsyncContextManager , asynccontextmanager
45from dataclasses import dataclass
5- from typing import Any , Generic , Protocol , TypeVar , cast , overload
6+ from typing import Any , Generic , Literal , Protocol , TypeVar , cast , overload
67
78import httpx
89
9- from deepset_mcp .api .exceptions import BadRequestError , ResourceNotFoundError , UnexpectedAPIError
10+ from deepset_mcp .api .exceptions import BadRequestError , RequestTimeoutError , ResourceNotFoundError , UnexpectedAPIError
1011
1112T = TypeVar ("T" )
1213
@@ -111,16 +112,34 @@ class TransportProtocol(Protocol):
111112
112113 @overload
113114 async def request (
114- self , method : str , url : str , * , response_type : type [T ], ** kwargs : Any
115+ self ,
116+ method : str ,
117+ url : str ,
118+ * ,
119+ response_type : type [T ],
120+ timeout : float | None | Literal ["config" ] = "config" ,
121+ ** kwargs : Any ,
115122 ) -> TransportResponse [T ]: ...
116123
117124 @overload
118125 async def request (
119- self , method : str , url : str , * , response_type : None = None , ** kwargs : Any
126+ self ,
127+ method : str ,
128+ url : str ,
129+ * ,
130+ response_type : None = None ,
131+ timeout : float | None | Literal ["config" ] = "config" ,
132+ ** kwargs : Any ,
120133 ) -> TransportResponse [Any ]: ...
121134
122135 async def request (
123- self , method : str , url : str , * , response_type : type [T ] | None = None , ** kwargs : Any
136+ self ,
137+ method : str ,
138+ url : str ,
139+ * ,
140+ response_type : type [T ] | None = None ,
141+ timeout : float | None | Literal ["config" ] = "config" ,
142+ ** kwargs : Any ,
124143 ) -> TransportResponse [Any ]:
125144 """Send a regular HTTP request and return the response."""
126145 ...
@@ -189,16 +208,34 @@ def __init__(
189208
190209 @overload
191210 async def request (
192- self , method : str , url : str , * , response_type : type [T ], ** kwargs : Any
211+ self ,
212+ method : str ,
213+ url : str ,
214+ * ,
215+ response_type : type [T ],
216+ timeout : float | None | Literal ["config" ] = "config" ,
217+ ** kwargs : Any ,
193218 ) -> TransportResponse [T ]: ...
194219
195220 @overload
196221 async def request (
197- self , method : str , url : str , * , response_type : None = None , ** kwargs : Any
222+ self ,
223+ method : str ,
224+ url : str ,
225+ * ,
226+ response_type : None = None ,
227+ timeout : float | None | Literal ["config" ] = "config" ,
228+ ** kwargs : Any ,
198229 ) -> TransportResponse [Any ]: ...
199230
200231 async def request (
201- self , method : str , url : str , * , response_type : type [T ] | None = None , ** kwargs : Any
232+ self ,
233+ method : str ,
234+ url : str ,
235+ * ,
236+ response_type : type [T ] | None = None ,
237+ timeout : float | None | Literal ["config" ] = "config" ,
238+ ** kwargs : Any ,
202239 ) -> TransportResponse [Any ]:
203240 """
204241 Send a regular HTTP request and return the response.
@@ -211,6 +248,9 @@ async def request(
211248 URL endpoint
212249 response_type : type[T], optional
213250 Expected response type for type checking
251+ timeout : float | None | Literal["config"], optional
252+ Request timeout in seconds. If "config", uses transport config timeout.
253+ If None, disables timeout. If float, uses specific timeout.
214254 **kwargs : Any
215255 Additional arguments to pass to httpx
216256
@@ -219,7 +259,26 @@ async def request(
219259 TransportResponse[T]
220260 The response with parsed JSON if available
221261 """
222- response = await self ._client .request (method , url , ** kwargs )
262+ if timeout != "config" :
263+ kwargs ["timeout" ] = timeout
264+
265+ start_time = time .time ()
266+ try :
267+ response = await self ._client .request (method , url , ** kwargs )
268+ except httpx .TimeoutException as e :
269+ duration = time .time () - start_time
270+ timeout_value = kwargs .get ("timeout" , "config default" )
271+
272+ detail = None
273+ if "search" in url and duration > 60 :
274+ detail = (
275+ "Search operations can take longer with large document collections or complex pipelines. "
276+ "Consider increasing the timeout for search requests."
277+ )
278+
279+ raise RequestTimeoutError (
280+ method = method , url = url , timeout = timeout_value , duration = duration , detail = detail
281+ ) from e
223282
224283 if response_type is not None :
225284 raw = response .json ()
0 commit comments