feat: standardize timeout values to floats in seconds (#1766)
This commit is contained in:
parent
4807eb5a80
commit
2aa1ad2a69
6 changed files with 38 additions and 49 deletions
|
|
@ -1,5 +1,4 @@
|
|||
import logging
|
||||
from datetime import timedelta
|
||||
from typing import Any, Protocol, overload
|
||||
|
||||
import anyio.lowlevel
|
||||
|
|
@ -113,7 +112,7 @@ class ClientSession(
|
|||
self,
|
||||
read_stream: MemoryObjectReceiveStream[SessionMessage | Exception],
|
||||
write_stream: MemoryObjectSendStream[SessionMessage],
|
||||
read_timeout_seconds: timedelta | None = None,
|
||||
read_timeout_seconds: float | None = None,
|
||||
sampling_callback: SamplingFnT | None = None,
|
||||
elicitation_callback: ElicitationFnT | None = None,
|
||||
list_roots_callback: ListRootsFnT | None = None,
|
||||
|
|
@ -369,7 +368,7 @@ class ClientSession(
|
|||
self,
|
||||
name: str,
|
||||
arguments: dict[str, Any] | None = None,
|
||||
read_timeout_seconds: timedelta | None = None,
|
||||
read_timeout_seconds: float | None = None,
|
||||
progress_callback: ProgressFnT | None = None,
|
||||
*,
|
||||
meta: dict[str, Any] | None = None,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import contextlib
|
|||
import logging
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from datetime import timedelta
|
||||
from types import TracebackType
|
||||
from typing import Any, TypeAlias, overload
|
||||
|
||||
|
|
@ -41,11 +40,11 @@ class SseServerParameters(BaseModel):
|
|||
# Optional headers to include in requests.
|
||||
headers: dict[str, Any] | None = None
|
||||
|
||||
# HTTP timeout for regular operations.
|
||||
timeout: float = 5
|
||||
# HTTP timeout for regular operations (in seconds).
|
||||
timeout: float = 5.0
|
||||
|
||||
# Timeout for SSE read operations.
|
||||
sse_read_timeout: float = 60 * 5
|
||||
# Timeout for SSE read operations (in seconds).
|
||||
sse_read_timeout: float = 300.0
|
||||
|
||||
|
||||
class StreamableHttpParameters(BaseModel):
|
||||
|
|
@ -57,11 +56,11 @@ class StreamableHttpParameters(BaseModel):
|
|||
# Optional headers to include in requests.
|
||||
headers: dict[str, Any] | None = None
|
||||
|
||||
# HTTP timeout for regular operations.
|
||||
timeout: timedelta = timedelta(seconds=30)
|
||||
# HTTP timeout for regular operations (in seconds).
|
||||
timeout: float = 30.0
|
||||
|
||||
# Timeout for SSE read operations.
|
||||
sse_read_timeout: timedelta = timedelta(seconds=60 * 5)
|
||||
# Timeout for SSE read operations (in seconds).
|
||||
sse_read_timeout: float = 300.0
|
||||
|
||||
# Close the client session when the transport closes.
|
||||
terminate_on_close: bool = True
|
||||
|
|
@ -76,7 +75,7 @@ ServerParameters: TypeAlias = StdioServerParameters | SseServerParameters | Stre
|
|||
class ClientSessionParameters:
|
||||
"""Parameters for establishing a client session to an MCP server."""
|
||||
|
||||
read_timeout_seconds: timedelta | None = None
|
||||
read_timeout_seconds: float | None = None
|
||||
sampling_callback: SamplingFnT | None = None
|
||||
elicitation_callback: ElicitationFnT | None = None
|
||||
list_roots_callback: ListRootsFnT | None = None
|
||||
|
|
@ -197,7 +196,7 @@ class ClientSessionGroup:
|
|||
self,
|
||||
name: str,
|
||||
arguments: dict[str, Any],
|
||||
read_timeout_seconds: timedelta | None = None,
|
||||
read_timeout_seconds: float | None = None,
|
||||
progress_callback: ProgressFnT | None = None,
|
||||
*,
|
||||
meta: dict[str, Any] | None = None,
|
||||
|
|
@ -210,7 +209,7 @@ class ClientSessionGroup:
|
|||
name: str,
|
||||
*,
|
||||
args: dict[str, Any],
|
||||
read_timeout_seconds: timedelta | None = None,
|
||||
read_timeout_seconds: float | None = None,
|
||||
progress_callback: ProgressFnT | None = None,
|
||||
meta: dict[str, Any] | None = None,
|
||||
) -> types.CallToolResult: ...
|
||||
|
|
@ -219,7 +218,7 @@ class ClientSessionGroup:
|
|||
self,
|
||||
name: str,
|
||||
arguments: dict[str, Any] | None = None,
|
||||
read_timeout_seconds: timedelta | None = None,
|
||||
read_timeout_seconds: float | None = None,
|
||||
progress_callback: ProgressFnT | None = None,
|
||||
*,
|
||||
meta: dict[str, Any] | None = None,
|
||||
|
|
@ -314,8 +313,8 @@ class ClientSessionGroup:
|
|||
httpx_client = create_mcp_http_client(
|
||||
headers=server_params.headers,
|
||||
timeout=httpx.Timeout(
|
||||
server_params.timeout.total_seconds(),
|
||||
read=server_params.sse_read_timeout.total_seconds(),
|
||||
server_params.timeout,
|
||||
read=server_params.sse_read_timeout,
|
||||
),
|
||||
)
|
||||
await session_stack.enter_async_context(httpx_client)
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ def _extract_session_id_from_endpoint(endpoint_url: str) -> str | None:
|
|||
async def sse_client(
|
||||
url: str,
|
||||
headers: dict[str, Any] | None = None,
|
||||
timeout: float = 5,
|
||||
sse_read_timeout: float = 60 * 5,
|
||||
timeout: float = 5.0,
|
||||
sse_read_timeout: float = 300.0,
|
||||
httpx_client_factory: McpHttpClientFactory = create_mcp_http_client,
|
||||
auth: httpx.Auth | None = None,
|
||||
on_session_created: Callable[[str], None] | None = None,
|
||||
|
|
@ -46,8 +46,8 @@ async def sse_client(
|
|||
Args:
|
||||
url: The SSE endpoint URL.
|
||||
headers: Optional headers to include in requests.
|
||||
timeout: HTTP timeout for regular operations.
|
||||
sse_read_timeout: Timeout for SSE read operations.
|
||||
timeout: HTTP timeout for regular operations (in seconds).
|
||||
sse_read_timeout: Timeout for SSE read operations (in seconds).
|
||||
auth: Optional HTTPX authentication handler.
|
||||
on_session_created: Optional callback invoked with the session ID when received.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -100,8 +100,8 @@ class StreamableHTTPTransport:
|
|||
self,
|
||||
url: str,
|
||||
headers: dict[str, str] | None = None,
|
||||
timeout: float | timedelta = 30,
|
||||
sse_read_timeout: float | timedelta = 60 * 5,
|
||||
timeout: float = 30.0,
|
||||
sse_read_timeout: float = 300.0,
|
||||
auth: httpx.Auth | None = None,
|
||||
) -> None: ...
|
||||
|
||||
|
|
@ -118,8 +118,8 @@ class StreamableHTTPTransport:
|
|||
Args:
|
||||
url: The endpoint URL.
|
||||
headers: Optional headers to include in requests.
|
||||
timeout: HTTP timeout for regular operations.
|
||||
sse_read_timeout: Timeout for SSE read operations.
|
||||
timeout: HTTP timeout for regular operations (in seconds).
|
||||
sse_read_timeout: Timeout for SSE read operations (in seconds).
|
||||
auth: Optional HTTPX authentication handler.
|
||||
"""
|
||||
# Check for deprecated parameters and issue runtime warning
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ from __future__ import annotations
|
|||
|
||||
from collections.abc import AsyncGenerator
|
||||
from contextlib import asynccontextmanager
|
||||
from datetime import timedelta
|
||||
from typing import Any
|
||||
|
||||
import anyio
|
||||
|
|
@ -49,7 +48,7 @@ async def create_client_server_memory_streams() -> AsyncGenerator[tuple[MessageS
|
|||
@asynccontextmanager
|
||||
async def create_connected_server_and_client_session(
|
||||
server: Server[Any] | FastMCP,
|
||||
read_timeout_seconds: timedelta | None = None,
|
||||
read_timeout_seconds: float | None = None,
|
||||
sampling_callback: SamplingFnT | None = None,
|
||||
list_roots_callback: ListRootsFnT | None = None,
|
||||
logging_callback: LoggingFnT | None = None,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import logging
|
||||
from collections.abc import Callable
|
||||
from contextlib import AsyncExitStack
|
||||
from datetime import timedelta
|
||||
from types import TracebackType
|
||||
from typing import Any, Generic, Protocol, TypeVar
|
||||
|
||||
|
|
@ -189,7 +188,7 @@ class BaseSession(
|
|||
receive_request_type: type[ReceiveRequestT],
|
||||
receive_notification_type: type[ReceiveNotificationT],
|
||||
# If none, reading will never time out
|
||||
read_timeout_seconds: timedelta | None = None,
|
||||
read_timeout_seconds: float | None = None,
|
||||
) -> None:
|
||||
self._read_stream = read_stream
|
||||
self._write_stream = write_stream
|
||||
|
|
@ -241,7 +240,7 @@ class BaseSession(
|
|||
self,
|
||||
request: SendRequestT,
|
||||
result_type: type[ReceiveResultT],
|
||||
request_read_timeout_seconds: timedelta | None = None,
|
||||
request_read_timeout_seconds: float | None = None,
|
||||
metadata: MessageMetadata = None,
|
||||
progress_callback: ProgressFnT | None = None,
|
||||
) -> ReceiveResultT:
|
||||
|
|
@ -283,9 +282,9 @@ class BaseSession(
|
|||
# request read timeout takes precedence over session read timeout
|
||||
timeout = None
|
||||
if request_read_timeout_seconds is not None: # pragma: no cover
|
||||
timeout = request_read_timeout_seconds.total_seconds()
|
||||
timeout = request_read_timeout_seconds
|
||||
elif self._session_read_timeout_seconds is not None: # pragma: no cover
|
||||
timeout = self._session_read_timeout_seconds.total_seconds()
|
||||
timeout = self._session_read_timeout_seconds
|
||||
|
||||
try:
|
||||
with anyio.fail_after(timeout):
|
||||
|
|
|
|||
Loading…
Reference in a new issue