chore(proxy): ignore invalid callback metadata rows

This commit is contained in:
user
2026-04-29 20:05:35 -07:00
parent 4d056a1f01
commit 22c01adeb2
4 changed files with 58 additions and 21 deletions
+2 -4
View File
@@ -1871,11 +1871,9 @@ class AddTeamCallback(LiteLLMPydanticObjectBase):
raise ValueError(
f"Invalid callback variable: {key}. Must be one of {valid_keys}"
)
if not isinstance(value, str):
callback_vars[key] = str(value)
value = callback_vars[key]
callback_vars[key] = str(value)
validate_no_callback_env_reference(
key, value, source="key/team callback metadata"
key, callback_vars[key], source="key/team callback metadata"
)
return values
+22 -2
View File
@@ -233,6 +233,20 @@ def convert_key_logging_metadata_to_callback(
return team_callback_settings_obj
def _get_validated_callback_metadata(
item: dict, *, source: str
) -> Optional[AddTeamCallback]:
try:
return AddTeamCallback(**item)
except ValueError as e:
verbose_proxy_logger.warning(
"Ignoring invalid %s callback metadata: %s",
source,
_sanitize_for_log(str(e)),
)
return None
class KeyAndTeamLoggingSettings:
"""
Helper class to get the dynamic logging settings for the key and team
@@ -272,8 +286,11 @@ def _get_dynamic_logging_metadata(
#########################################################################################
if key_dynamic_logging_settings is not None:
for item in key_dynamic_logging_settings:
callback = _get_validated_callback_metadata(item=item, source="key-level")
if callback is None:
continue
callback_settings_obj = convert_key_logging_metadata_to_callback(
data=AddTeamCallback(**item),
data=callback,
team_callback_settings_obj=callback_settings_obj,
)
#########################################################################################
@@ -281,8 +298,11 @@ def _get_dynamic_logging_metadata(
#########################################################################################
elif team_dynamic_logging_settings is not None:
for item in team_dynamic_logging_settings:
callback = _get_validated_callback_metadata(item=item, source="team-level")
if callback is None:
continue
callback_settings_obj = convert_key_logging_metadata_to_callback(
data=AddTeamCallback(**item),
data=callback,
team_callback_settings_obj=callback_settings_obj,
)
#########################################################################################
+10 -7
View File
@@ -309,10 +309,15 @@ def test_dynamic_logging_metadata_key_and_team_metadata(callback_vars):
assert "os.environ" not in var
def test_dynamic_logging_metadata_rejects_env_references_from_key_metadata(
def test_dynamic_logging_metadata_ignores_env_references_from_key_metadata(
monkeypatch,
):
monkeypatch.setenv("LANGFUSE_SECRET_KEY_TEMP", "server-side-secret")
monkeypatch.setattr(
litellm.utils,
"get_secret",
lambda *args, **kwargs: pytest.fail("get_secret should not be called"),
)
from litellm.proxy.proxy_server import ProxyConfig
proxy_config = ProxyConfig()
@@ -332,13 +337,11 @@ def test_dynamic_logging_metadata_rejects_env_references_from_key_metadata(
team_metadata={},
)
with pytest.raises(ValueError) as exc_info:
_get_dynamic_logging_metadata(
user_api_key_dict=user_api_key_dict, proxy_config=proxy_config
)
callbacks = _get_dynamic_logging_metadata(
user_api_key_dict=user_api_key_dict, proxy_config=proxy_config
)
assert "os.environ/" in str(exc_info.value)
assert "server-side-secret" not in str(exc_info.value)
assert callbacks is None
@pytest.mark.parametrize(
@@ -10,7 +10,7 @@ from fastapi import Request
from starlette.datastructures import Headers
import litellm
from litellm.proxy._types import TeamCallbackMetadata, UserAPIKeyAuth
from litellm.proxy._types import AddTeamCallback, TeamCallbackMetadata, UserAPIKeyAuth
from litellm.proxy.litellm_pre_call_utils import (
KeyAndTeamLoggingSettings,
LiteLLMProxyRequestSetup,
@@ -1274,10 +1274,28 @@ def test_get_dynamic_logging_metadata_with_arize_team_logging():
assert result.callback_vars["arize_space_id"] == "test_arize_space_id"
def test_get_dynamic_logging_metadata_rejects_env_reference_from_key_metadata(
def test_add_team_callback_rejects_env_reference():
with pytest.raises(ValueError) as exc_info:
AddTeamCallback(
callback_name="langfuse",
callback_type="success",
callback_vars={
"langfuse_secret_key": "os.environ/LANGFUSE_SECRET_KEY_TEMP"
},
)
assert "os.environ/" in str(exc_info.value)
def test_get_dynamic_logging_metadata_ignores_env_reference_from_key_metadata(
monkeypatch,
):
monkeypatch.setenv("LANGFUSE_SECRET_KEY_TEMP", "server-side-secret")
monkeypatch.setattr(
litellm.utils,
"get_secret",
lambda *args, **kwargs: pytest.fail("get_secret should not be called"),
)
user_api_key_dict = UserAPIKeyAuth(
api_key="test-key",
metadata={
@@ -1294,13 +1312,11 @@ def test_get_dynamic_logging_metadata_rejects_env_reference_from_key_metadata(
team_metadata={},
)
with pytest.raises(ValueError) as exc_info:
_get_dynamic_logging_metadata(
user_api_key_dict=user_api_key_dict, proxy_config=MagicMock()
)
result = _get_dynamic_logging_metadata(
user_api_key_dict=user_api_key_dict, proxy_config=MagicMock()
)
assert "os.environ/" in str(exc_info.value)
assert "server-side-secret" not in str(exc_info.value)
assert result is None
def test_get_num_retries_from_request():