mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-11 22:51:28 +00:00
fix: address review feedback - local variable for getattr, sync path embed_api_base, test production code
- Store getattr result in inner_cache local variable (caching_handler.py) - Apply embed_api_base fix to sync set_cache and get_cache (qdrant_semantic_cache.py) - Rewrite test to call LLMCachingHandler.__init__() directly instead of replaying getattr
This commit is contained in:
parent
12bd05990e
commit
fb7cf50148
3 changed files with 31 additions and 63 deletions
|
|
@ -98,9 +98,10 @@ class LLMCachingHandler:
|
|||
self.request_kwargs = request_kwargs
|
||||
self.original_function = original_function
|
||||
self.start_time = start_time
|
||||
if litellm.cache is not None and isinstance(getattr(litellm.cache, "cache", None), RedisCache):
|
||||
inner_cache = getattr(litellm.cache, "cache", None)
|
||||
if litellm.cache is not None and isinstance(inner_cache, RedisCache):
|
||||
self.dual_cache: Optional[DualCache] = DualCache(
|
||||
redis_cache=getattr(litellm.cache, "cache", None),
|
||||
redis_cache=inner_cache,
|
||||
in_memory_cache=in_memory_cache_obj,
|
||||
)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -183,13 +183,16 @@ class QdrantSemanticCache(BaseCache):
|
|||
prompt += message["content"]
|
||||
|
||||
# create an embedding for prompt
|
||||
embedding_kwargs: dict[str, Any] = {
|
||||
"model": self.embedding_model,
|
||||
"input": prompt,
|
||||
"cache": {"no-store": True, "no-cache": True},
|
||||
}
|
||||
if getattr(self, "embed_api_base", None) is not None:
|
||||
embedding_kwargs["api_base"] = self.embed_api_base
|
||||
embedding_response = cast(
|
||||
EmbeddingResponse,
|
||||
litellm.embedding(
|
||||
model=self.embedding_model,
|
||||
input=prompt,
|
||||
cache={"no-store": True, "no-cache": True},
|
||||
),
|
||||
litellm.embedding(**embedding_kwargs),
|
||||
)
|
||||
|
||||
# get the embedding
|
||||
|
|
@ -227,13 +230,16 @@ class QdrantSemanticCache(BaseCache):
|
|||
prompt += message["content"]
|
||||
|
||||
# convert to embedding
|
||||
embedding_kwargs: dict[str, Any] = {
|
||||
"model": self.embedding_model,
|
||||
"input": prompt,
|
||||
"cache": {"no-store": True, "no-cache": True},
|
||||
}
|
||||
if getattr(self, "embed_api_base", None) is not None:
|
||||
embedding_kwargs["api_base"] = self.embed_api_base
|
||||
embedding_response = cast(
|
||||
EmbeddingResponse,
|
||||
litellm.embedding(
|
||||
model=self.embedding_model,
|
||||
input=prompt,
|
||||
cache={"no-store": True, "no-cache": True},
|
||||
),
|
||||
litellm.embedding(**embedding_kwargs),
|
||||
)
|
||||
|
||||
# get the embedding
|
||||
|
|
|
|||
|
|
@ -9,57 +9,15 @@ sys.path.insert(
|
|||
) # Adds the parent directory to the system path
|
||||
|
||||
|
||||
def test_proxy_init_cache_does_not_crash_on_non_redis_cache():
|
||||
def test_caching_handler_init_does_not_crash_on_non_redis_cache():
|
||||
"""
|
||||
Test that proxy cache initialization does not crash for non-Redis backends.
|
||||
Verifies that accessing litellm.cache.cache via getattr prevents AttributeError
|
||||
when the cache type is qdrant-semantic.
|
||||
Test that LLMCachingHandler.__init__ does not crash for non-Redis backends.
|
||||
Verifies that the production code path handles Qdrant semantic cache without
|
||||
raising AttributeError on litellm.cache.cache.
|
||||
"""
|
||||
import litellm
|
||||
from litellm.caching.caching import Cache
|
||||
|
||||
with patch("litellm.llms.custom_httpx.http_handler._get_httpx_client") as mock_sync_client, \
|
||||
patch("litellm.llms.custom_httpx.http_handler.get_async_httpx_client"):
|
||||
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {"result": {"exists": True}}
|
||||
|
||||
mock_sync_client_instance = MagicMock()
|
||||
mock_sync_client_instance.get.return_value = mock_response
|
||||
mock_sync_client.return_value = mock_sync_client_instance
|
||||
|
||||
# Create a qdrant-semantic cache (has no inner .cache attribute like Redis does)
|
||||
cache = Cache(
|
||||
type="qdrant-semantic",
|
||||
qdrant_api_base="http://test.qdrant.local",
|
||||
qdrant_api_key="test_key",
|
||||
qdrant_collection_name="test_collection",
|
||||
similarity_threshold=0.8,
|
||||
)
|
||||
litellm.cache = cache
|
||||
|
||||
# This should not raise AttributeError
|
||||
from litellm.caching.redis_cache import RedisCache
|
||||
from litellm.caching.redis_cluster_cache import RedisClusterCache
|
||||
|
||||
inner = getattr(litellm.cache, "cache", None)
|
||||
result = isinstance(inner, (RedisCache, RedisClusterCache))
|
||||
assert result is False
|
||||
|
||||
# Cleanup
|
||||
litellm.cache = None
|
||||
|
||||
|
||||
def test_caching_handler_does_not_crash_on_non_redis_cache():
|
||||
"""
|
||||
Test that CachingHandlerResponse isinstance checks do not crash for non-Redis backends.
|
||||
Verifies that getattr prevents AttributeError when cache type is qdrant-semantic.
|
||||
"""
|
||||
import litellm
|
||||
from litellm.caching.caching import Cache
|
||||
from litellm.caching.redis_cache import RedisCache
|
||||
from litellm.caching.s3_cache import S3Cache
|
||||
from litellm.caching.caching_handler import LLMCachingHandler
|
||||
|
||||
with patch("litellm.llms.custom_httpx.http_handler._get_httpx_client") as mock_sync_client, \
|
||||
patch("litellm.llms.custom_httpx.http_handler.get_async_httpx_client"):
|
||||
|
|
@ -81,10 +39,13 @@ def test_caching_handler_does_not_crash_on_non_redis_cache():
|
|||
)
|
||||
litellm.cache = cache
|
||||
|
||||
# These isinstance checks should not raise AttributeError
|
||||
inner = getattr(litellm.cache, "cache", None)
|
||||
assert not isinstance(inner, RedisCache)
|
||||
assert not isinstance(inner, S3Cache)
|
||||
# This should not raise AttributeError — exercises the actual production code
|
||||
handler = LLMCachingHandler(
|
||||
original_function=MagicMock(),
|
||||
request_kwargs={"messages": [{"content": "test"}]},
|
||||
start_time=None,
|
||||
)
|
||||
assert handler.dual_cache is None
|
||||
|
||||
# Cleanup
|
||||
litellm.cache = None
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue