From 95248d4d27ba2d74ed021a2973884919cc913d44 Mon Sep 17 00:00:00 2001 From: Harshit Jain <48647625+Harshit28j@users.noreply.github.com> Date: Wed, 11 Feb 2026 13:00:24 +0000 Subject: [PATCH] fixes deprecated functions --- ci_cd/security_scans.sh | 2 ++ docker/Dockerfile.non_root | 17 ++++++++++++++--- docker/install_auto_router.sh | 10 ++++++++-- litellm/integrations/custom_guardrail.py | 3 ++- litellm/litellm_core_utils/logging_utils.py | 3 ++- litellm/litellm_core_utils/redact_messages.py | 3 ++- litellm/proxy/common_utils/performance_utils.py | 3 ++- .../key_management_endpoints.py | 5 +++-- litellm/proxy/management_endpoints/ui_sso.py | 3 ++- requirements.txt | 4 ++-- 10 files changed, 39 insertions(+), 14 deletions(-) diff --git a/ci_cd/security_scans.sh b/ci_cd/security_scans.sh index c75e594c25b..da41f35955a 100755 --- a/ci_cd/security_scans.sh +++ b/ci_cd/security_scans.sh @@ -158,6 +158,8 @@ run_grype_scans() { "CVE-2025-11468" # No fix available yet "CVE-2026-1299" # Python email module header injection - not applicable, LiteLLM doesn't use BytesGenerator for email serialization "CVE-2026-0775" # npm cli incorrect permission assignment - no fix available yet, npm is only used at build/prisma-generate time + "GHSA-h395-gr6q-cpjc" # jsonwebtoken <=9.3.1 - pulled in by prisma/node tooling, not used in application runtime + "GHSA-r6v5-fh4h-64xc" # time crate 0.3.44 - transitive Rust dependency, fix available in 0.3.47 but awaiting upstream update ) # Build JSON array of allowlisted CVE IDs for jq diff --git a/docker/Dockerfile.non_root b/docker/Dockerfile.non_root index b6ca23c5715..2a54db1f0fe 100644 --- a/docker/Dockerfile.non_root +++ b/docker/Dockerfile.non_root @@ -47,7 +47,13 @@ COPY requirements.txt . RUN pip install --no-cache-dir hatchling hatch-vcs RUN pip wheel --no-cache-dir --wheel-dir=/wheels/ --only-binary=Pillow,tokenizers -r requirements.txt \ - && pip wheel --no-cache-dir --wheel-dir=/wheels/ "semantic_router==0.1.11" "aurelio-sdk==0.0.19" "PyJWT==2.9.0" + && PYTHON_MINOR=$(python3 -c "import sys; print(sys.version_info.minor)") \ + && if [ "$PYTHON_MINOR" -lt 14 ]; then \ + pip wheel --no-cache-dir --wheel-dir=/wheels/ "semantic_router==0.1.11" "aurelio-sdk==0.0.19"; \ + else \ + echo "Skipping semantic_router/aurelio-sdk: not supported on Python 3.14+"; \ + fi \ + && pip wheel --no-cache-dir --wheel-dir=/wheels/ "PyJWT==2.9.0" # Copy source after dependency layers COPY . . @@ -163,8 +169,13 @@ ENV PRISMA_BINARY_CACHE_DIR=/app/.cache/prisma-python/binaries \ # Install packages from wheels and optional extras without network RUN pip install --no-index --find-links=/wheels/ -r requirements.txt && \ pip install --no-index --find-links=/wheels/ /wheels/litellm-*-py3-none-any.whl && \ - pip install --no-index --find-links=/wheels/ --no-deps semantic_router==0.1.11 && \ - pip install --no-index --find-links=/wheels/ aurelio-sdk==0.0.19 && \ + PYTHON_MINOR=$(python3 -c "import sys; print(sys.version_info.minor)") && \ + if [ "$PYTHON_MINOR" -lt 14 ]; then \ + pip install --no-index --find-links=/wheels/ --no-deps semantic_router==0.1.11; \ + pip install --no-index --find-links=/wheels/ aurelio-sdk==0.0.19; \ + else \ + echo "Skipping semantic_router/aurelio-sdk: not supported on Python 3.14+"; \ + fi && \ if [ "$PROXY_EXTRAS_SOURCE" = "local" ]; then \ if ls /wheels/litellm_proxy_extras-*.whl >/dev/null 2>&1; then \ pip install --no-index --find-links=/wheels/ /wheels/litellm_proxy_extras-*.whl; \ diff --git a/docker/install_auto_router.sh b/docker/install_auto_router.sh index 794f9a2bbce..25825206715 100755 --- a/docker/install_auto_router.sh +++ b/docker/install_auto_router.sh @@ -1,3 +1,9 @@ #!/bin/bash -pip install semantic_router==0.1.11 --no-deps -pip install aurelio-sdk==0.0.19 \ No newline at end of file +# semantic_router does not support Python 3.14+ (requires_python: >=3.9,<3.14) +PYTHON_MINOR=$(python3 -c "import sys; print(sys.version_info.minor)") +if [ "$PYTHON_MINOR" -lt 14 ]; then + pip install semantic_router==0.1.11 --no-deps + pip install aurelio-sdk==0.0.19 +else + echo "Skipping semantic_router and aurelio-sdk: not supported on Python 3.14+" +fi \ No newline at end of file diff --git a/litellm/integrations/custom_guardrail.py b/litellm/integrations/custom_guardrail.py index 407bc581f71..7e9d3809ceb 100644 --- a/litellm/integrations/custom_guardrail.py +++ b/litellm/integrations/custom_guardrail.py @@ -1,3 +1,4 @@ +import inspect from datetime import datetime from typing import ( TYPE_CHECKING, @@ -863,7 +864,7 @@ def log_guardrail_information(func): @functools.wraps(func) def wrapper(*args, **kwargs): - if asyncio.iscoroutinefunction(func): + if inspect.iscoroutinefunction(func): return async_wrapper(*args, **kwargs) return sync_wrapper(*args, **kwargs) diff --git a/litellm/litellm_core_utils/logging_utils.py b/litellm/litellm_core_utils/logging_utils.py index bf43519afc6..8cde8ccef1c 100644 --- a/litellm/litellm_core_utils/logging_utils.py +++ b/litellm/litellm_core_utils/logging_utils.py @@ -1,5 +1,6 @@ import asyncio import functools +import inspect import time from datetime import datetime from typing import TYPE_CHECKING, Any, List, Optional, Union @@ -270,7 +271,7 @@ def track_llm_api_timing(): verbose_logger.debug(f"Error in service logging: {str(e)}") # Check if the function is async or sync - if asyncio.iscoroutinefunction(func): + if inspect.iscoroutinefunction(func): return async_wrapper return sync_wrapper diff --git a/litellm/litellm_core_utils/redact_messages.py b/litellm/litellm_core_utils/redact_messages.py index aa763dc9899..38ef9b7b5c1 100644 --- a/litellm/litellm_core_utils/redact_messages.py +++ b/litellm/litellm_core_utils/redact_messages.py @@ -9,6 +9,7 @@ import asyncio import copy +import inspect from typing import TYPE_CHECKING, Any, Optional import litellm @@ -102,7 +103,7 @@ def perform_redaction(model_call_details: dict, result): if result is not None: # Check if result is a coroutine, async generator, or other async object - these cannot be deepcopied if (asyncio.iscoroutine(result) or - asyncio.iscoroutinefunction(result) or + inspect.iscoroutinefunction(result) or hasattr(result, '__aiter__') or # async generator hasattr(result, '__anext__')): # async iterator # For async objects, return a simple redacted response without deepcopy diff --git a/litellm/proxy/common_utils/performance_utils.py b/litellm/proxy/common_utils/performance_utils.py index f9537f85e2b..ec36f865cf1 100644 --- a/litellm/proxy/common_utils/performance_utils.py +++ b/litellm/proxy/common_utils/performance_utils.py @@ -12,6 +12,7 @@ import asyncio import atexit import cProfile import functools +import inspect import threading from pathlib import Path as PathLib from typing import Any, Callable, Optional @@ -100,7 +101,7 @@ def profile_endpoint(sampling_rate: float = 1.0): global _last_profile_file_path _last_profile_file_path = path - if asyncio.iscoroutinefunction(func): + if inspect.iscoroutinefunction(func): @functools.wraps(func) async def async_wrapper(*args, **kwargs): is_sampling = _start_profiling_for_request(sampling_rate) diff --git a/litellm/proxy/management_endpoints/key_management_endpoints.py b/litellm/proxy/management_endpoints/key_management_endpoints.py index 2e71759072d..002ecd4716b 100644 --- a/litellm/proxy/management_endpoints/key_management_endpoints.py +++ b/litellm/proxy/management_endpoints/key_management_endpoints.py @@ -11,6 +11,7 @@ All /key management endpoints import asyncio import copy +import inspect import json import secrets import traceback @@ -1096,7 +1097,7 @@ async def generate_key_fn( ) if user_custom_key_generate is not None: - if asyncio.iscoroutinefunction(user_custom_key_generate): + if inspect.iscoroutinefunction(user_custom_key_generate): result = await user_custom_key_generate(data) # type: ignore else: raise ValueError("user_custom_key_generate must be a coroutine") @@ -1248,7 +1249,7 @@ async def generate_service_account_key_fn( verbose_proxy_logger.debug("entered /key/generate") if user_custom_key_generate is not None: - if asyncio.iscoroutinefunction(user_custom_key_generate): + if inspect.iscoroutinefunction(user_custom_key_generate): result = await user_custom_key_generate(data) # type: ignore else: raise ValueError("user_custom_key_generate must be a coroutine") diff --git a/litellm/proxy/management_endpoints/ui_sso.py b/litellm/proxy/management_endpoints/ui_sso.py index 7274b389a92..7b21694a6a4 100644 --- a/litellm/proxy/management_endpoints/ui_sso.py +++ b/litellm/proxy/management_endpoints/ui_sso.py @@ -11,6 +11,7 @@ Has all /sso/* routes import asyncio import base64 import hashlib +import inspect import os import secrets from copy import deepcopy @@ -2236,7 +2237,7 @@ class SSOAuthenticationHandler: user_defined_values: Optional[SSOUserDefinedValues] = None if user_custom_sso is not None: - if asyncio.iscoroutinefunction(user_custom_sso): + if inspect.iscoroutinefunction(user_custom_sso): user_defined_values = await user_custom_sso(result) # type: ignore else: raise ValueError("user_custom_sso must be a coroutine function") diff --git a/requirements.txt b/requirements.txt index c36e2e7bc25..ae5033703f4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,8 +22,8 @@ prisma==0.11.0 # for db nodejs-wheel-binaries==24.12.0 ## required by prisma for migrations, prevents runtime download (updated from nodejs-bin for security fixes) mangum==0.17.0 # for aws lambda functions pynacl==1.6.2 # for encrypting keys -# google-cloud-aiplatform==1.133.0 # for vertex ai calls - disabled for Python 3.14 (pip resolver "resolution-too-deep" error) -# google-cloud-iam==2.19.1 # for GCP IAM Redis authentication - disabled for Python 3.14 (pip resolver "resolution-too-deep" error) +google-cloud-aiplatform==1.133.0 ; python_version < "3.14" # for vertex ai calls (no Python 3.14 support yet) +google-cloud-iam==2.19.1 ; python_version < "3.14" # for GCP IAM Redis authentication (no Python 3.14 support yet) google-genai==1.37.0 anthropic[vertex]==0.54.0 mcp==1.25.0 ; python_version >= "3.10" # for MCP server