simbiot-harness/venv/lib/python3.12/site-packages/mcp/shared/_httpx_utils.py
Simbiot Harness b60439152b Simbiot Harness v0.1: тактовая лестница на Strands + CQRS/ES-спина
- harness/es.py: append-only event store + проекции (образец — кооп-портал)
- harness/levels.py: уровни 1с/1м/1ч/1д, контекст ∝ масштабу
- harness/scheduler.py: уровневые потоки, идемпотентные тики, absorbed-стабы
- harness/isolated_runner.py + _llm_worker.py: LLM-тик в сабпроцессе
  (глобальный asyncio-рантайм Strands не переживает 2+ create_harness)
- cli.py: init/task/tasks/status/events + requeue (написан самим минутным агентом)
- 9router: отдельный ключ sk-simbiot, модель auto (glm-5.3 первым)
2026-09-29 15:28:50 +00:00

95 lines
2.9 KiB
Python

"""Utilities for creating standardized httpx2 AsyncClient instances."""
from typing import Any, Protocol
import httpx2
__all__ = ["create_mcp_http_client", "MCP_DEFAULT_TIMEOUT", "MCP_DEFAULT_SSE_READ_TIMEOUT"]
# Default MCP timeout configuration
MCP_DEFAULT_TIMEOUT = 30.0 # General operations (seconds)
MCP_DEFAULT_SSE_READ_TIMEOUT = 300.0 # SSE streams - 5 minutes (seconds)
class McpHttpClientFactory(Protocol): # pragma: no branch
def __call__( # pragma: no branch
self,
headers: dict[str, str] | None = None,
timeout: httpx2.Timeout | None = None,
auth: httpx2.Auth | None = None,
) -> httpx2.AsyncClient: ...
def create_mcp_http_client(
headers: dict[str, str] | None = None,
timeout: httpx2.Timeout | None = None,
auth: httpx2.Auth | None = None,
) -> httpx2.AsyncClient:
"""Create a standardized httpx2 AsyncClient with MCP defaults.
Always enables follow_redirects and applies an SSE-friendly default timeout.
Args:
headers: Optional headers to include with all requests.
timeout: Request timeout as httpx2.Timeout object. Defaults to 30s for
connect/write/pool and 300s for read (for long-lived SSE streams).
auth: Optional authentication handler.
Returns:
Configured httpx2.AsyncClient instance with MCP defaults.
Note:
The returned AsyncClient must be used as a context manager to ensure
proper cleanup of connections.
Example:
Basic usage with MCP defaults:
```python
async with create_mcp_http_client() as client:
response = await client.get("https://api.example.com")
```
With custom headers:
```python
headers = {"Authorization": "Bearer token"}
async with create_mcp_http_client(headers) as client:
response = await client.get("/endpoint")
```
With both custom headers and timeout:
```python
timeout = httpx2.Timeout(60.0, read=300.0)
async with create_mcp_http_client(headers, timeout) as client:
response = await client.get("/long-request")
```
With authentication:
```python
from httpx2 import BasicAuth
auth = BasicAuth(username="user", password="pass")
async with create_mcp_http_client(headers, timeout, auth) as client:
response = await client.get("/protected-endpoint")
```
"""
# Set MCP defaults
kwargs: dict[str, Any] = {"follow_redirects": True}
# Handle timeout
if timeout is None:
kwargs["timeout"] = httpx2.Timeout(MCP_DEFAULT_TIMEOUT, read=MCP_DEFAULT_SSE_READ_TIMEOUT)
else:
kwargs["timeout"] = timeout
# Handle headers
if headers is not None:
kwargs["headers"] = headers
# Handle authentication
if auth is not None: # pragma: no cover
kwargs["auth"] = auth
return httpx2.AsyncClient(**kwargs)