mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-26 01:12:21 +00:00
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:
parent
991c339946
commit
f0e671f754
14 changed files with 177 additions and 74 deletions
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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."""
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 == {}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue