Merge pull request #23019 from BerriAI/litellm_redis_txn_buffer_check

[Fix] Block proxy startup when use_redis_transaction_buffer has no Redis
This commit is contained in:
yuneng-jiang
2026-03-06 22:01:37 -08:00
committed by GitHub
2 changed files with 73 additions and 1 deletions
+35
View File
@@ -871,6 +871,12 @@ async def proxy_startup_event(app: FastAPI): # noqa: PLR0915
redis_usage_cache=redis_usage_cache,
)
## Validate use_redis_transaction_buffer requires Redis cache ##
ProxyStartupEvent._validate_redis_transaction_buffer_config(
general_settings=general_settings,
redis_usage_cache=redis_usage_cache,
)
## SEMANTIC TOOL FILTER ##
# Read litellm_settings from config for semantic filter initialization
try:
@@ -5618,6 +5624,35 @@ class ProxyStartupEvent:
llm_router=llm_router, redis_usage_cache=redis_usage_cache
)
@staticmethod
def _validate_redis_transaction_buffer_config(
general_settings: dict,
redis_usage_cache: Optional[RedisCache],
):
"""
Validates that when use_redis_transaction_buffer is enabled,
a Redis cache is properly configured in litellm_settings.
"""
from litellm.secret_managers.main import str_to_bool
_use_redis_transaction_buffer: Optional[Union[bool, str]] = (
general_settings.get("use_redis_transaction_buffer", False)
)
if isinstance(_use_redis_transaction_buffer, str):
_use_redis_transaction_buffer = str_to_bool(_use_redis_transaction_buffer)
if _use_redis_transaction_buffer and redis_usage_cache is None:
raise ValueError(
"`use_redis_transaction_buffer` is enabled in general_settings "
"but no Redis cache is configured. This will cause spend updates "
"to not be tracked. Add a Redis cache in litellm_settings:\n\n"
"litellm_settings:\n"
" cache: true\n"
" cache_params:\n"
" type: redis\n"
" url: os.environ/REDIS_URL\n"
)
@classmethod
async def _initialize_semantic_tool_filter(
cls,
@@ -1,7 +1,7 @@
import json
import os
import sys
from unittest.mock import AsyncMock, MagicMock, patch
from unittest.mock import AsyncMock, MagicMock
import pytest
@@ -10,6 +10,7 @@ sys.path.insert(
) # Adds the parent directory to the system path
from litellm.proxy.db.db_transaction_queue.redis_update_buffer import RedisUpdateBuffer
from litellm.proxy.proxy_server import ProxyStartupEvent
from litellm.types.caching import RedisPipelineRpushOperation
@@ -192,3 +193,39 @@ async def test_get_all_transactions_from_redis_buffer_pipeline_no_redis():
buffer = RedisUpdateBuffer(redis_cache=None)
result = await buffer.get_all_transactions_from_redis_buffer_pipeline()
assert result == (None, None, None, None, None, None, None)
def test_validate_redis_transaction_buffer_raises_without_redis():
"""
When use_redis_transaction_buffer=true but no Redis cache is configured,
the proxy should refuse to start with a clear error message.
"""
with pytest.raises(ValueError, match="use_redis_transaction_buffer"):
ProxyStartupEvent._validate_redis_transaction_buffer_config(
general_settings={"use_redis_transaction_buffer": True},
redis_usage_cache=None,
)
def test_validate_redis_transaction_buffer_passes_with_redis():
"""
When use_redis_transaction_buffer=true and Redis cache is configured,
validation should pass without error.
"""
# Should not raise
ProxyStartupEvent._validate_redis_transaction_buffer_config(
general_settings={"use_redis_transaction_buffer": True},
redis_usage_cache=MagicMock(),
)
def test_validate_redis_transaction_buffer_passes_when_disabled():
"""
When use_redis_transaction_buffer is not set or false,
validation should pass regardless of Redis configuration.
"""
# Should not raise even without Redis
ProxyStartupEvent._validate_redis_transaction_buffer_config(
general_settings={},
redis_usage_cache=None,
)