refactor(types): replace Any with proven types in 13 files (#42937)

* refactor(types): replace Any with proven types in 13 files

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor(types): drop unused executor import from utils type-checking block

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(realtime): keep reserved-key filtering on azure realtime health params

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(realtime): pin reserved-key filtering in azure realtime health auth params

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(realtime): exercise the real azure header builder in the reserved-key test

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
devin-ai-integration[bot] 2026-09-24 09:02:02 -07:00 • committed by GitHub
parent 991c339946
commit f0e671f754
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 177 additions and 74 deletions

View file

@ -62,10 +62,10 @@ if TYPE_CHECKING:
from litellm.proxy.proxy_server import UserAPIKeyAuth as _UserAPIKeyAuth
Span = _Span | Any
Tracer = _Tracer | Any
Context = _Context | Any
SpanExporter = _SpanExporter | Any
UserAPIKeyAuth = _UserAPIKeyAuth | Any
Tracer = _Tracer
Context = _Context
SpanExporter = _SpanExporter
UserAPIKeyAuth = _UserAPIKeyAuth
ManagementEndpointLoggingPayload = _ManagementEndpointLoggingPayload | Any
else:
Span = Any
@ -2730,7 +2730,7 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger):
self.handle_callback_failure(callback_name=self.callback_name or "opentelemetry")
verbose_logger.exception("OpenTelemetry logging error in set_attributes %s", str(e))
def _cast_as_primitive_value_type(self, value) -> str | bool | int | float:
def _cast_as_primitive_value_type(self, value: object) -> str | bool | int | float:
"""
Casts the value to a primitive OTEL type if it is not already a primitive type.

View file

@ -1566,14 +1566,14 @@ class Logging(LiteLLMLoggingBaseClass):
attr = "debug"
if json_logs:
callattr = getattr(verbose_logger, attr)
callattr = verbose_logger.warning if attr == "warning" else verbose_logger.debug
callattr(
"RAW RESPONSE:\n{}\n\n".format(
self.model_call_details.get("original_response", self.model_call_details)
),
)
else:
callattr = getattr(verbose_logger, attr)
callattr = verbose_logger.warning if attr == "warning" else verbose_logger.debug
callattr(
"RAW RESPONSE:\n{}\n\n".format(
self.model_call_details.get("original_response", self.model_call_details)
@ -5882,7 +5882,7 @@ class StandardLoggingPayloadSetup:
base_model: str | None,
custom_pricing: bool | None,
custom_llm_provider: str | None,
init_response_obj: Any | BaseModel | dict,
init_response_obj: object,
api_base: str | None = None,
) -> StandardLoggingModelInformation:
model_cost_name: Final = _select_model_name_for_cost_calc(
@ -5915,9 +5915,7 @@ class StandardLoggingPayloadSetup:
return model_cost_information
@staticmethod
def get_final_response_obj(
response_obj: dict, init_response_obj: Any | BaseModel | dict, kwargs: dict
) -> dict | str | list | None:
def get_final_response_obj(response_obj: dict, init_response_obj: object, kwargs: dict) -> dict | str | list | None:
"""
Get final response object after redacting the message input/output from logging
"""
@ -6360,7 +6358,7 @@ def _get_status_fields(
def _extract_response_obj_and_hidden_params(
init_response_obj: Any | BaseModel | dict,
init_response_obj: object,
original_exception: Exception | None,
) -> tuple[dict, dict | None]:
"""Extract response_obj and hidden_params from init_response_obj."""

View file

@ -446,7 +446,7 @@ def _render_chat_template(env, chat_template: str, bos_token: str, eos_token: st
async def _afetch_and_extract_template(
model: str, chat_template: Any | None, get_config_fn, get_template_fn
model: str, chat_template: str | None, get_config_fn, get_template_fn
) -> tuple[str, str, str]:
"""
Async version: Fetch template and tokens from HuggingFace.
@ -500,7 +500,7 @@ async def _afetch_and_extract_template(
def _fetch_and_extract_template(
model: str, chat_template: Any | None, get_config_fn, get_template_fn
model: str, chat_template: str | None, get_config_fn, get_template_fn
) -> tuple[str, str, str]:
"""
Sync version: Fetch template and tokens from HuggingFace.

View file

@ -12,6 +12,7 @@ from typing import (
Literal,
NamedTuple,
Optional,
Protocol,
TypedDict,
TypeVar,
Union,
@ -24,6 +25,7 @@ import httpx
from httpx import USE_CLIENT_DEFAULT
from httpx._types import FileContent
from openai.types.file_deleted import FileDeleted
from typing_extensions import ReadOnly
import litellm
import litellm.litellm_core_utils
@ -206,6 +208,7 @@ if TYPE_CHECKING:
FakeAnthropicMessagesStreamIterator,
)
from litellm.llms.base_llm.passthrough.transformation import BasePassthroughConfig
from litellm.proxy._types import UserAPIKeyAuth
from litellm.types.llms.openai_evals import (
CancelEvalResponse,
CancelRunResponse,
@ -221,6 +224,21 @@ if TYPE_CHECKING:
else:
LiteLLMLoggingObj = Any
class _RealtimeClientWebSocket(Protocol):
async def send_text(self, data: str) -> None: ...
async def close(self, code: int = ..., reason: str | None = ...) -> None: ...
class _ResponsesClientWebSocket(Protocol):
async def send_text(self, data: str) -> None: ...
async def receive_text(self) -> str: ...
async def close(self, code: int = ..., reason: str | None = ...) -> None: ...
_ResponseT = TypeVar("_ResponseT")
@ -237,6 +255,17 @@ class _MediaUploadKwargs(TypedDict, total=False):
timeout: float | httpx.Timeout
class _SignedBodyKwargs(TypedDict, total=False):
data: ReadOnly[bytes]
json: ReadOnly[dict[str, object]]
def _signed_body_kwargs(*, signed_body: bytes | None, data: dict[str, object]) -> _SignedBodyKwargs:
if signed_body is not None:
return {"data": signed_body}
return {"json": data}
def _google_genai_streaming_hidden_params(
*,
api_base: str,
@ -318,7 +347,9 @@ def _mask_presigned_request_headers(transformed_request: bytes | str | dict) ->
}
def _aws_signing_overrides(optional_params: Mapping[str, Any], litellm_params: Mapping[str, Any]) -> Mapping[str, Any]:
def _aws_signing_overrides(
optional_params: Mapping[str, object], litellm_params: Mapping[str, object]
) -> Mapping[str, object]:
return MappingProxyType(
{
key: litellm_params[key]
@ -2739,7 +2770,7 @@ class BaseLLMHTTPHandler:
stream=stream,
fake_stream=fake_stream,
)
body_kwargs: Final[dict[str, Any]] = {"data": signed_body} if signed_body is not None else {"json": data}
body_kwargs: Final = _signed_body_kwargs(signed_body=signed_body, data=data)
## LOGGING
logging_obj.pre_call(
@ -2926,7 +2957,7 @@ class BaseLLMHTTPHandler:
stream=stream,
fake_stream=fake_stream,
)
body_kwargs: Final[dict[str, Any]] = {"data": signed_body} if signed_body is not None else {"json": data}
body_kwargs: Final = _signed_body_kwargs(signed_body=signed_body, data=data)
## LOGGING
logging_obj.pre_call(
@ -4540,7 +4571,7 @@ class BaseLLMHTTPHandler:
api_key=litellm_params.api_key,
model=model,
)
body_kwargs: Final[dict[str, Any]] = {"data": signed_body} if signed_body is not None else {"json": data}
body_kwargs: Final = _signed_body_kwargs(signed_body=signed_body, data=data)
## LOGGING
logging_obj.pre_call(
@ -4634,7 +4665,7 @@ class BaseLLMHTTPHandler:
api_key=litellm_params.api_key,
model=model,
)
body_kwargs: Final[dict[str, Any]] = {"data": signed_body} if signed_body is not None else {"json": data}
body_kwargs: Final = _signed_body_kwargs(signed_body=signed_body, data=data)
## LOGGING
logging_obj.pre_call(
@ -6186,6 +6217,7 @@ class BaseLLMHTTPHandler:
"BasePassthroughConfig",
"BaseContainerConfig",
BaseEvalsAPIConfig,
BaseRealtimeHTTPConfig,
],
):
received_status_code: Final = (
@ -6300,7 +6332,7 @@ class BaseLLMHTTPHandler:
async def async_realtime(
self,
model: str,
websocket: Any,
websocket: _RealtimeClientWebSocket,
logging_obj: LiteLLMLoggingObj,
provider_config: BaseRealtimeConfig,
headers: dict,
@ -6308,7 +6340,7 @@ class BaseLLMHTTPHandler:
api_key: str | None = None,
client: Any | None = None,
timeout: float | None = None,
user_api_key_dict: Any | None = None,
user_api_key_dict: object | None = None,
litellm_metadata: dict[str, object] | None = None,
query_params: RealtimeQueryParams | None = None,
):
@ -6483,7 +6515,7 @@ class BaseLLMHTTPHandler:
request_data: dict[str, object],
logging_obj: LiteLLMLoggingObj,
timeout: float | httpx.Timeout,
provider_config: Any | None = None,
provider_config: BaseRealtimeHTTPConfig | None = None,
model: str | None = None,
extra_headers: dict[str, object] | None = None,
client: HTTPHandler | AsyncHTTPHandler | None = None,
@ -6555,7 +6587,7 @@ class BaseLLMHTTPHandler:
sdp_body: bytes,
logging_obj: LiteLLMLoggingObj,
timeout: float | httpx.Timeout,
provider_config: Any | None = None,
provider_config: BaseRealtimeHTTPConfig | None = None,
model: str | None = None,
session_config: dict[str, object] | None = None,
extra_headers: dict[str, object] | None = None,
@ -6633,13 +6665,13 @@ class BaseLLMHTTPHandler:
async def async_responses_websocket(
self,
model: str,
websocket: Any,
websocket: _ResponsesClientWebSocket,
logging_obj: LiteLLMLoggingObj,
responses_api_provider_config: BaseResponsesAPIConfig | None,
api_base: str | None = None,
api_key: str | None = None,
timeout: float | None = None,
user_api_key_dict: Any | None = None,
user_api_key_dict: "UserAPIKeyAuth | None" = None,
litellm_metadata: dict[str, object] | None = None,
custom_llm_provider: str | None = None,
first_message: str | None = None,
@ -7850,7 +7882,7 @@ class BaseLLMHTTPHandler:
def video_create_character_handler(
self,
name: str,
video: Any,
video: FileTypes,
video_provider_config: BaseVideoConfig,
custom_llm_provider: str,
litellm_params,
@ -7934,7 +7966,7 @@ class BaseLLMHTTPHandler:
async def async_video_create_character_handler(
self,
name: str,
video: Any,
video: FileTypes,
video_provider_config: BaseVideoConfig,
custom_llm_provider: str,
litellm_params,

View file

@ -57,6 +57,7 @@ from litellm.utils import (
# Logging is imported lazily when needed to avoid loading litellm_logging at import time
if TYPE_CHECKING:
from litellm.litellm_core_utils.litellm_logging import Logging
from litellm.router import Router
from litellm.types.utils import TokenCountResponse
from litellm.constants import (
@ -351,7 +352,7 @@ class LiteLLM:
class Chat:
def __init__(self, params, router_obj: Any | None):
def __init__(self, params, router_obj: "Router | None"):
self.params = params
if self.params.get("acompletion", False) is True:
self.params.pop("acompletion")
@ -361,7 +362,7 @@ class Chat:
class Completions:
def __init__(self, params, router_obj: Any | None):
def __init__(self, params, router_obj: "Router | None"):
self.params = params
self.router_obj = router_obj
@ -377,7 +378,7 @@ class Completions:
class AsyncCompletions:
def __init__(self, params, router_obj: Any | None):
def __init__(self, params, router_obj: "Router | None"):
self.params = params
self.router_obj = router_obj

View file

@ -218,7 +218,7 @@ ProxyRouteType: TypeAlias = Literal[
from litellm.llms.anthropic.chat.transformation import AnthropicConfig
# Type alias for streaming chunk serializer (chunk after hooks + cost injection -> wire format)
StreamChunkSerializer = Callable[[Any], str]
StreamChunkSerializer = Callable[[object], str]
# Type alias for streaming error serializer (ProxyException -> wire format)
StreamErrorSerializer = Callable[[ProxyException], str]
@ -459,7 +459,7 @@ async def _bill_partial_streamed_spend_on_disconnect(request_data: dict, respons
return True
async def _cancel_pending_gather_tasks(tasks: list["asyncio.Task[Any]"]) -> None:
async def _cancel_pending_gather_tasks(tasks: Sequence["asyncio.Task[object]"]) -> None:
pending_tasks: Final = [task for task in tasks if not task.done()]
for task in pending_tasks:
task.cancel()
@ -3145,7 +3145,7 @@ class ProxyBaseLLMRequestProcessing:
logging_obj._on_detached_stream_failure = _on_detached_stream_failure
def _is_streaming_response(self, response: Any) -> bool:
def _is_streaming_response(self, response: object) -> bool:
"""
Check if the response object is actually a streaming response by inspecting its type.
@ -3259,7 +3259,7 @@ class ProxyBaseLLMRequestProcessing:
async def _handle_non_streaming_allm_passthrough_route(
self,
response: Any,
response: _UpstreamHttpResponse,
proxy_logging_obj: "ProxyLogging",
user_api_key_dict: "UserAPIKeyAuth",
custom_headers: Mapping[str, str],
@ -3852,7 +3852,7 @@ class ProxyBaseLLMRequestProcessing:
@staticmethod
async def async_streaming_data_generator(
response: Any,
response: object,
user_api_key_dict: UserAPIKeyAuth,
request_data: dict,
proxy_logging_obj: ProxyLogging,
@ -3993,7 +3993,7 @@ class ProxyBaseLLMRequestProcessing:
@staticmethod
def async_sse_data_generator(
response: Any,
response: object,
user_api_key_dict: UserAPIKeyAuth,
request_data: dict,
proxy_logging_obj: ProxyLogging,

View file

@ -453,7 +453,7 @@ def _regenerate_request_as_update_request(key: str, data: RegenerateKeyRequest)
)
if not changed_fields:
return None
return UpdateKeyRequest(key=key, **changed_fields)
return UpdateKeyRequest.model_validate(MappingProxyType({"key": key, **changed_fields}))
class _LegacyDumpable(Protocol):

View file

@ -8700,9 +8700,9 @@ class ProxyConfig:
@staticmethod
def _merge_config_and_db_search_tools(
config_search_tools: list[SearchToolTypedDict],
db_search_tools: list[dict[str, Any]],
) -> list[dict[str, Any]]:
config_search_tools: Sequence[SearchToolTypedDict],
db_search_tools: Sequence[dict[str, object]],
) -> list[dict[str, object]]:
db_tool_names: Final = {tool.get("search_tool_name") for tool in db_search_tools}
return [
*[
@ -9273,10 +9273,10 @@ _EMPTY_HEADERS: Final[Mapping[str, str]] = MappingProxyType({})
async def _iter_with_keepalive(
aiter: AsyncIterator[Any],
aiter: AsyncIterator[object],
resolve_keepalive_seconds: Callable[[object], float],
keepalive_seconds: float,
) -> AsyncGenerator[Any, None]:
) -> AsyncGenerator[object, None]:
"""Wrap `aiter` with idle-gap heartbeats, re-resolving the interval after each
real chunk via `resolve_keepalive_seconds`. A mid-stream router fallback can
swap in a deployment with a different keepalive policy, including one that
@ -9287,7 +9287,7 @@ async def _iter_with_keepalive(
actually produced it, in both directions. While the interval is <= 0, no
task is created and no timeout is awaited: a chunk is forwarded the moment
it arrives, at the same cost as a bare `async for`."""
pending: asyncio.Task[Any] | None = None # rebind-ok: rebound each loop iteration
pending: asyncio.Task[object] | None = None # rebind-ok: rebound each loop iteration
current_keepalive_seconds = keepalive_seconds # rebind-ok: re-resolved after each chunk
try:
while True:

View file

@ -3956,7 +3956,7 @@ class ProxyLogging:
request_data: dict, # mutable-ok: same request-payload shape the hooks mutate
pipelines: "tuple[tuple[str, GuardrailPipeline], ...]",
translation: "tuple[str, BaseTranslation]",
) -> "AsyncGenerator[Any, None]":
) -> "AsyncGenerator[object, None]":
"""
Execute post_call policy pipelines against a streamed response.

View file

@ -127,15 +127,15 @@ def _get_realtime_http_provider_config(
@wrapper_client
async def acreate_realtime_client_secret(
model: str | None = None,
session: dict[str, Any] | None = None,
expires_after: dict[str, Any] | None = None,
session: Mapping[str, object] | None = None,
expires_after: Mapping[str, object] | None = None,
timeout: float | None = None,
**kwargs,
):
req: Final = RealtimeClientSecretRequest(
model=model,
session=RealtimeSessionConfig(**session) if session else None,
expires_after=RealtimeExpiresAfter(**expires_after) if expires_after else None,
session=RealtimeSessionConfig.model_validate(session) if session else None,
expires_after=RealtimeExpiresAfter.model_validate(expires_after) if expires_after else None,
)
model_name = (req.session.model if req.session is not None else None) or req.model or "gpt-4o-realtime-preview"
litellm_logging_obj: Final[LiteLLMLogging] = kwargs.get("litellm_logging_obj")
@ -614,12 +614,14 @@ def _azure_realtime_health_protocol(
def _realtime_health_check_auth_headers(
custom_llm_provider: str, api_key: str | None, model_params: Mapping[str, Any]
custom_llm_provider: str, api_key: str | None, model_params: Mapping[str, object]
) -> Mapping[str, str]:
if custom_llm_provider == "azure":
return azure_realtime.get_auth_headers(
api_key=api_key,
azure_ad_token=(None if api_key else get_azure_ad_token(GenericLiteLLMParams(**model_params))),
azure_ad_token=(
None if api_key else get_azure_ad_token(GenericLiteLLMParams.model_validate(dict(model_params)))
),
)
if api_key is None:
return _EMPTY_AUTH_HEADERS

View file

@ -549,7 +549,7 @@ def _will_bridge_to_chat_completions(
@contextmanager
def _prompt_management_sees_a_provisional_message_list(
kwargs: dict[str, Any], # mutable-ok: the signal is read and popped out of the caller's own kwargs
kwargs: dict[str, object], # mutable-ok: the signal is read and popped out of the caller's own kwargs
bridged: bool,
) -> Generator[None, None]:
"""Tell the cache-control hook that this layer's messages are not the ones sent upstream.

View file

@ -4231,7 +4231,7 @@ class Router:
models: Final = [m.strip() for m in model.split(",")]
async def _async_completion_no_exceptions(
model_name: str, messages: list[dict[str, str]], stream: bool, **kwargs: Any
model_name: str, messages: list[dict[str, str]], stream: bool, **kwargs: object
) -> ModelResponse | CustomStreamWrapper | Exception:
"""
Wrapper around self.acompletion that catches exceptions and returns them as a result
@ -6736,7 +6736,7 @@ class Router:
# Handle asynchronous call types
async def async_wrapper(
custom_llm_provider: str | None = None,
client: Any | None = None,
client: AsyncOpenAI | None = None,
**kwargs,
):
if call_type == "assistants":
@ -8441,7 +8441,7 @@ class Router:
return self._has_content_policy_fallback(model, kwargs)
def _should_raise_anthropic_refusal_error(
self, model: str, original_generic_function: Callable, response: object, kwargs: Mapping[str, Any]
self, model: str, original_generic_function: Callable, response: object, kwargs: Mapping[str, object]
) -> bool:
"""
The /v1/messages twin of _should_raise_content_policy_error: an Anthropic safeguard
@ -10318,7 +10318,7 @@ class Router:
)
@staticmethod
def _widest_configured_limit(model_infos: Sequence[Mapping[str, Any]], field: str) -> int | None:
def _widest_configured_limit(model_infos: Sequence[Mapping[str, object]], field: str) -> int | None:
"""The largest usable value of ``field`` across a group's configured model_info blocks."""
limits: Final = tuple(
limit
@ -13409,7 +13409,7 @@ class Router:
self,
model: str,
request_kwargs: dict,
messages: list[dict[str, Any]] | None,
messages: list[dict[str, object]] | None,
) -> RoutingContext:
"""
Build a RoutingContext for `model`, run it through `self.routing_plugins`

View file

@ -369,7 +369,7 @@ if TYPE_CHECKING:
)
from litellm.litellm_core_utils.rules import Rules
from litellm.litellm_core_utils.streaming_handler import CustomStreamWrapper
from litellm.litellm_core_utils.thread_pool_executor import executor
from litellm.litellm_core_utils.thread_pool_executor import BoundedLoggingThreadPoolExecutor
from litellm.llms.base_llm.anthropic_messages.transformation import (
BaseAnthropicMessagesConfig,
)
@ -683,12 +683,12 @@ def load_credentials_from_list(kwargs: dict):
Updates kwargs with the credentials if credential_name in kwarg
"""
# Access CredentialAccessor via module to trigger lazy loading if needed
CredentialAccessor: Final = getattr(sys.modules[__name__], "CredentialAccessor")
credential_accessor: Final[type[CredentialAccessor]] = getattr(sys.modules[__name__], "CredentialAccessor")
credential_name: Final = kwargs.get("litellm_credential_name")
if not credential_name:
return
credential: Final = CredentialAccessor.find_credential(credential_name)
credential: Final = credential_accessor.find_credential(credential_name)
if credential is None:
verbose_logger.warning(
"litellm_credential_name=%s matched none of the %d loaded credentials; the request runs without it",
@ -894,6 +894,45 @@ class _NamedFile(Protocol):
def name(self) -> object: ...
class _LoggingClassGetter(Protocol):
def __call__(self) -> type[LiteLLMLoggingObject]: ...
class _ResponseMetadataUpdater(Protocol):
def __call__(
self,
result: object,
logging_obj: LiteLLMLoggingObject,
model: str | None,
kwargs: dict[str, object],
start_time: datetime.datetime,
end_time: datetime.datetime,
include_overhead: bool = True,
) -> None: ...
class _SupportedOpenAIParamsGetter(Protocol):
def __call__(
self,
model: str,
custom_llm_provider: str | None = None,
request_type: Literal["chat_completion", "embeddings", "transcription"] = "chat_completion",
base_model: str | None = None,
) -> list[str] | None: ...
class _NestedPathChecker(Protocol):
def __call__(self, path: str) -> bool: ...
class _NestedValueDeleter(Protocol):
def __call__(self, data: dict[str, object], path: str) -> dict[str, object]: ...
class _BaseModelFromMetadataGetter(Protocol):
def __call__(self, metadata: Mapping[str, object] | None) -> str | None: ...
def _ocr_document_summary(document: object) -> str:
if not isinstance(document, Mapping):
return "default-message-value"
@ -978,7 +1017,9 @@ def function_setup(
len(litellm.input_callback) > 0 or len(litellm.success_callback) > 0 or len(litellm.failure_callback) > 0
) and len(callback_list) == 0:
callback_list = list(set(litellm.input_callback + litellm.success_callback + litellm.failure_callback))
get_set_callbacks: Final = getattr(sys.modules[__name__], "get_set_callbacks")
get_set_callbacks: Final[Callable[[], Callable[..., None]]] = getattr(
sys.modules[__name__], "get_set_callbacks"
)
get_set_callbacks()(callback_list=callback_list, function_id=function_id)
## ASYNC CALLBACKS - safety net for callbacks added via direct append
if len(litellm.input_callback) > 0:
@ -1223,7 +1264,9 @@ def function_setup(
call_type=call_type,
):
stream = True
get_litellm_logging_class: Final = getattr(sys.modules[__name__], "get_litellm_logging_class")
get_litellm_logging_class: Final[_LoggingClassGetter] = getattr(
sys.modules[__name__], "get_litellm_logging_class"
)
# Victim for object pool
logging_obj = get_litellm_logging_class()( # rebind-ok: 2nd assignment to logging_obj (see initial None above)
model=model,
@ -1761,7 +1804,9 @@ def client(original_function):
return litellm.stream_chunk_builder(chunks, messages=kwargs.get("messages", None))
else:
# RETURN RESULT
update_response_metadata = getattr(sys.modules[__name__], "update_response_metadata")
update_response_metadata: _ResponseMetadataUpdater = getattr(
sys.modules[__name__], "update_response_metadata"
)
update_response_metadata(
result=result,
logging_obj=logging_obj,
@ -1802,7 +1847,9 @@ def client(original_function):
kwargs=kwargs,
)
_update_response_metadata: Final = getattr(sys.modules[__name__], "update_response_metadata")
_update_response_metadata: Final[_ResponseMetadataUpdater] = getattr(
sys.modules[__name__], "update_response_metadata"
)
_update_response_metadata(
result=result,
logging_obj=logging_obj,
@ -1817,7 +1864,7 @@ def client(original_function):
# Copy the current context to propagate it to the background thread
# This is essential for OpenTelemetry span context propagation
ctx: Final = contextvars.copy_context()
executor: Final = getattr(sys.modules[__name__], "executor")
executor: Final[BoundedLoggingThreadPoolExecutor] = getattr(sys.modules[__name__], "executor")
executor.submit(
ctx.run,
logging_obj.success_handler,
@ -1910,7 +1957,9 @@ def client(original_function):
print_args_passed_to_litellm(original_function, args, kwargs)
start_time: Final = datetime.datetime.now()
result = None
_update_response_metadata: Final = getattr(sys.modules[__name__], "update_response_metadata")
_update_response_metadata: Final[_ResponseMetadataUpdater] = getattr(
sys.modules[__name__], "update_response_metadata"
)
logging_obj: LiteLLMLoggingObject | None = kwargs.get("litellm_logging_obj", None)
LLMCachingHandler: Final = _get_cached_llm_caching_handler()
_llm_caching_handler: Final[LLMCachingHandler] = LLMCachingHandler(
@ -3678,7 +3727,9 @@ def get_optional_params_embeddings(
**kwargs,
):
# Lazy load get_supported_openai_params
get_supported_openai_params: Final = getattr(sys.modules[__name__], "get_supported_openai_params")
get_supported_openai_params: Final[_SupportedOpenAIParamsGetter] = getattr(
sys.modules[__name__], "get_supported_openai_params"
)
# retrieve all parameters passed to the function
passed_params: Final = locals()
@ -4469,7 +4520,9 @@ def get_optional_params(
message=f"{custom_llm_provider} does not support parameters: {list(unsupported_params.keys())}, for model={model}. To drop these, set `litellm.drop_params=True` or for proxy:\n\n`litellm_settings:\n drop_params: true`\n. \n If you want to use these params dynamically send allowed_openai_params={list(unsupported_params.keys())} in your request.",
)
get_supported_openai_params: Final = getattr(sys.modules[__name__], "get_supported_openai_params")
get_supported_openai_params: Final[_SupportedOpenAIParamsGetter] = getattr(
sys.modules[__name__], "get_supported_openai_params"
)
supported_params = get_supported_openai_params(
model=model, custom_llm_provider=custom_llm_provider, base_model=base_model
)
@ -4640,9 +4693,9 @@ def get_optional_params(
drop_params=bool(drop_params),
)
elif custom_llm_provider == "bedrock":
BedrockModelInfo: Final = getattr(sys.modules[__name__], "BedrockModelInfo")
bedrock_route: Final = BedrockModelInfo.get_bedrock_route(model)
bedrock_base_model: Final = BedrockModelInfo.get_base_model(model)
bedrock_model_info: Final[type[BedrockModelInfo]] = getattr(sys.modules[__name__], "BedrockModelInfo")
bedrock_route: Final = bedrock_model_info.get_bedrock_route(model)
bedrock_base_model: Final = bedrock_model_info.get_base_model(model)
if bedrock_route == "converse" or bedrock_route == "converse_like":
optional_params = litellm.AmazonConverseConfig().map_openai_params(
model=model,
@ -4680,7 +4733,7 @@ def get_optional_params(
drop_params=bool(drop_params),
)
if bedrock_route == "claude_platform":
optional_params = BedrockModelInfo.map_claude_platform_auth_params(
optional_params = bedrock_model_info.map_claude_platform_auth_params(
passed_params=passed_params, optional_params=optional_params
)
elif custom_llm_provider == "cloudflare":
@ -4954,8 +5007,8 @@ def get_optional_params(
# Apply nested drops from additional_drop_params
if additional_drop_params:
is_nested_path: Final = getattr(sys.modules[__name__], "is_nested_path")
delete_nested_value: Final = getattr(sys.modules[__name__], "delete_nested_value")
is_nested_path: Final[_NestedPathChecker] = getattr(sys.modules[__name__], "is_nested_path")
delete_nested_value: Final[_NestedValueDeleter] = getattr(sys.modules[__name__], "delete_nested_value")
nested_paths: Final = [p for p in additional_drop_params if is_nested_path(p)]
for path in nested_paths:
optional_params = delete_nested_value(optional_params, path)
@ -7852,7 +7905,7 @@ def _get_base_model_from_metadata(model_call_details=None):
return _base_model
metadata: Final = litellm_params.get("metadata") or {}
_get_base_model_from_litellm_call_metadata: Callable[..., str | None] = getattr(
_get_base_model_from_litellm_call_metadata: _BaseModelFromMetadataGetter = getattr(
sys.modules[__name__], "_get_base_model_from_litellm_call_metadata"
)
base_model_from_metadata: Final = _get_base_model_from_litellm_call_metadata(metadata=metadata)

View file

@ -2,6 +2,7 @@
import struct
import zlib
from types import MappingProxyType
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
@ -482,3 +483,19 @@ async def test_ocr_health_check_sends_the_document_kind_the_provider_config_acce
document = mock_aocr.call_args.kwargs["document"]
assert document["type"] == expected_document_type
assert document[expected_document_type].startswith(expected_uri_prefix)
def test_realtime_health_check_azure_ad_params_drop_reserved_keys():
from litellm.realtime_api import main as realtime_main
seen = []
with patch.object(realtime_main, "get_azure_ad_token", lambda params: seen.append(params) or "ad-token"):
headers = realtime_main._realtime_health_check_auth_headers(
"azure",
None,
MappingProxyType({"api_base": "https://x.openai.azure.com", "self": 1, "params": 2, "__class__": 3}),
)
assert dict(headers) == {"Authorization": "Bearer ad-token"}
assert seen[0].api_base == "https://x.openai.azure.com"
assert seen[0].model_extra == {}