From fee80d6c5f5b167df1777856820256249807bab1 Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Thu, 30 Jul 2026 10:52:05 +0000 Subject: [PATCH] chore(typing): clear basedpyright Any errors in proxy management endpoints and http handlers Replace Any type seams with real types across proxy_server.py, llm_http_handler.py, proxy/utils.py, streaming_handler.py, key_management_endpoints.py, and team_endpoints.py: Prisma repository return types, request/response payload TypedDicts and Pydantic models, and precise callback/logging-object types instead of Any. Whole-tree basedpyright totals (severity=error): reportAny 22710 -> 22448, reportExplicitAny 7283 -> 7074, all other rules unchanged or improved, zero regressions. --- basedpyright-code-budget.json | 18 +- .../litellm_core_utils/streaming_handler.py | 2 +- .../azure/realtime/http_transformation.py | 6 +- .../base_llm/realtime/http_transformation.py | 6 +- litellm/llms/custom_httpx/llm_http_handler.py | 271 +++++++++--------- .../openai/realtime/http_transformation.py | 4 +- .../key_management_endpoints.py | 123 ++++---- .../management_endpoints/team_endpoints.py | 173 ++++++----- litellm/proxy/proxy_server.py | 57 ++-- litellm/proxy/utils.py | 42 +-- ruff-strict-budget.json | 12 +- type-discipline-budget.json | 2 +- 12 files changed, 390 insertions(+), 326 deletions(-) diff --git a/basedpyright-code-budget.json b/basedpyright-code-budget.json index 3f89ff179eb..0247f03e023 100644 --- a/basedpyright-code-budget.json +++ b/basedpyright-code-budget.json @@ -1,9 +1,9 @@ { "reportAny": { - "limit": 33171 + "limit": 32379 }, "reportArgumentType": { - "limit": 2645 + "limit": 2633 }, "reportAssignmentType": { "limit": 329 @@ -24,7 +24,7 @@ "limit": 42 }, "reportExplicitAny": { - "limit": 10228 + "limit": 9602 }, "reportFunctionMemberAccess": { "limit": 11 @@ -54,10 +54,10 @@ "limit": 0 }, "reportMissingParameterType": { - "limit": 5869 + "limit": 5857 }, "reportMissingTypeArgument": { - "limit": 15864 + "limit": 15831 }, "reportMissingTypeStubs": { "limit": 41 @@ -99,19 +99,19 @@ "limit": 0 }, "reportUnknownArgumentType": { - "limit": 45522 + "limit": 45456 }, "reportUnknownLambdaType": { "limit": 113 }, "reportUnknownMemberType": { - "limit": 40479 + "limit": 40416 }, "reportUnknownParameterType": { - "limit": 20341 + "limit": 20296 }, "reportUnknownVariableType": { - "limit": 32052 + "limit": 31976 }, "reportUnnecessaryCast": { "limit": 177 diff --git a/litellm/litellm_core_utils/streaming_handler.py b/litellm/litellm_core_utils/streaming_handler.py index 60dbf7c644a..45a3d38a4d3 100644 --- a/litellm/litellm_core_utils/streaming_handler.py +++ b/litellm/litellm_core_utils/streaming_handler.py @@ -105,7 +105,7 @@ class _ProviderChunkParsed: @dataclass(frozen=True, slots=True) class _ProviderChunkEarlyReturn: - value: Any + value: ModelResponseStream | None _ProviderChunkResult = Union[_ProviderChunkParsed, _ProviderChunkEarlyReturn] diff --git a/litellm/llms/azure/realtime/http_transformation.py b/litellm/llms/azure/realtime/http_transformation.py index 55a86014423..ae0ad06fe55 100644 --- a/litellm/llms/azure/realtime/http_transformation.py +++ b/litellm/llms/azure/realtime/http_transformation.py @@ -21,10 +21,10 @@ class AzureRealtimeHTTPConfig(BaseRealtimeHTTPConfig): def validate_environment( self, - headers: dict, + headers: dict[str, str], model: str, api_key: Optional[str] = None, - ) -> dict: + ) -> dict[str, str]: return { **headers, "api-key": api_key or "", @@ -43,7 +43,7 @@ class AzureRealtimeHTTPConfig(BaseRealtimeHTTPConfig): version = api_version or get_secret_str("AZURE_API_VERSION") or "2024-12-17" return f"{base}/openai/realtime/transcription_sessions?api-version={version}" - def get_realtime_calls_headers(self, ephemeral_key: str) -> dict: + def get_realtime_calls_headers(self, ephemeral_key: str) -> dict[str, str]: return { "api-key": ephemeral_key, } diff --git a/litellm/llms/base_llm/realtime/http_transformation.py b/litellm/llms/base_llm/realtime/http_transformation.py index 4c8cc30a8b3..b3b8c0dd716 100644 --- a/litellm/llms/base_llm/realtime/http_transformation.py +++ b/litellm/llms/base_llm/realtime/http_transformation.py @@ -69,10 +69,10 @@ class BaseRealtimeHTTPConfig(ABC): @abstractmethod def validate_environment( self, - headers: dict, + headers: dict[str, str], model: str, api_key: Optional[str] = None, - ) -> dict: + ) -> dict[str, str]: """ Build and return the request headers for the client_secrets call. @@ -89,7 +89,7 @@ class BaseRealtimeHTTPConfig(ABC): base = (api_base or "").rstrip("/") return f"{base}/v1/realtime/calls" - def get_realtime_calls_headers(self, ephemeral_key: str) -> dict: + def get_realtime_calls_headers(self, ephemeral_key: str) -> dict[str, str]: """ Build headers for the realtime_calls POST. diff --git a/litellm/llms/custom_httpx/llm_http_handler.py b/litellm/llms/custom_httpx/llm_http_handler.py index ec1301e5923..726029334a0 100644 --- a/litellm/llms/custom_httpx/llm_http_handler.py +++ b/litellm/llms/custom_httpx/llm_http_handler.py @@ -61,6 +61,7 @@ from litellm.llms.base_llm.image_generation.transformation import ( BaseImageGenerationConfig, ) from litellm.llms.base_llm.ocr.transformation import BaseOCRConfig, OCRResponse +from litellm.llms.base_llm.realtime.http_transformation import BaseRealtimeHTTPConfig from litellm.llms.base_llm.realtime.transformation import BaseRealtimeConfig from litellm.llms.base_llm.rerank.transformation import BaseRerankConfig from litellm.llms.base_llm.responses.transformation import BaseResponsesAPIConfig @@ -162,6 +163,7 @@ from .http_handler import get_shared_realtime_ssl_context if TYPE_CHECKING: from aiohttp import ClientSession + from litellm.integrations.custom_logger import CustomLogger from litellm.litellm_core_utils.litellm_logging import Logging as _LiteLLMLoggingObj from litellm.llms.anthropic.experimental_pass_through.messages.streaming_iterator import ( AnthropicMessagesStreamingResponse, @@ -193,7 +195,7 @@ def _google_genai_streaming_hidden_params( """Pre-stream metadata for proxy response headers (mirrors CustomStreamWrapper._hidden_params).""" from litellm.litellm_core_utils.core_helpers import process_response_headers - _model_info: Dict[str, Any] = dict(getattr(litellm_params, "model_info", None) or {}) + _model_info: Dict[str, object] = dict(getattr(litellm_params, "model_info", None) or {}) _raw_id = _model_info.get("id") or logging_obj.get_router_model_id() or "" _model_id = _raw_id if isinstance(_raw_id, str) else str(_raw_id) return { @@ -210,7 +212,7 @@ def _responses_api_optional_request_param_names() -> frozenset[str]: return frozenset(get_type_hints(ResponsesAPIOptionalRequestParams).keys()) -def _custom_logger_callbacks(logging_obj: Any) -> list[Any]: +def _custom_logger_callbacks(logging_obj: LiteLLMLoggingObj) -> "list[CustomLogger]": from litellm.integrations.custom_logger import CustomLogger from litellm.litellm_core_utils.litellm_logging import ( get_custom_logger_compatible_class, @@ -221,7 +223,7 @@ def _custom_logger_callbacks(logging_obj: Any) -> list[Any]: if isinstance(dynamic_success_callbacks, (list, tuple)): callbacks.extend(dynamic_success_callbacks) - custom_loggers: list[Any] = [] + custom_loggers: list[CustomLogger] = [] for cb in callbacks: if isinstance(cb, str): resolved = get_custom_logger_compatible_class(cb) # type: ignore[arg-type] @@ -233,7 +235,7 @@ def _custom_logger_callbacks(logging_obj: Any) -> list[Any]: return custom_loggers -def _has_pre_call_deployment_hook(logging_obj: Any) -> bool: +def _has_pre_call_deployment_hook(logging_obj: LiteLLMLoggingObj) -> bool: from litellm.integrations.custom_logger import CustomLogger base_func = CustomLogger.async_pre_call_deployment_hook @@ -1051,7 +1053,7 @@ class BaseLLMHTTPHandler: timeout: Optional[Union[float, httpx.Timeout]], model_response: RerankResponse, _is_async: bool = False, - headers: Optional[Dict[str, Any]] = None, + headers: Optional[Dict[str, str]] = None, api_key: Optional[str] = None, api_base: Optional[str] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -1177,7 +1179,7 @@ class BaseLLMHTTPHandler: logging_obj: LiteLLMLoggingObj, api_key: Optional[str], api_base: Optional[str], - headers: Optional[Dict[str, Any]], + headers: Optional[Dict[str, str]], provider_config: BaseAudioTranscriptionConfig, ) -> Tuple[dict, str, Union[dict, bytes, None], Optional[dict]]: """ @@ -1266,7 +1268,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, atranscription: bool = False, - headers: Optional[Dict[str, Any]] = None, + headers: Optional[Dict[str, str]] = None, provider_config: Optional[BaseAudioTranscriptionConfig] = None, shared_session: Optional["ClientSession"] = None, ) -> Union[TranscriptionResponse, Coroutine[Any, Any, TranscriptionResponse]]: @@ -1351,7 +1353,7 @@ class BaseLLMHTTPHandler: api_base: Optional[str], custom_llm_provider: str, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, - headers: Optional[Dict[str, Any]] = None, + headers: Optional[Dict[str, str]] = None, provider_config: Optional[BaseAudioTranscriptionConfig] = None, shared_session: Optional["ClientSession"] = None, ) -> TranscriptionResponse: @@ -1417,10 +1419,10 @@ class BaseLLMHTTPHandler: logging_obj: LiteLLMLoggingObj, api_key: Optional[str], api_base: Optional[str], - headers: Optional[Dict[str, Any]], + headers: Optional[Dict[str, str]], provider_config: BaseOCRConfig, litellm_params: dict, - ) -> Tuple[Dict[str, Any], str, Dict[str, Any], None]: + ) -> Tuple[Dict[str, str], str, Dict[str, Any], None]: """ Shared logic for preparing OCR requests. Returns: (headers, complete_url, data, files) @@ -1483,10 +1485,10 @@ class BaseLLMHTTPHandler: logging_obj: LiteLLMLoggingObj, api_key: Optional[str], api_base: Optional[str], - headers: Optional[Dict[str, Any]], + headers: Optional[Dict[str, str]], provider_config: BaseOCRConfig, litellm_params: dict, - ) -> Tuple[Dict[str, Any], str, Dict[str, Any], None]: + ) -> Tuple[Dict[str, str], str, Dict[str, Any], None]: """ Async version of _prepare_ocr_request for providers that need async transforms. Returns: (headers, complete_url, data, files) @@ -1641,7 +1643,7 @@ class BaseLLMHTTPHandler: api_base: Optional[str], custom_llm_provider: str, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, - headers: Optional[Dict[str, Any]] = None, + headers: Optional[Dict[str, str]] = None, provider_config: Optional[BaseOCRConfig] = None, litellm_params: Optional[dict] = None, ) -> OCRResponse: @@ -1703,7 +1705,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, asearch: bool = False, - headers: Optional[Dict[str, Any]] = None, + headers: Optional[Dict[str, str]] = None, provider_config: Optional[BaseSearchConfig] = None, ) -> Union[SearchResponse, Coroutine[Any, Any, SearchResponse]]: """ @@ -1798,7 +1800,7 @@ class BaseLLMHTTPHandler: api_base: Optional[str], custom_llm_provider: str, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, - headers: Optional[Dict[str, Any]] = None, + headers: Optional[Dict[str, str]] = None, provider_config: Optional[BaseSearchConfig] = None, ) -> SearchResponse: """ @@ -1976,7 +1978,7 @@ class BaseLLMHTTPHandler: litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, client: Optional[AsyncHTTPHandler] = None, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, api_key: Optional[str] = None, api_base: Optional[str] = None, stream: Optional[bool] = False, @@ -2449,7 +2451,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -2663,7 +2665,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -2847,7 +2849,7 @@ class BaseLLMHTTPHandler: litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, custom_llm_provider: Optional[str], - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -2931,7 +2933,7 @@ class BaseLLMHTTPHandler: litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, custom_llm_provider: Optional[str], - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -3021,7 +3023,7 @@ class BaseLLMHTTPHandler: litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, custom_llm_provider: Optional[str] = None, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -3102,7 +3104,7 @@ class BaseLLMHTTPHandler: litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, custom_llm_provider: Optional[str] = None, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -3183,7 +3185,7 @@ class BaseLLMHTTPHandler: include: Optional[List[str]] = None, limit: int = 20, order: Literal["asc", "desc"] = "desc", - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -3269,7 +3271,7 @@ class BaseLLMHTTPHandler: include: Optional[List[str]] = None, limit: int = 20, order: Literal["asc", "desc"] = "desc", - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, shared_session: Optional["ClientSession"] = None, @@ -4138,7 +4140,7 @@ class BaseLLMHTTPHandler: litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, custom_llm_provider: Optional[str], - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -4218,7 +4220,7 @@ class BaseLLMHTTPHandler: litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, custom_llm_provider: Optional[str], - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -4294,7 +4296,7 @@ class BaseLLMHTTPHandler: litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, custom_llm_provider: Optional[str], - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -4393,7 +4395,7 @@ class BaseLLMHTTPHandler: litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, custom_llm_provider: Optional[str], - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -5008,7 +5010,7 @@ class BaseLLMHTTPHandler: return depth, max(max_loops, 1), fingerprints @staticmethod - def _has_agentic_completion_hook(logging_obj: Any) -> bool: + def _has_agentic_completion_hook(logging_obj: LiteLLMLoggingObj) -> bool: """ True if any registered callback actually overrides ``async_should_run_agentic_loop`` (the gate every agentic hook goes @@ -5715,6 +5717,7 @@ class BaseLLMHTTPHandler: "BasePassthroughConfig", "BaseContainerConfig", BaseEvalsAPIConfig, + BaseRealtimeHTTPConfig, ], ): status_code = getattr(e, "status_code", 500) @@ -5769,7 +5772,7 @@ class BaseLLMHTTPHandler: websockets_module: Any, url: str, headers: dict, - ssl_context: Any, + ssl_context: Union[bool, str, ssl.SSLContext], *, open_timeout: float = 8.0, max_attempts: int = 3, @@ -5925,9 +5928,9 @@ class BaseLLMHTTPHandler: request_data: Dict[str, Any], logging_obj: LiteLLMLoggingObj, timeout: Union[float, httpx.Timeout], - provider_config: Optional[Any] = None, + provider_config: BaseRealtimeHTTPConfig | None = None, model: Optional[str] = None, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, api_version: Optional[str] = None, ) -> httpx.Response: @@ -5958,9 +5961,9 @@ class BaseLLMHTTPHandler: request_data: Dict[str, Any], logging_obj: LiteLLMLoggingObj, timeout: Union[float, httpx.Timeout], - provider_config: Optional[Any] = None, + provider_config: BaseRealtimeHTTPConfig | None = None, model: Optional[str] = None, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, api_version: Optional[str] = None, ) -> httpx.Response: @@ -5987,9 +5990,9 @@ class BaseLLMHTTPHandler: request_data: Dict[str, Any], logging_obj: LiteLLMLoggingObj, timeout: Union[float, httpx.Timeout], - provider_config: Optional[Any] = None, + provider_config: BaseRealtimeHTTPConfig | None = None, model: Optional[str] = None, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, api_version: Optional[str] = None, ) -> httpx.Response: @@ -6014,7 +6017,7 @@ class BaseLLMHTTPHandler: ) else: url = provider_config.get_complete_url(api_base=api_base, model=model or "", api_version=api_version) - headers: Dict[str, Any] = provider_config.validate_environment( + headers: Dict[str, str] = provider_config.validate_environment( headers={}, model=model or "", api_key=api_key ) else: @@ -6059,10 +6062,10 @@ class BaseLLMHTTPHandler: sdp_body: bytes, logging_obj: LiteLLMLoggingObj, timeout: Union[float, httpx.Timeout], - provider_config: Optional[Any] = None, + provider_config: BaseRealtimeHTTPConfig | None = None, model: Optional[str] = None, session_config: Optional[Dict[str, Any]] = None, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, api_version: Optional[str] = None, ) -> httpx.Response: @@ -6085,7 +6088,7 @@ class BaseLLMHTTPHandler: if provider_config is not None: url = provider_config.get_realtime_calls_url(api_base=api_base, model=model or "", api_version=api_version) - headers: Dict[str, Any] = provider_config.get_realtime_calls_headers(ephemeral_key=openai_ephemeral_key) + headers: Dict[str, str] = provider_config.get_realtime_calls_headers(ephemeral_key=openai_ephemeral_key) else: url = f"{api_base.rstrip('/')}/v1/realtime/calls" headers = { @@ -6322,7 +6325,7 @@ class BaseLLMHTTPHandler: litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, timeout: Union[float, httpx.Timeout], - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -6434,7 +6437,7 @@ class BaseLLMHTTPHandler: async def async_image_edit_handler( self, model: str, - image: FileTypes, + image: Any, prompt: Optional[str], image_edit_provider_config: BaseImageEditConfig, image_edit_optional_request_params: Dict, @@ -6442,7 +6445,7 @@ class BaseLLMHTTPHandler: litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, timeout: Union[float, httpx.Timeout], - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, fake_stream: bool = False, @@ -6540,7 +6543,7 @@ class BaseLLMHTTPHandler: litellm_params: Dict, logging_obj: LiteLLMLoggingObj, timeout: Union[float, httpx.Timeout], - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -6667,7 +6670,7 @@ class BaseLLMHTTPHandler: litellm_params: Dict, logging_obj: LiteLLMLoggingObj, timeout: Union[float, httpx.Timeout], - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, fake_stream: bool = False, @@ -6775,7 +6778,7 @@ class BaseLLMHTTPHandler: litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, timeout: Union[float, httpx.Timeout], - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -6899,7 +6902,7 @@ class BaseLLMHTTPHandler: litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, timeout: Union[float, httpx.Timeout], - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, fake_stream: bool = False, @@ -6999,7 +7002,7 @@ class BaseLLMHTTPHandler: litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, timeout: Union[float, httpx.Timeout], - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, api_key: Optional[str] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -7089,7 +7092,7 @@ class BaseLLMHTTPHandler: litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, timeout: Union[float, httpx.Timeout], - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, api_key: Optional[str] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, variant: Optional[str] = None, @@ -7167,7 +7170,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params, logging_obj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, _is_async: bool = False, @@ -7266,7 +7269,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params, logging_obj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, client=None, @@ -7349,7 +7352,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params, logging_obj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None, _is_async: bool = False, client=None, @@ -7433,7 +7436,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params, logging_obj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None, client=None, api_key: Optional[str] = None, @@ -7504,7 +7507,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params, logging_obj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None, _is_async: bool = False, client=None, @@ -7573,7 +7576,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params, logging_obj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None, client=None, api_key: Optional[str] = None, @@ -7632,7 +7635,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params, logging_obj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, _is_async: bool = False, @@ -7741,7 +7744,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params, logging_obj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, client=None, @@ -7838,7 +7841,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params, logging_obj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, _is_async: bool = False, @@ -7927,7 +7930,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params, logging_obj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, client=None, @@ -8002,7 +8005,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params, logging_obj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_query: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, _is_async: bool = False, @@ -8056,7 +8059,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params, logging_obj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_query: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, client=None, @@ -8137,7 +8140,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params, logging_obj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None, client=None, api_key: Optional[str] = None, @@ -8213,7 +8216,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params, logging_obj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, _is_async: bool = False, @@ -8318,7 +8321,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params, logging_obj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, client=None, @@ -8408,7 +8411,7 @@ class BaseLLMHTTPHandler: container_provider_config: "BaseContainerConfig", litellm_params: GenericLiteLLMParams, logging_obj: "LiteLLMLoggingObj", - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Union[float, httpx.Timeout] = 600, _is_async: bool = False, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -8495,7 +8498,7 @@ class BaseLLMHTTPHandler: container_provider_config: "BaseContainerConfig", litellm_params: GenericLiteLLMParams, logging_obj: "LiteLLMLoggingObj", - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Union[float, httpx.Timeout] = 600, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, ) -> "ContainerObject": @@ -8572,7 +8575,7 @@ class BaseLLMHTTPHandler: after: Optional[str] = None, limit: Optional[int] = None, order: Optional[str] = None, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_query: Optional[Dict[str, Any]] = None, timeout: Union[float, httpx.Timeout] = 600, _is_async: bool = False, @@ -8662,7 +8665,7 @@ class BaseLLMHTTPHandler: after: Optional[str] = None, limit: Optional[int] = None, order: Optional[str] = None, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_query: Optional[Dict[str, Any]] = None, timeout: Union[float, httpx.Timeout] = 600, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -8737,7 +8740,7 @@ class BaseLLMHTTPHandler: container_provider_config: "BaseContainerConfig", litellm_params: GenericLiteLLMParams, logging_obj: "LiteLLMLoggingObj", - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_query: Optional[Dict[str, Any]] = None, timeout: Union[float, httpx.Timeout] = 600, _is_async: bool = False, @@ -8825,7 +8828,7 @@ class BaseLLMHTTPHandler: container_provider_config: "BaseContainerConfig", litellm_params: GenericLiteLLMParams, logging_obj: "LiteLLMLoggingObj", - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_query: Optional[Dict[str, Any]] = None, timeout: Union[float, httpx.Timeout] = 600, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -8902,7 +8905,7 @@ class BaseLLMHTTPHandler: container_provider_config: "BaseContainerConfig", litellm_params: GenericLiteLLMParams, logging_obj: "LiteLLMLoggingObj", - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_query: Optional[Dict[str, Any]] = None, timeout: Union[float, httpx.Timeout] = 600, _is_async: bool = False, @@ -8990,7 +8993,7 @@ class BaseLLMHTTPHandler: container_provider_config: "BaseContainerConfig", litellm_params: GenericLiteLLMParams, logging_obj: "LiteLLMLoggingObj", - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_query: Optional[Dict[str, Any]] = None, timeout: Union[float, httpx.Timeout] = 600, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -9070,7 +9073,7 @@ class BaseLLMHTTPHandler: after: Optional[str] = None, limit: Optional[int] = None, order: Optional[str] = None, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_query: Optional[Dict[str, Any]] = None, timeout: Union[float, httpx.Timeout] = 600, _is_async: bool = False, @@ -9162,7 +9165,7 @@ class BaseLLMHTTPHandler: after: Optional[str] = None, limit: Optional[int] = None, order: Optional[str] = None, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_query: Optional[Dict[str, Any]] = None, timeout: Union[float, httpx.Timeout] = 600, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -9239,7 +9242,7 @@ class BaseLLMHTTPHandler: container_provider_config: "BaseContainerConfig", litellm_params: GenericLiteLLMParams, logging_obj: "LiteLLMLoggingObj", - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Union[float, httpx.Timeout] = 600, _is_async: bool = False, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -9325,7 +9328,7 @@ class BaseLLMHTTPHandler: container_provider_config: "BaseContainerConfig", litellm_params: GenericLiteLLMParams, logging_obj: "LiteLLMLoggingObj", - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Union[float, httpx.Timeout] = 600, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, ) -> bytes: @@ -9404,7 +9407,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -9502,7 +9505,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -9596,7 +9599,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -9656,7 +9659,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -9726,7 +9729,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -9779,7 +9782,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -9846,7 +9849,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -9910,7 +9913,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -9986,7 +9989,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -10052,7 +10055,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -10129,7 +10132,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -10180,7 +10183,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -10247,7 +10250,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -10312,7 +10315,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -10389,7 +10392,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_query: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -10453,7 +10456,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_query: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -10529,7 +10532,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, ) -> VectorStoreFileObject: @@ -10588,7 +10591,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -10658,7 +10661,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, ) -> VectorStoreFileContentResponse: @@ -10719,7 +10722,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -10795,7 +10798,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -10861,7 +10864,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, @@ -10939,7 +10942,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, ) -> VectorStoreFileDeleteResponse: @@ -10998,7 +11001,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -11075,7 +11078,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, _is_async: bool = False, @@ -11207,7 +11210,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, extra_body: Optional[Dict[str, Any]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[AsyncHTTPHandler] = None, @@ -11326,7 +11329,7 @@ class BaseLLMHTTPHandler: litellm_params: Dict, logging_obj: LiteLLMLoggingObj, timeout: Union[float, httpx.Timeout], - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, ) -> Union[ @@ -11441,7 +11444,7 @@ class BaseLLMHTTPHandler: litellm_params: Dict, logging_obj: LiteLLMLoggingObj, timeout: Union[float, httpx.Timeout], - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, ) -> "HttpxBinaryResponseContent": """ @@ -11573,7 +11576,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -11639,7 +11642,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, shared_session: Optional["ClientSession"] = None, @@ -11695,7 +11698,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -11754,7 +11757,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, shared_session: Optional["ClientSession"] = None, @@ -11800,7 +11803,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -11856,7 +11859,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, shared_session: Optional["ClientSession"] = None, @@ -11901,7 +11904,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -11957,7 +11960,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, shared_session: Optional["ClientSession"] = None, @@ -12007,7 +12010,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -12066,7 +12069,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, shared_session: Optional["ClientSession"] = None, @@ -12113,7 +12116,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -12172,7 +12175,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, shared_session: Optional["ClientSession"] = None, @@ -12218,7 +12221,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -12274,7 +12277,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, shared_session: Optional["ClientSession"] = None, @@ -12320,7 +12323,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -12379,7 +12382,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, shared_session: Optional["ClientSession"] = None, @@ -12425,7 +12428,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -12481,7 +12484,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, shared_session: Optional["ClientSession"] = None, @@ -12526,7 +12529,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -12582,7 +12585,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, shared_session: Optional["ClientSession"] = None, @@ -12632,7 +12635,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -12691,7 +12694,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, shared_session: Optional["ClientSession"] = None, @@ -12738,7 +12741,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -12797,7 +12800,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, shared_session: Optional["ClientSession"] = None, @@ -12843,7 +12846,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -12899,7 +12902,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, shared_session: Optional["ClientSession"] = None, @@ -12944,7 +12947,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -13000,7 +13003,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, shared_session: Optional["ClientSession"] = None, @@ -13045,7 +13048,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, _is_async: bool = False, @@ -13101,7 +13104,7 @@ class BaseLLMHTTPHandler: custom_llm_provider: str, litellm_params: GenericLiteLLMParams, logging_obj: LiteLLMLoggingObj, - extra_headers: Optional[Dict[str, Any]] = None, + extra_headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, httpx.Timeout]] = None, client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None, shared_session: Optional["ClientSession"] = None, diff --git a/litellm/llms/openai/realtime/http_transformation.py b/litellm/llms/openai/realtime/http_transformation.py index 0a7e65dfea2..e9535d7c4b8 100644 --- a/litellm/llms/openai/realtime/http_transformation.py +++ b/litellm/llms/openai/realtime/http_transformation.py @@ -36,10 +36,10 @@ class OpenAIRealtimeHTTPConfig(BaseRealtimeHTTPConfig): def validate_environment( self, - headers: dict, + headers: dict[str, str], model: str, api_key: Optional[str] = None, - ) -> dict: + ) -> dict[str, str]: return { **headers, "Authorization": f"Bearer {api_key or ''}", diff --git a/litellm/proxy/management_endpoints/key_management_endpoints.py b/litellm/proxy/management_endpoints/key_management_endpoints.py index a94a75fdfa3..cd8e11904a0 100644 --- a/litellm/proxy/management_endpoints/key_management_endpoints.py +++ b/litellm/proxy/management_endpoints/key_management_endpoints.py @@ -20,7 +20,7 @@ import secrets import traceback from collections.abc import Mapping from datetime import datetime, timedelta, timezone -from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, cast +from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple, cast import fastapi import yaml @@ -127,6 +127,7 @@ from litellm.types.proxy.management_endpoints.key_management_endpoints import ( from litellm.types.router import Deployment from litellm.types.utils import ( BudgetConfig, + CredentialItem, PersonalUIKeyGenerationConfig, TeamUIKeyGenerationConfig, ) @@ -489,8 +490,8 @@ _NON_ADMIN_SAFE_ALLOWED_ROUTES_PRESETS = frozenset({"llm_api_routes", "info_rout def _validate_caller_can_change_key_ownership( - data: Optional[BaseModel], - existing_key_row: Any, + data: Union[UpdateKeyRequest, RegenerateKeyRequest] | None, + existing_key_row: LiteLLM_VerificationToken, user_api_key_dict: UserAPIKeyAuth, ) -> None: """ @@ -514,16 +515,16 @@ def _validate_caller_can_change_key_ownership( # ``prepare_key_update_data`` and writes NULL to the token row — # detaching the key from its user and bypassing the user-row # role check on subsequent requests. - fields_set = getattr(data, "model_fields_set", None) or set() + fields_set = data.model_fields_set if "user_id" not in fields_set: return - incoming_user_id = getattr(data, "user_id", None) + incoming_user_id = data.user_id if incoming_user_id is None or incoming_user_id == "": raise HTTPException( status_code=403, detail="Non-admin users cannot remove the user_id from a key.", ) - existing_user_id = getattr(existing_key_row, "user_id", None) + existing_user_id = existing_key_row.user_id if incoming_user_id != existing_user_id: raise HTTPException( status_code=403, @@ -889,14 +890,14 @@ async def _common_key_generation_helper( ) new_budget = prisma_client.jsonify_object(budget_row.json(exclude_none=True)) - _budget = await BudgetRepository(prisma_client).table.create( + _budget: LiteLLM_BudgetTable = await BudgetRepository(prisma_client).table.create( data={ **new_budget, # type: ignore "created_by": user_api_key_dict.user_id or litellm_proxy_admin_name, "updated_by": user_api_key_dict.user_id or litellm_proxy_admin_name, } ) - _budget_id = getattr(_budget, "budget_id", None) + _budget_id = _budget.budget_id # ADD METADATA FIELDS # Set Management Endpoint Metadata Fields @@ -1405,14 +1406,12 @@ async def _validate_caller_can_assign_key_org( detail="Cannot assign a key to an organization without a user_id on the caller's token", ) - user_row = await UserRepository(prisma_client).table.find_unique( + user_row: LiteLLM_UserTable | None = await UserRepository(prisma_client).table.find_unique( where={"user_id": user_api_key_dict.user_id}, include={"organization_memberships": True}, ) - memberships = getattr(user_row, "organization_memberships", None) if user_row else None - member_org_ids = { - membership.organization_id for membership in (memberships or []) if membership.organization_id is not None - } + memberships = user_row.organization_memberships if user_row else None + member_org_ids = {membership.organization_id for membership in (memberships or [])} if organization_id not in member_org_ids: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, @@ -2112,7 +2111,7 @@ async def _process_single_key_update( litellm_changed_by: Optional[str], prisma_client: Optional[PrismaClient], user_api_key_cache: UserApiKeyCache, - proxy_logging_obj: Any, + proxy_logging_obj: ProxyLogging, llm_router: Optional[Router], user_custom_key_update: Optional[Callable] = None, existing_key_row: Optional[LiteLLM_VerificationToken] = None, @@ -2265,9 +2264,9 @@ async def _process_single_key_update( async def _validate_mcp_servers_for_key_update( data: "UpdateKeyRequest", team_obj: Optional["LiteLLM_TeamTableCachedObj"], - existing_key_row: Any, - prisma_client: Any, - user_api_key_cache: Any, + existing_key_row: LiteLLM_VerificationToken, + prisma_client: PrismaClient | None, + user_api_key_cache: UserApiKeyCache, is_proxy_admin: bool, ) -> Optional[ObjectPermissionDict]: """Validate MCP servers in object_permission against the effective team.""" @@ -2302,14 +2301,20 @@ async def _validate_mcp_servers_for_key_update( async def _validate_update_key_data( data: UpdateKeyRequest, - existing_key_row: Any, + existing_key_row: LiteLLM_VerificationToken, user_api_key_dict: UserAPIKeyAuth, - llm_router: Any, + llm_router: Router | None, premium_user: bool, - prisma_client: Any, - user_api_key_cache: Any, + prisma_client: PrismaClient | None, + user_api_key_cache: UserApiKeyCache, ) -> None: """Validate permissions and constraints for key update.""" + if prisma_client is None: + raise HTTPException( + status_code=500, + detail={"error": "Database not connected"}, + ) + # Reject NaN/±inf spend before it can reach the DB / spend counter. validate_finite_spend(data.spend) @@ -2404,17 +2409,24 @@ async def _validate_update_key_data( # admin authorization after the key was reassigned. caller_is_creator = ( user_api_key_dict.user_id is not None - and getattr(existing_key_row, "created_by", None) == user_api_key_dict.user_id - and getattr(existing_key_row, "user_id", None) == user_api_key_dict.user_id + and existing_key_row.created_by == user_api_key_dict.user_id + and existing_key_row.user_id == user_api_key_dict.user_id ) # Team keys: can_team_member_execute_key_management_endpoint (called above) # already validated team membership + /key/update permission and would have # raised if the caller lacked it. Reaching this point on a team key for a # non-budget change means the caller was authorized — skip the redundant # _check_key_admin_access that would otherwise require team/org admin status. - _key_is_team_key = getattr(existing_key_row, "team_id", None) is not None + _key_is_team_key = existing_key_row.team_id is not None can_skip_admin_check = (caller_is_creator or _key_is_team_key) and not _is_budget_change - if (not _is_proxy_admin) and prisma_client is not None and not can_skip_admin_check: + if (not _is_proxy_admin) and not can_skip_admin_check: + if existing_key_row.token is None: + raise ProxyException( + message="Key not found.", + type=ProxyErrorTypes.not_found_error, + param="key", + code=status.HTTP_404_NOT_FOUND, + ) hashed_key = existing_key_row.token await _check_key_admin_access( user_api_key_dict=user_api_key_dict, @@ -2426,7 +2438,7 @@ async def _validate_update_key_data( # Check team limits if key has a team_id (from request or existing key) team_obj: Optional[LiteLLM_TeamTableCachedObj] = None - _team_id_to_check = data.team_id or getattr(existing_key_row, "team_id", None) + _team_id_to_check = data.team_id or existing_key_row.team_id if _team_id_to_check is not None: team_obj = await get_team_object( team_id=_team_id_to_check, @@ -2456,7 +2468,7 @@ async def _validate_update_key_data( ) # Validate key against project limits if project_id is being set - _project_id_to_check = getattr(data, "project_id", None) or getattr(existing_key_row, "project_id", None) + _project_id_to_check = getattr(data, "project_id", None) or existing_key_row.project_id if _project_id_to_check is not None and (data.models is not None or data.max_budget is not None): await _check_project_key_limits( project_id=_project_id_to_check, @@ -3004,6 +3016,7 @@ async def bulk_update_team_keys( }, ) + existing_keys: Sequence[LiteLLM_VerificationToken] if data.all_keys_in_team: # "all" excludes blocked/expired — bulk refresh shouldn't revive a key an admin disabled. # `blocked` is Boolean? with no default; `/key/generate` writes NULL. Prisma's `NOT` @@ -3027,7 +3040,7 @@ async def bulk_update_team_keys( "error": f"Team {data.team_id} has more than {MAX_BATCH_SIZE} keys. Use `key_ids` to update in batches of {MAX_BATCH_SIZE}." }, ) - requested_tokens = [row.token for row in existing_keys] + requested_tokens = [row.token for row in existing_keys if row.token is not None] else: if data.key_ids is None or len(data.key_ids) == 0: raise HTTPException( @@ -3416,7 +3429,9 @@ async def info_key_fn_v2( # Resolve key_aliases to tokens so we never pass token=None (unbounded query) tokens_to_query = list(data.keys) if data.keys else [] if data.key_aliases: - alias_rows = await VerificationTokenRepository(prisma_client).table.find_many( + alias_rows: Sequence[LiteLLM_VerificationToken] = await VerificationTokenRepository( + prisma_client + ).table.find_many( where={"key_alias": {"in": data.key_aliases}}, include={"litellm_budget_table": True}, ) @@ -4175,9 +4190,9 @@ async def delete_key_aliases( user_api_key_dict: UserAPIKeyAuth, litellm_changed_by: Optional[str] = None, ) -> Tuple[Optional[Dict], List[LiteLLM_VerificationToken]]: - _keys_being_deleted = await VerificationTokenRepository(prisma_client).table.find_many( - where={"key_alias": {"in": key_aliases}} - ) + _keys_being_deleted: Sequence[LiteLLM_VerificationToken] = await VerificationTokenRepository( + prisma_client + ).table.find_many(where={"key_alias": {"in": key_aliases}}) tokens = [key.token for key in _keys_being_deleted] return await delete_verification_tokens( @@ -4242,7 +4257,7 @@ async def _rotate_master_key( ) # 3. process config table try: - config = await ConfigRepository(prisma_client).table.find_many() + config: Sequence[LiteLLM_Config] | None = await ConfigRepository(prisma_client).table.find_many() except Exception: config = None @@ -4307,7 +4322,7 @@ async def _rotate_master_key( # 5. process credentials table try: - credentials = await CredentialsRepository(prisma_client).table.find_many() + credentials: Sequence[CredentialItem] | None = await CredentialsRepository(prisma_client).table.find_many() except Exception: credentials = None if credentials: @@ -4571,7 +4586,7 @@ async def _execute_virtual_key_regeneration( grace_period=data.grace_period if data else None, ) - updated_token = await VerificationTokenRepository(prisma_client).table.update( + updated_token: LiteLLM_VerificationToken | None = await VerificationTokenRepository(prisma_client).table.update( where={"token": hashed_api_key}, data=update_data, # type: ignore ) @@ -4772,7 +4787,9 @@ async def regenerate_key_fn( else: hashed_api_key = hash_token(key) - _key_in_db = await VerificationTokenRepository(prisma_client).table.find_unique( + _key_in_db: LiteLLM_VerificationToken | None = await VerificationTokenRepository( + prisma_client + ).table.find_unique( where={"token": hashed_api_key}, ) if _key_in_db is None: @@ -4976,7 +4993,9 @@ async def reset_key_spend_fn( else: hashed_api_key = hash_token(key) - _key_in_db = await VerificationTokenRepository(prisma_client).table.find_unique( + _key_in_db: LiteLLM_VerificationToken | None = await VerificationTokenRepository( + prisma_client + ).table.find_unique( where={"token": hashed_api_key}, include={"litellm_budget_table": True}, ) @@ -4996,7 +5015,7 @@ async def reset_key_spend_fn( user_api_key_cache=user_api_key_cache, ) - updated_key = await VerificationTokenRepository(prisma_client).table.update( + updated_key: LiteLLM_VerificationToken | None = await VerificationTokenRepository(prisma_client).table.update( where={"token": hashed_api_key}, data={"spend": reset_to}, ) @@ -5421,8 +5440,8 @@ async def list_keys( async def _apply_non_admin_alias_scope( user_api_key_dict: UserAPIKeyAuth, - prisma_client: Any, - query_params: List[Any], + prisma_client: PrismaClient, + query_params: List[str], where_parts: List[str], ) -> None: """Append SQL scope conditions so non-admin users only see aliases for @@ -5493,7 +5512,7 @@ async def key_aliases( # support column-level SELECT projection on find_many. # # $1 is always UI_SESSION_TOKEN_TEAM_ID (filters out UI session tokens). - query_params: List[Any] = [UI_SESSION_TOKEN_TEAM_ID] + query_params: List[str] = [UI_SESSION_TOKEN_TEAM_ID] where_parts = [ "key_alias IS NOT NULL", "key_alias != ''", @@ -5932,7 +5951,7 @@ def _get_condition_to_filter_out_ui_session_tokens() -> Dict[str, Any]: async def _check_key_admin_access( user_api_key_dict: UserAPIKeyAuth, hashed_token: str, - prisma_client: Any, + prisma_client: PrismaClient, user_api_key_cache: UserApiKeyCache, route: str, ) -> None: @@ -5951,7 +5970,9 @@ async def _check_key_admin_access( return # Look up the target key to find its team - target_key_row = await VerificationTokenRepository(prisma_client).table.find_unique(where={"token": hashed_token}) + target_key_row: LiteLLM_VerificationToken | None = await VerificationTokenRepository( + prisma_client + ).table.find_unique(where={"token": hashed_token}) if target_key_row is None: raise HTTPException( status_code=404, @@ -6047,7 +6068,9 @@ async def block_key( ) # Check if the key exists before trying to block it - existing_record = await VerificationTokenRepository(prisma_client).table.find_unique(where={"token": hashed_token}) + existing_record: LiteLLM_VerificationToken | None = await VerificationTokenRepository( + prisma_client + ).table.find_unique(where={"token": hashed_token}) if existing_record is None: raise ProxyException( message="Key not found.", @@ -6077,7 +6100,7 @@ async def block_key( ) ) - record = await VerificationTokenRepository(prisma_client).table.update( + record: LiteLLM_VerificationToken | None = await VerificationTokenRepository(prisma_client).table.update( where={"token": hashed_token}, data={"blocked": True}, # type: ignore ) @@ -6158,7 +6181,9 @@ async def unblock_key( ) # Check if the key exists before trying to unblock it - existing_record = await VerificationTokenRepository(prisma_client).table.find_unique(where={"token": hashed_token}) + existing_record: LiteLLM_VerificationToken | None = await VerificationTokenRepository( + prisma_client + ).table.find_unique(where={"token": hashed_token}) if existing_record is None: raise ProxyException( message="Key not found.", @@ -6188,7 +6213,7 @@ async def unblock_key( ) ) - record = await VerificationTokenRepository(prisma_client).table.update( + record: LiteLLM_VerificationToken | None = await VerificationTokenRepository(prisma_client).table.update( where={"token": hashed_token}, data={"blocked": False}, # type: ignore ) @@ -6443,7 +6468,7 @@ def _validate_key_alias_format(key_alias: Optional[str]) -> None: async def _enforce_unique_key_alias( key_alias: Optional[str], - prisma_client: Any, + prisma_client: PrismaClient | None, existing_key_token: Optional[str] = None, ) -> None: """ @@ -6451,7 +6476,7 @@ async def _enforce_unique_key_alias( Args: key_alias (Optional[str]): The key alias to check - prisma_client (Any): Prisma client instance + prisma_client (Optional[PrismaClient]): Prisma client instance existing_key_token (Optional[str]): ID of existing key being updated, to exclude from uniqueness check (The Admin UI passes key_alias, in all Edit key requests. So we need to be sure that if we find a key with the same alias, it's not the same key we're updating) diff --git a/litellm/proxy/management_endpoints/team_endpoints.py b/litellm/proxy/management_endpoints/team_endpoints.py index c35c17aa359..20cf00ac80f 100644 --- a/litellm/proxy/management_endpoints/team_endpoints.py +++ b/litellm/proxy/management_endpoints/team_endpoints.py @@ -14,7 +14,7 @@ import json import math import traceback from datetime import datetime, timezone -from typing import Annotated, Any, Dict, List, Mapping, Optional, Tuple, Union, cast +from typing import Annotated, Dict, List, Mapping, Optional, Sequence, Tuple, TypedDict, Union, cast import fastapi from fastapi import APIRouter, Depends, Header, HTTPException, Request, status @@ -30,7 +30,10 @@ from litellm.proxy._types import ( BlockTeamRequest, CommonProxyErrors, DeleteTeamRequest, + KeyManagementRoutes, + LiteLLM_AccessGroupTable, LiteLLM_AuditLogs, + LiteLLM_BudgetTable, LiteLLM_DeletedTeamTable, LiteLLM_ManagementEndpoint_MetadataFields, LiteLLM_ManagementEndpoint_MetadataFields_Premium, @@ -78,6 +81,7 @@ from litellm.proxy.auth.auth_checks import ( from litellm.proxy.auth.user_api_key_auth import user_api_key_auth from litellm.proxy.common_utils.callback_utils import encrypt_callback_vars from litellm.proxy.common_utils.json_merge_patch import apply_json_merge_patch +from litellm.proxy.common_utils.user_api_key_cache import UserApiKeyCache from litellm.proxy.management_endpoints.common_utils import ( _check_passthrough_routes_caller_permission, _is_user_org_admin_for_team, @@ -106,7 +110,7 @@ from litellm.proxy.management_helpers.utils import ( add_new_member, management_endpoint_wrapper, ) -from litellm.proxy.utils import PrismaClient, handle_exception_on_proxy +from litellm.proxy.utils import PrismaClient, ProxyLogging, handle_exception_on_proxy from litellm.repositories.budget_repository import BudgetRepository from litellm.repositories.organization_repository import OrganizationRepository from litellm.repositories.table_repositories import ( @@ -141,6 +145,11 @@ from litellm.types.proxy.management_endpoints.team_endpoints import ( router = APIRouter() +class _TeamKeyCountRow(TypedDict): + team_id: str + _count: Mapping[str, int] + + def _sanitize_for_log(value: object) -> str: """Strip CR/LF from user-controlled values to prevent log injection.""" try: @@ -151,9 +160,9 @@ def _sanitize_for_log(value: object) -> str: async def _refresh_cached_team( - team_row: Any, - user_api_key_cache: Any, - proxy_logging_obj: Any, + team_row: LiteLLM_TeamTable, + user_api_key_cache: UserApiKeyCache, + proxy_logging_obj: ProxyLogging | None, ) -> None: """ Refresh the in-memory cached team object after a DB write. @@ -274,7 +283,7 @@ class TeamMemberBudgetHandler: if team_member_budget_duration is not None: budget_request.budget_duration = team_member_budget_duration - team_member_budget_table = await new_budget( + team_member_budget_table: LiteLLM_BudgetTable = await new_budget( budget_obj=budget_request, user_api_key_dict=user_api_key_dict, ) @@ -322,7 +331,7 @@ class TeamMemberBudgetHandler: if team_member_budget_duration is not None: budget_request.budget_duration = team_member_budget_duration - budget_row = await update_budget( + budget_row: LiteLLM_BudgetTable = await update_budget( budget_obj=budget_request, user_api_key_dict=user_api_key_dict, ) @@ -395,7 +404,7 @@ class TeamMemberBudgetHandler: @staticmethod async def backfill_team_member_budget_entries( team_id: str, - members_with_roles: List[Union[Member, dict]], + members_with_roles: Sequence[Union[Member, dict]], team_member_budget_id: str, prisma_client: PrismaClient, ) -> None: @@ -460,7 +469,7 @@ class TeamMemberBudgetHandler: ) -def _get_default_team_param(field: str) -> Any: +def _get_default_team_param(field: str) -> object: """ Returns a default value for the given field from litellm.default_team_params config. Returns None if no default is configured. @@ -790,7 +799,7 @@ async def _check_user_team_limits( data: Union[NewTeamRequest, UpdateTeamRequest], user_api_key_dict: UserAPIKeyAuth, prisma_client: PrismaClient, - user_api_key_cache: Any, + user_api_key_cache: UserApiKeyCache, ) -> None: """ Enforce the caller's personal limits when CREATING a standalone team. @@ -1051,7 +1060,7 @@ async def new_team( ) # Check if license is over limit - total_teams = await TeamRepository(prisma_client).table.count() + total_teams: int = await TeamRepository(prisma_client).table.count() if total_teams and _license_check.is_team_count_over_limit(team_count=total_teams): raise HTTPException( status_code=403, @@ -1153,7 +1162,7 @@ async def new_team( created_by=user_api_key_dict.user_id or litellm_proxy_admin_name, updated_by=user_api_key_dict.user_id or litellm_proxy_admin_name, ) - model_dict = await ModelTableRepository(prisma_client).table.create( + model_dict: LiteLLM_ModelTable = await ModelTableRepository(prisma_client).table.create( {**litellm_modeltable.json(exclude_none=True)} # type: ignore ) # type: ignore @@ -1357,11 +1366,11 @@ async def _create_team_update_audit_log( async def _update_model_table( data: UpdateTeamRequest, - model_id: Optional[str], + model_id: int | None, prisma_client: PrismaClient, user_api_key_dict: UserAPIKeyAuth, litellm_proxy_admin_name: str, -) -> Optional[str]: +) -> int | None: """ Upsert model table and return the model id """ @@ -1374,7 +1383,7 @@ async def _update_model_table( updated_by=user_api_key_dict.user_id or litellm_proxy_admin_name, ) if model_id is None: - model_dict = await ModelTableRepository(prisma_client).table.create( + model_dict: LiteLLM_ModelTable = await ModelTableRepository(prisma_client).table.create( data={**litellm_modeltable.json(exclude_none=True)} # type: ignore ) else: @@ -1394,7 +1403,7 @@ async def _update_model_table( async def _auto_add_team_members_to_organization( team: LiteLLM_TeamTable, organization: LiteLLM_OrganizationTableWithMembers, - prisma_client: Any, + prisma_client: PrismaClient, ) -> None: """ When moving a team to an org, ensure all team members are also org members. @@ -1432,11 +1441,11 @@ async def _auto_add_team_members_to_organization( async def fetch_and_validate_organization( organization_id: str, - existing_team_row: Any, + existing_team_row: LiteLLM_TeamTable, llm_router: Optional[Router], - prisma_client: Any, + prisma_client: PrismaClient, user_api_key_dict: Optional[UserAPIKeyAuth] = None, -) -> Any: +) -> LiteLLM_OrganizationTable: """ Fetch and validate an organization for team update operations. @@ -1455,7 +1464,7 @@ async def fetch_and_validate_organization( if llm_router is None: raise HTTPException(status_code=500, detail={"error": CommonProxyErrors.no_llm_router.value}) - organization_row = await OrganizationRepository(prisma_client).table.find_unique( + organization_row: LiteLLM_OrganizationTable | None = await OrganizationRepository(prisma_client).table.find_unique( where={"organization_id": organization_id}, include={"litellm_budget_table": True, "members": True, "teams": True}, ) @@ -2004,7 +2013,9 @@ async def patch_team( patch_fields = data.model_dump(exclude_unset=True, exclude={"team_id"}) if "metadata" in patch_fields: - existing_team_row = await TeamRepository(prisma_client).table.find_unique(where={"team_id": team_id}) + existing_team_row: LiteLLM_TeamTable | None = await TeamRepository(prisma_client).table.find_unique( + where={"team_id": team_id} + ) if existing_team_row is None: raise HTTPException( status_code=404, @@ -2259,7 +2270,7 @@ async def _process_team_members( # Resolve allowed_models: explicit request value, or fall back to team's default_team_member_models member_allowed_models = data.allowed_models - team_default_member_models = getattr(complete_team_data, "default_team_member_models", None) + team_default_member_models = complete_team_data.default_team_member_models if member_allowed_models is None and team_default_member_models: member_allowed_models = team_default_member_models @@ -2470,10 +2481,10 @@ async def _validate_and_populate_member_user_info( ) # Get the single user - user_by_email = users_by_email[0] + matched_user: LiteLLM_UserTable = users_by_email[0] # Verify the user_id matches - if user_by_email.user_id != member.user_id: + if matched_user.user_id != member.user_id: raise HTTPException( status_code=400, detail={ @@ -2486,7 +2497,7 @@ async def _validate_and_populate_member_user_info( # Case 2: Only user_email provided - populate user_id from DB if member.user_email is not None and member.user_id is None: - user_by_email = await UserRepository(prisma_client).table.find_first( + user_by_email: LiteLLM_UserTable | None = await UserRepository(prisma_client).table.find_first( where={"user_email": {"equals": member.user_email, "mode": "insensitive"}} ) @@ -2515,7 +2526,9 @@ async def _validate_and_populate_member_user_info( # Case 3: Only user_id provided - populate user_email from DB if user exists if member.user_id is not None and member.user_email is None: - user_by_id = await UserRepository(prisma_client).table.find_unique(where={"user_id": member.user_id}) + user_by_id: LiteLLM_UserTable | None = await UserRepository(prisma_client).table.find_unique( + where={"user_id": member.user_id} + ) if user_by_id is None: # User doesn't exist yet - allow it to pass with user_email as None @@ -2706,7 +2719,9 @@ async def team_member_delete( detail={"error": "Either user_id or user_email needs to be passed in"}, ) - _existing_team_row = await TeamRepository(prisma_client).table.find_unique(where={"team_id": data.team_id}) + _existing_team_row: LiteLLM_TeamTable | None = await TeamRepository(prisma_client).table.find_unique( + where={"team_id": data.team_id} + ) if _existing_team_row is None: raise HTTPException( @@ -2834,7 +2849,7 @@ _MEMBER_BUDGET_PATCH_FIELDS = { } -def _build_member_budget_patch(data: TeamMemberUpdateRequest) -> Dict[str, Any]: +def _build_member_budget_patch(data: TeamMemberUpdateRequest) -> Dict[str, object]: """Map the budget fields the request actually set (merge-patch: a sent value updates, an explicit null clears, an absent field is left untouched) to their budget-table columns.""" @@ -2910,7 +2925,9 @@ async def team_member_update( _validate_budget_duration(data.budget_duration) - _existing_team_row = await TeamRepository(prisma_client).table.find_unique(where={"team_id": data.team_id}) + _existing_team_row: LiteLLM_TeamTable | None = await TeamRepository(prisma_client).table.find_unique( + where={"team_id": data.team_id} + ) if _existing_team_row is None: raise HTTPException( @@ -3378,7 +3395,7 @@ def _transform_teams_to_deleted_records( teams: List[LiteLLM_TeamTable], user_api_key_dict: UserAPIKeyAuth, litellm_changed_by: Optional[str] = None, -) -> List[Dict[str, Any]]: +) -> List[Dict[str, object]]: """Transform teams into deleted team records ready for persistence.""" if not teams: return [] @@ -3423,7 +3440,7 @@ def _transform_teams_to_deleted_records( async def _save_deleted_team_records( - records: List[Dict[str, Any]], + records: List[Dict[str, object]], prisma_client: PrismaClient, ) -> None: """Save deleted team records to the database.""" @@ -3517,7 +3534,7 @@ async def _add_team_member_budget_table( return team_info_response_object -async def _resolve_team_access_group_resources(_team_info: Any) -> None: +async def _resolve_team_access_group_resources(_team_info: TeamInfoResponseObjectTeamTable) -> None: """Populate access_group_models / mcp_server_ids / agent_ids on the team info response by resolving inherited resources from its access groups.""" if not _team_info.access_group_ids: @@ -3818,7 +3835,9 @@ async def block_team( if prisma_client is None: raise Exception("No DB Connected.") - existing_team = await TeamRepository(prisma_client).table.find_unique(where={"team_id": data.team_id}) + existing_team: LiteLLM_TeamTable | None = await TeamRepository(prisma_client).table.find_unique( + where={"team_id": data.team_id} + ) if existing_team is None: raise HTTPException( status_code=404, @@ -3867,7 +3886,9 @@ async def unblock_team( if prisma_client is None: raise Exception("No DB Connected.") - existing_team = await TeamRepository(prisma_client).table.find_unique(where={"team_id": data.team_id}) + existing_team: LiteLLM_TeamTable | None = await TeamRepository(prisma_client).table.find_unique( + where={"team_id": data.team_id} + ) if existing_team is None: raise HTTPException( status_code=404, @@ -3933,9 +3954,9 @@ async def list_available_teams( async def _get_org_admin_org_ids( user_id: str, - prisma_client: Any, - user_api_key_cache: Any, - proxy_logging_obj: Any, + prisma_client: PrismaClient, + user_api_key_cache: UserApiKeyCache, + proxy_logging_obj: ProxyLogging | None, ) -> Optional[List[str]]: """ Return the list of organization IDs where the user is an org admin. @@ -3974,16 +3995,16 @@ async def _build_team_list_where_conditions( use_deleted_table: bool, search: Optional[str] = None, org_admin_org_ids: Optional[List[str]] = None, - user_api_key_cache: Optional[Any] = None, - proxy_logging_obj: Optional[Any] = None, -) -> Optional[Dict[str, Any]]: + user_api_key_cache: UserApiKeyCache | None = None, + proxy_logging_obj: ProxyLogging | None = None, +) -> Dict[str, object] | None: """ Build where conditions for team list query. Returns None when the query is guaranteed to yield no results (e.g. user has no team memberships), allowing the caller to skip the DB round-trip. """ - where_conditions: Dict[str, Any] = {} + where_conditions: Dict[str, object] = {} if team_id: where_conditions["team_id"] = team_id @@ -4065,7 +4086,7 @@ async def _batch_resolve_access_group_resources( return {} unique_ids = list(set(all_access_group_ids)) - rows = await AccessGroupRepository(_prisma_client).table.find_many( + rows: Sequence[LiteLLM_AccessGroupTable] = await AccessGroupRepository(_prisma_client).table.find_many( where={"access_group_id": {"in": unique_ids}}, ) @@ -4113,7 +4134,7 @@ def _convert_teams_to_response_models( async def _get_keys_count_by_team( - prisma_client: Any, + prisma_client: PrismaClient, teams: list, ) -> Dict[str, int]: """Aggregate virtual-key counts per team for the given page of teams. @@ -4126,7 +4147,7 @@ async def _get_keys_count_by_team( if not page_team_ids: return {} - grouped = await VerificationTokenRepository(prisma_client).table.group_by( + grouped: Sequence[_TeamKeyCountRow] = await VerificationTokenRepository(prisma_client).table.group_by( by=["team_id"], where={"team_id": {"in": page_team_ids}}, count={"team_id": True}, @@ -4138,9 +4159,9 @@ async def _enforce_list_team_v2_access( user_api_key_dict: UserAPIKeyAuth, user_id: Optional[str], organization_id: Optional[str], - prisma_client: Any, - user_api_key_cache: Any, - proxy_logging_obj: Any, + prisma_client: PrismaClient, + user_api_key_cache: UserApiKeyCache, + proxy_logging_obj: ProxyLogging | None, ) -> Tuple[Optional[str], Optional[List[str]]]: """Enforce access control for list_team_v2. @@ -4339,7 +4360,7 @@ async def list_team_v2( order=order_by if order_by else {"created_at": "desc"}, # Default sort ) # Get total count for pagination - total_count = await DeletedTeamRepository(prisma_client).table.count(where=where_conditions) + total_count: int = await DeletedTeamRepository(prisma_client).table.count(where=where_conditions) else: teams = await TeamRepository(prisma_client).table.find_many( where=where_conditions, @@ -4391,9 +4412,9 @@ async def list_team_v2( async def _authorize_and_filter_teams( user_api_key_dict: UserAPIKeyAuth, user_id: Optional[str], - prisma_client: Any, - user_api_key_cache: Any, - proxy_logging_obj: Any, + prisma_client: PrismaClient, + user_api_key_cache: UserApiKeyCache, + proxy_logging_obj: ProxyLogging | None, ) -> list: """ Authorize the /team/list request and return filtered teams. @@ -4565,7 +4586,7 @@ async def get_paginated_teams( # Calculate skip for pagination skip = (page - 1) * page_size # Get total count - total_count = await TeamRepository(prisma_client).table.count() + total_count: int = await TeamRepository(prisma_client).table.count() # Get paginated teams teams = await TeamRepository(prisma_client).table.find_many( @@ -4701,7 +4722,9 @@ async def team_model_add( raise HTTPException(status_code=500, detail={"error": "No db connected"}) # Get existing team - team_row = await TeamRepository(prisma_client).table.find_unique(where={"team_id": data.team_id}) + team_row: LiteLLM_TeamTable | None = await TeamRepository(prisma_client).table.find_unique( + where={"team_id": data.team_id} + ) if team_row is None: raise HTTPException( @@ -4747,7 +4770,7 @@ async def team_model_add( # the writer and lets Prisma bump updated_at. # `include` mirrors the relations the auth path consumes off the cached # team object so that `_refresh_cached_team` doesn't null them out. - updated_team = await TeamRepository(prisma_client).table.update( + updated_team: LiteLLM_TeamTable = await TeamRepository(prisma_client).table.update( where={"team_id": data.team_id}, data={"updated_at": datetime.now(timezone.utc)}, include={"object_permission": True}, # type: ignore @@ -4801,7 +4824,9 @@ async def team_model_delete( raise HTTPException(status_code=500, detail={"error": "No db connected"}) # Get existing team - team_row = await TeamRepository(prisma_client).table.find_unique(where={"team_id": data.team_id}) + team_row: LiteLLM_TeamTable | None = await TeamRepository(prisma_client).table.find_unique( + where={"team_id": data.team_id} + ) if team_row is None: raise HTTPException( @@ -4829,7 +4854,7 @@ async def team_model_delete( updated_models = [m for m in current_models if m not in data.models] # Update team. See team_model_add for the rationale on `include`. - updated_team = await TeamRepository(prisma_client).table.update( + updated_team: LiteLLM_TeamTable = await TeamRepository(prisma_client).table.update( where={"team_id": data.team_id}, data={"models": updated_models}, include={"object_permission": True}, # type: ignore @@ -4964,7 +4989,7 @@ async def update_team_member_permissions( }, ) # Update the team member permissions - updated_team = await TeamRepository(prisma_client).table.update( + updated_team: LiteLLM_TeamTable = await TeamRepository(prisma_client).table.update( where={"team_id": data.team_id}, data={"team_member_permissions": data.team_member_permissions}, ) @@ -5034,7 +5059,11 @@ async def bulk_update_team_member_permissions( } -async def _compute_and_batch_updates(prisma_client, teams, permissions_to_add: set) -> int: +async def _compute_and_batch_updates( + prisma_client: PrismaClient, + teams: Sequence[LiteLLM_TeamTable], + permissions_to_add: set[KeyManagementRoutes], +) -> int: """Compute merged permissions and batch-write updates. Returns count of teams updated.""" updates = [] for team in teams: @@ -5056,9 +5085,11 @@ async def _compute_and_batch_updates(prisma_client, teams, permissions_to_add: s return len(updates) -async def _append_permissions_to_specific_teams(prisma_client, team_ids: List[str], permissions_to_add: set) -> int: +async def _append_permissions_to_specific_teams( + prisma_client: PrismaClient, team_ids: List[str], permissions_to_add: set[KeyManagementRoutes] +) -> int: """Fetch specific teams by ID and append permissions.""" - teams = await TeamRepository(prisma_client).table.find_many( + teams: Sequence[LiteLLM_TeamTable] = await TeamRepository(prisma_client).table.find_many( where={"team_id": {"in": team_ids}}, ) @@ -5073,10 +5104,12 @@ async def _append_permissions_to_specific_teams(prisma_client, team_ids: List[st return await _compute_and_batch_updates(prisma_client, teams, permissions_to_add) -async def _append_permissions_to_all_teams(prisma_client, permissions_to_add: set) -> int: +async def _append_permissions_to_all_teams( + prisma_client: PrismaClient, permissions_to_add: set[KeyManagementRoutes] +) -> int: """Paginated read + batched write across all teams.""" teams_updated = 0 - cursor = None + cursor: str | None = None BATCH_SIZE = 500 while True: @@ -5088,7 +5121,7 @@ async def _append_permissions_to_all_teams(prisma_client, permissions_to_add: se find_args["cursor"] = {"team_id": cursor} find_args["skip"] = 1 - teams = await TeamRepository(prisma_client).table.find_many(**find_args) + teams: Sequence[LiteLLM_TeamTable] = await TeamRepository(prisma_client).table.find_many(**find_args) if not teams: break @@ -5188,8 +5221,12 @@ async def get_team_daily_activity( where_condition = {} if team_ids_list: where_condition["team_id"] = {"in": list(team_ids_list)} - team_aliases = await TeamRepository(prisma_client).table.find_many(where=where_condition) - team_alias_metadata = {t.team_id: {"team_alias": t.team_alias} for t in team_aliases} + team_aliases: Sequence[LiteLLM_TeamTable] = await TeamRepository(prisma_client).table.find_many( + where=where_condition + ) + team_alias_metadata: Mapping[str, Dict[str, object]] = { + t.team_id: {"team_alias": t.team_alias} for t in team_aliases + } # Check if user is team admin or has /team/daily/activity permission # If not, filter by user's API keys. @@ -5219,9 +5256,9 @@ async def get_team_daily_activity( # If user does not have full team view, filter by their API keys if not has_full_team_view: # Get all API keys for this user - user_keys = await VerificationTokenRepository(prisma_client).table.find_many( - where={"user_id": user_api_key_dict.user_id} - ) + user_keys: Sequence[LiteLLM_VerificationToken] = await VerificationTokenRepository( + prisma_client + ).table.find_many(where={"user_id": user_api_key_dict.user_id}) user_api_keys = [key.token for key in user_keys if key.token] # If user has no API keys, return empty result if not user_api_keys: diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 18a927e7a44..f2eb8edb91c 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -648,7 +648,7 @@ from fastapi.responses import ( RedirectResponse, StreamingResponse, ) -from fastapi.routing import APIRouter +from fastapi.routing import APIRoute, APIRouter from fastapi.security import OAuth2PasswordBearer from fastapi.security.api_key import APIKeyHeader from fastapi.staticfiles import StaticFiles @@ -839,21 +839,14 @@ async def _initialize_shared_aiohttp_session(): _build_aiohttp_keepalive_socket_factory, ) - connector_kwargs: Dict[str, Any] = { - "keepalive_timeout": AIOHTTP_KEEPALIVE_TIMEOUT, - "ttl_dns_cache": AIOHTTP_TTL_DNS_CACHE, - } - if AIOHTTP_NEEDS_CLEANUP_CLOSED: - connector_kwargs["enable_cleanup_closed"] = True - if AIOHTTP_CONNECTOR_LIMIT > 0: - connector_kwargs["limit"] = AIOHTTP_CONNECTOR_LIMIT - if AIOHTTP_CONNECTOR_LIMIT_PER_HOST > 0: - connector_kwargs["limit_per_host"] = AIOHTTP_CONNECTOR_LIMIT_PER_HOST - socket_factory = _build_aiohttp_keepalive_socket_factory() - if socket_factory is not None: - connector_kwargs["socket_factory"] = socket_factory - - connector = TCPConnector(**connector_kwargs) + connector = TCPConnector( + keepalive_timeout=AIOHTTP_KEEPALIVE_TIMEOUT, + ttl_dns_cache=AIOHTTP_TTL_DNS_CACHE, + enable_cleanup_closed=AIOHTTP_NEEDS_CLEANUP_CLOSED, + limit=AIOHTTP_CONNECTOR_LIMIT if AIOHTTP_CONNECTOR_LIMIT > 0 else 100, + limit_per_host=AIOHTTP_CONNECTOR_LIMIT_PER_HOST if AIOHTTP_CONNECTOR_LIMIT_PER_HOST > 0 else 0, + socket_factory=_build_aiohttp_keepalive_socket_factory(), + ) session = ClientSession(connector=connector) verbose_proxy_logger.info( @@ -1153,7 +1146,7 @@ async def proxy_startup_event(app: FastAPI): await proxy_shutdown_event() # type: ignore[reportGeneralTypeIssues] -def _generate_stable_operation_id(route: Any) -> str: +def _generate_stable_operation_id(route: APIRoute) -> str: operation_id = re.sub(r"\W", "_", f"{route.name}{route.path_format}") route_methods = sorted(route.methods or []) if len(route_methods) == 1: @@ -1195,7 +1188,9 @@ def ensure_unique_openapi_operation_ids( ) -> Dict[str, Any]: operation_entries = [] operation_id_counts: Dict[str, int] = {} - for path_item in openapi_schema.get("paths", {}).values(): + paths = openapi_schema.get("paths", {}) + paths_dict = paths if isinstance(paths, dict) else {} + for path_item in paths_dict.values(): if not isinstance(path_item, dict): continue for method, operation in path_item.items(): @@ -3518,11 +3513,11 @@ _DB_OVERLAY_REMOTE_MODULE_LIST_FIELDS: Dict[str, Tuple[str, ...]] = { } -def _is_remote_module_url(value: Any) -> bool: +def _is_remote_module_url(value: object) -> bool: return isinstance(value, str) and (value.startswith("s3://") or value.startswith("gcs://")) -def _scrub_guardrail_inner(inner: Dict[str, Any]) -> None: +def _scrub_guardrail_inner(inner: Dict[str, JsonValue]) -> None: """Strip remote-URL entries from a guardrail's ``callbacks`` list and ``guardrail`` (v2 module-path) field. Mutates in place.""" cbs = inner.get("callbacks") @@ -3542,7 +3537,7 @@ def _scrub_guardrail_inner(inner: Dict[str, Any]) -> None: inner["guardrail"] = None -def _scrub_db_overlay_remote_module_loads(section: str, db_value: Any) -> Any: +def _scrub_db_overlay_remote_module_loads(section: str, db_value: JsonValue) -> JsonValue: """Strip ``s3://`` / ``gcs://`` entries from the DB-overlay value for fields whose contents reach ``get_instance_fn``. The same scheme is allowed from a YAML config (the documented operator flow) but a @@ -5649,7 +5644,7 @@ class ProxyConfig: ) @staticmethod - def _parse_router_settings_value(value: Any) -> Optional[dict]: + def _parse_router_settings_value(value: object) -> dict | None: """ Parse a router_settings value that may be a dict or a JSON/YAML string. @@ -8945,7 +8940,7 @@ async def model_info( ) -def _blocked_response_usage(original_response: Optional[Any]) -> "litellm.Usage": +def _blocked_response_usage(original_response: object | None) -> "litellm.Usage": """ Token usage for a synthetic guardrail-blocked response. @@ -11467,7 +11462,7 @@ def _enrich_model_info_with_litellm_data( async def _get_caller_byok_team_scope( user_api_key_dict: Optional[UserAPIKeyAuth], - prisma_client: Optional[Any], + prisma_client: PrismaClient | None, ) -> Optional[Set[str]]: """ Return the team IDs whose BYOK rows the caller is allowed to see via @@ -11524,8 +11519,8 @@ _SORTED_SEARCH_DB_FETCH_CAP = 500 async def _fetch_db_models_for_search( - prisma_client: Any, - proxy_config: Any, + prisma_client: PrismaClient, + proxy_config: ProxyConfig, search_lower: str, db_model_ids_in_router: Set[str], router_models_count: int, @@ -11590,8 +11585,8 @@ async def _fetch_db_models_for_search( async def _apply_search_filter_to_models( all_models: List[Dict[str, Any]], search: str, - prisma_client: Optional[Any], - proxy_config: Any, + prisma_client: PrismaClient | None, + proxy_config: ProxyConfig, user_api_key_dict: Optional[UserAPIKeyAuth] = None, page: int = 1, size: int = 50, @@ -11696,7 +11691,7 @@ async def _apply_search_filter_to_models( return filtered_router_models + db_models, search_total_count -def _normalize_datetime_for_sorting(dt: Any) -> Optional[datetime]: +def _normalize_datetime_for_sorting(dt: object) -> datetime | None: """ Normalize a datetime value to a timezone-aware UTC datetime for sorting. @@ -15095,7 +15090,7 @@ def _general_settings_ui_litellm_default( return False if spec["type"] == "Boolean" else None -def _validate_general_settings_ui_litellm_value(field_name: str, value: Any) -> GeneralSettingsUILiteLLMValue: +def _validate_general_settings_ui_litellm_value(field_name: str, value: JsonValue) -> GeneralSettingsUILiteLLMValue: spec = _GENERAL_SETTINGS_UI_LITELLM_FIELDS[field_name] field_type = spec["type"] if value is None or value == "": @@ -15135,7 +15130,7 @@ def _validate_general_settings_ui_litellm_value(field_name: str, value: Any) -> async def _persist_general_settings_ui_litellm_field( - field_name: str, value: Any, user_api_key_dict: UserAPIKeyAuth + field_name: str, value: JsonValue, user_api_key_dict: UserAPIKeyAuth ) -> dict: validated = _validate_general_settings_ui_litellm_value(field_name, value) config = await proxy_config.get_config() diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index 924189fed4b..92ce4b2c7b1 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -28,6 +28,7 @@ from typing import ( Optional, Sequence, Tuple, + TypeVar, Union, cast, overload, @@ -178,7 +179,7 @@ if TYPE_CHECKING: from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj from litellm.proxy.db.spend_log_tool_index import ToolUsageTransaction - Span = Union[_Span, Any] + Span = _Span else: Span = Any @@ -345,7 +346,7 @@ def _accepts_litellm_call_info(cb: CustomLogger) -> bool: return _CALLBACK_ACCEPTS_CALL_INFO[key] -def _enrich_http_exception_with_guardrail_context(exc: BaseException, callback: Any) -> None: +def _enrich_http_exception_with_guardrail_context(exc: BaseException, callback: CustomLogger) -> None: """ If `exc` is an HTTPException with a dict `detail`, mutate it in place to add `guardrail_name` and `guardrail_mode` taken from the callback instance. @@ -367,6 +368,9 @@ def _enrich_http_exception_with_guardrail_context(exc: BaseException, callback: detail.setdefault("guardrail_mode", event_hook) +_GuardrailResultT = TypeVar("_GuardrailResultT") + + def _exception_changes_request_flow(exc: BaseException) -> bool: """ True for guardrail exceptions the proxy turns into an alternate request flow @@ -394,11 +398,11 @@ class _CallbackCapabilities: # Tuple[(resolved_callback, "override" | "apply_guardrail"), ...] # Ordered the same as ``litellm.callbacks``; used to build the streaming # iterator chain without re-scanning per request. - iterator_overrides: Tuple[Tuple[Any, str], ...] = field(default_factory=tuple) + iterator_overrides: Tuple[Tuple[CustomLogger, str], ...] = field(default_factory=tuple) # Resolved CustomLogger callbacks in original order. Pre-resolving once # avoids the per-request ``get_custom_logger_compatible_class`` walk for # every string entry in ``litellm.callbacks``. - resolved_callbacks: Tuple[Any, ...] = field(default_factory=tuple) + resolved_callbacks: Tuple[CustomLogger, ...] = field(default_factory=tuple) class ProxyLogging: @@ -676,7 +680,7 @@ class ProxyLogging: return synthetic_data - def _convert_llm_result_to_mcp_response(self, llm_result, request_obj) -> Optional[Any]: + def _convert_llm_result_to_mcp_response(self, llm_result, request_obj) -> MCPPreCallResponseObject | None: """ Convert LLM guardrail result back to MCP response format. """ @@ -802,7 +806,7 @@ class ProxyLogging: verbose_proxy_logger.error(f"Error in manual argument parsing: {e}") return None - def _convert_llm_result_to_mcp_during_response(self, llm_result, request_obj) -> Optional[Any]: + def _convert_llm_result_to_mcp_during_response(self, llm_result, request_obj) -> MCPDuringCallResponseObject | None: """ Convert LLM guardrail result back to MCP during call response format. """ @@ -1438,9 +1442,7 @@ class ProxyLogging: data = result elif ( - _callback is not None - and isinstance(_callback, CustomLogger) - and "async_pre_call_hook" in vars(_callback.__class__) + "async_pre_call_hook" in vars(_callback.__class__) and _callback.__class__.async_pre_call_hook != CustomLogger.async_pre_call_hook ): if call_type == "call_mcp_tool" and user_api_key_dict is None: @@ -1614,7 +1616,9 @@ class ProxyLogging: break @staticmethod - async def _run_guardrail_with_metrics(callback: Any, coro: Awaitable[Any], hook_type: str) -> Any: + async def _run_guardrail_with_metrics( + callback: CustomLogger, coro: Awaitable[_GuardrailResultT], hook_type: str + ) -> _GuardrailResultT: """ Await `coro`, recording its latency and status to the `litellm_guardrail_latency_seconds` metric under `hook_type`, and @@ -1646,7 +1650,7 @@ class ProxyLogging: @staticmethod async def _wrap_streaming_iterator_with_enrichment( - callback: Any, gen: AsyncGenerator[Any, None] + callback: CustomLogger, gen: AsyncGenerator[Any, None] ) -> AsyncGenerator[Any, None]: """ Yield from `gen`; if iteration raises an HTTPException with dict detail, @@ -1691,12 +1695,12 @@ class ProxyLogging: has_streaming_chunk_override = False has_guardrail = False has_pre_call_override = False - iterator_overrides: List[Tuple[Any, str]] = [] # (callback, kind) - resolved_callbacks: List[Any] = [] + iterator_overrides: List[Tuple[CustomLogger, str]] = [] # (callback, kind) + resolved_callbacks: List[CustomLogger] = [] for callback in callbacks: if isinstance(callback, str): - resolved: Any = litellm.litellm_core_utils.litellm_logging.get_custom_logger_compatible_class( + resolved = litellm.litellm_core_utils.litellm_logging.get_custom_logger_compatible_class( cast(_custom_logger_compatible_callbacks_literal, callback) ) else: @@ -2795,7 +2799,7 @@ _DEPRECATED_KEY_CACHE_TTL_SECONDS = 60 async def _lookup_deprecated_key( - db: Any, + db: Union[PrismaWrapper, RoutingPrismaWrapper], hashed_token: str, ) -> Optional[str]: """ @@ -2875,7 +2879,7 @@ def _unpack_config_row(cached: Any) -> Optional[_ConfigRow]: return None -async def get_config_param(prisma_client: Any, param_name: str) -> Optional[Any]: +async def get_config_param(prisma_client: "PrismaClient", param_name: str) -> Any | None: """Cached read of a LiteLLM_Config row; returns row, _ConfigRow shim, or None.""" cache_key = _config_cache_key(param_name) cached = await litellm_config_cache.async_get_cache(cache_key) @@ -2883,7 +2887,7 @@ async def get_config_param(prisma_client: Any, param_name: str) -> Optional[Any] return _unpack_config_row(cached) row = await prisma_client.get_generic_data(key="param_name", value=param_name, table_name="config") - cache_value: Any = _pack_config_row(row) if row is not None else _CONFIG_CACHE_MISS + cache_value = _pack_config_row(row) if row is not None else _CONFIG_CACHE_MISS await litellm_config_cache.async_set_cache(cache_key, cache_value, ttl=LITELLM_CONFIG_CACHE_TTL_SECONDS) return row @@ -2893,7 +2897,7 @@ async def invalidate_config_param(param_name: str) -> None: await litellm_config_cache.async_delete_cache(_config_cache_key(param_name)) -async def prefetch_config_params(prisma_client: Any, param_names: List[str]) -> None: +async def prefetch_config_params(prisma_client: "PrismaClient", param_names: List[str]) -> None: """Batch-load LiteLLM_Config rows into the cache with one find_many.""" if not param_names: return @@ -2910,7 +2914,7 @@ async def prefetch_config_params(prisma_client: Any, param_names: List[str]) -> by_name = {row.param_name: row for row in rows} for name in param_names: row = by_name.get(name) - cache_value: Any = _pack_config_row(row) if row is not None else _CONFIG_CACHE_MISS + cache_value = _pack_config_row(row) if row is not None else _CONFIG_CACHE_MISS await litellm_config_cache.async_set_cache( _config_cache_key(name), cache_value, ttl=LITELLM_CONFIG_CACHE_TTL_SECONDS ) diff --git a/ruff-strict-budget.json b/ruff-strict-budget.json index 3b5ec5b0dee..7dd5f06f4fb 100644 --- a/ruff-strict-budget.json +++ b/ruff-strict-budget.json @@ -1,6 +1,6 @@ { "ANN001": { - "limit": 3118 + "limit": 3106 }, "ANN002": { "limit": 69 @@ -24,7 +24,7 @@ "limit": 130 }, "ANN401": { - "limit": 2013 + "limit": 1821 }, "ASYNC230": { "limit": 14 @@ -222,7 +222,7 @@ "limit": 38 }, "RET504": { - "limit": 716 + "limit": 713 }, "RUF010": { "limit": 874 @@ -306,7 +306,7 @@ "limit": 9 }, "TID251": { - "limit": 2652 + "limit": 2649 }, "TRY002": { "limit": 547 @@ -324,7 +324,7 @@ "limit": 883 }, "UP006": { - "limit": 12146 + "limit": 12144 }, "UP007": { "limit": 2526 @@ -363,6 +363,6 @@ "limit": 105 }, "UP045": { - "limit": 17806 + "limit": 17788 } } diff --git a/type-discipline-budget.json b/type-discipline-budget.json index 25cc1621d54..0e9665c352d 100644 --- a/type-discipline-budget.json +++ b/type-discipline-budget.json @@ -1,6 +1,6 @@ { "LIT001": { - "limit": 23267 + "limit": 23265 }, "LIT002": { "limit": 27434