Spaces:
Paused
Paused
Mirrowel
fix(timeout): π increase streaming read timeout to 5 minutes - 3 minute timeouts failed sometimes
0a45558
| # src/rotator_library/timeout_config.py | |
| """ | |
| Centralized timeout configuration for HTTP requests. | |
| All values can be overridden via environment variables: | |
| TIMEOUT_CONNECT - Connection establishment timeout (default: 30s) | |
| TIMEOUT_WRITE - Request body send timeout (default: 30s) | |
| TIMEOUT_POOL - Connection pool acquisition timeout (default: 60s) | |
| TIMEOUT_READ_STREAMING - Read timeout between chunks for streaming (default: 180s / 3 min) | |
| TIMEOUT_READ_NON_STREAMING - Read timeout for non-streaming responses (default: 600s / 10 min) | |
| """ | |
| import os | |
| import logging | |
| import httpx | |
| lib_logger = logging.getLogger("rotator_library") | |
| class TimeoutConfig: | |
| """ | |
| Centralized timeout configuration for HTTP requests. | |
| All values can be overridden via environment variables. | |
| """ | |
| # Default values (in seconds) | |
| _CONNECT = 30.0 | |
| _WRITE = 30.0 | |
| _POOL = 60.0 | |
| _READ_STREAMING = 300.0 # 5 minutes between chunks | |
| _READ_NON_STREAMING = 600.0 # 10 minutes for full response | |
| def _get_env_float(cls, key: str, default: float) -> float: | |
| """Get a float value from environment variable, or return default.""" | |
| value = os.environ.get(key) | |
| if value is not None: | |
| try: | |
| return float(value) | |
| except ValueError: | |
| lib_logger.warning( | |
| f"Invalid value for {key}: {value}. Using default: {default}" | |
| ) | |
| return default | |
| def connect(cls) -> float: | |
| """Connection establishment timeout.""" | |
| return cls._get_env_float("TIMEOUT_CONNECT", cls._CONNECT) | |
| def write(cls) -> float: | |
| """Request body send timeout.""" | |
| return cls._get_env_float("TIMEOUT_WRITE", cls._WRITE) | |
| def pool(cls) -> float: | |
| """Connection pool acquisition timeout.""" | |
| return cls._get_env_float("TIMEOUT_POOL", cls._POOL) | |
| def read_streaming(cls) -> float: | |
| """Read timeout between chunks for streaming requests.""" | |
| return cls._get_env_float("TIMEOUT_READ_STREAMING", cls._READ_STREAMING) | |
| def read_non_streaming(cls) -> float: | |
| """Read timeout for non-streaming responses.""" | |
| return cls._get_env_float("TIMEOUT_READ_NON_STREAMING", cls._READ_NON_STREAMING) | |
| def streaming(cls) -> httpx.Timeout: | |
| """ | |
| Timeout configuration for streaming LLM requests. | |
| Uses a shorter read timeout (default 3 min) since we expect | |
| periodic chunks. If no data arrives for this duration, the | |
| connection is considered stalled. | |
| """ | |
| return httpx.Timeout( | |
| connect=cls.connect(), | |
| read=cls.read_streaming(), | |
| write=cls.write(), | |
| pool=cls.pool(), | |
| ) | |
| def non_streaming(cls) -> httpx.Timeout: | |
| """ | |
| Timeout configuration for non-streaming LLM requests. | |
| Uses a longer read timeout (default 10 min) since the server | |
| may take significant time to generate the complete response | |
| before sending anything back. | |
| """ | |
| return httpx.Timeout( | |
| connect=cls.connect(), | |
| read=cls.read_non_streaming(), | |
| write=cls.write(), | |
| pool=cls.pool(), | |
| ) | |