mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
request_timeout was shadowed by router_settings.timeout: Router stored a single slot via `self.timeout = timeout or litellm.request_timeout`, so when a router timeout was set the configured request_timeout was never used. Provider calls with no per-model timeout (Bedrock especially) then fell back to the hardcoded 600s httpx client default. Mirrors PR #25701 and completes it on top of the CompletionTimeout work already on this branch. - Router: add an independent self.request_timeout and prefer it over router_settings.timeout in both _get_non_stream_timeout and _get_stream_timeout - http_handler: cached default clients now fall back to request_timeout instead of a hardcoded 600s - Replace the brittle `== 6000` default-detection heuristic with a single get_configured_request_timeout() resolver backed by an explicit request_timeout_explicitly_set sentinel (set from REQUEST_TIMEOUT env and litellm_settings), keeping the value-differs fallback for SDK assignment. This also fixes an explicit request_timeout of 6000 being coerced to 600 - CompletionTimeout no longer second-guesses the package default; the caller passes the explicitly-configured value or None Regression for LIT-2369.
144 lines
3.5 KiB
Python
144 lines
3.5 KiB
Python
"""Unit tests for litellm.litellm_core_utils.completion_timeout.CompletionTimeout."""
|
|
|
|
import os
|
|
import sys
|
|
|
|
import httpx
|
|
|
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../..")))
|
|
|
|
from litellm.litellm_core_utils.completion_timeout import CompletionTimeout
|
|
from litellm.utils import supports_httpx_timeout
|
|
|
|
|
|
def test_explicit_timeout_wins():
|
|
assert (
|
|
CompletionTimeout.resolve(
|
|
12.5,
|
|
{"timeout": 99.0, "request_timeout": 88.0},
|
|
"openai",
|
|
global_timeout=None,
|
|
supports_httpx_timeout=supports_httpx_timeout,
|
|
)
|
|
== 12.5
|
|
)
|
|
|
|
|
|
def test_kwargs_timeout_when_param_none():
|
|
assert (
|
|
CompletionTimeout.resolve(
|
|
None,
|
|
{"timeout": 21.0},
|
|
"azure_ai",
|
|
global_timeout=None,
|
|
supports_httpx_timeout=supports_httpx_timeout,
|
|
)
|
|
== 21.0
|
|
)
|
|
|
|
|
|
def test_request_timeout_alias_in_kwargs():
|
|
assert (
|
|
CompletionTimeout.resolve(
|
|
None,
|
|
{"request_timeout": 33.0},
|
|
"bedrock",
|
|
global_timeout=None,
|
|
supports_httpx_timeout=supports_httpx_timeout,
|
|
)
|
|
== 33.0
|
|
)
|
|
|
|
|
|
def test_global_timeout_from_litellm_settings():
|
|
assert (
|
|
CompletionTimeout.resolve(
|
|
None,
|
|
{},
|
|
"vertex_ai",
|
|
global_timeout=360.0,
|
|
supports_httpx_timeout=supports_httpx_timeout,
|
|
)
|
|
== 360.0
|
|
)
|
|
|
|
|
|
def test_explicit_global_timeout_6000_is_preserved():
|
|
"""The caller passes the explicitly-configured value (or None); an explicit
|
|
6000 must be honored, not silently coerced to 600."""
|
|
assert (
|
|
CompletionTimeout.resolve(
|
|
None,
|
|
{},
|
|
"openai",
|
|
global_timeout=6000.0,
|
|
supports_httpx_timeout=supports_httpx_timeout,
|
|
)
|
|
== 6000.0
|
|
)
|
|
|
|
|
|
def test_explicit_request_timeout_6000_preserved():
|
|
"""Explicit deployment/request timeout must not be truncated by the package sentinel."""
|
|
assert (
|
|
CompletionTimeout.resolve(
|
|
None,
|
|
{"request_timeout": 6000.0},
|
|
"openai",
|
|
global_timeout=None,
|
|
supports_httpx_timeout=supports_httpx_timeout,
|
|
)
|
|
== 6000.0
|
|
)
|
|
|
|
|
|
def test_explicit_model_timeout_6000_preserved():
|
|
assert (
|
|
CompletionTimeout.resolve(
|
|
6000.0,
|
|
{"timeout": 1.0, "request_timeout": 2.0},
|
|
"openai",
|
|
global_timeout=None,
|
|
supports_httpx_timeout=supports_httpx_timeout,
|
|
)
|
|
== 6000.0
|
|
)
|
|
|
|
|
|
def test_fallback_600_when_no_global_timeout():
|
|
assert (
|
|
CompletionTimeout.resolve(
|
|
None,
|
|
{},
|
|
"azure_ai",
|
|
global_timeout=None,
|
|
supports_httpx_timeout=supports_httpx_timeout,
|
|
)
|
|
== 600.0
|
|
)
|
|
|
|
|
|
def test_httpx_timeout_coerced_for_provider_without_httpx_timeout_support():
|
|
t = httpx.Timeout(50.0, connect=2.0)
|
|
out = CompletionTimeout.resolve(
|
|
t,
|
|
{},
|
|
"azure_ai",
|
|
global_timeout=None,
|
|
supports_httpx_timeout=supports_httpx_timeout,
|
|
)
|
|
assert out == 50.0
|
|
assert not isinstance(out, httpx.Timeout)
|
|
|
|
|
|
def test_httpx_timeout_preserved_for_openai():
|
|
t = httpx.Timeout(40.0, connect=5.0)
|
|
out = CompletionTimeout.resolve(
|
|
t,
|
|
{},
|
|
"openai",
|
|
global_timeout=None,
|
|
supports_httpx_timeout=supports_httpx_timeout,
|
|
)
|
|
assert out is t
|
|
assert isinstance(out, httpx.Timeout)
|