Skip to content

Commit 5d02f58

Browse files
Copilotabrookins
andcommitted
Ignore empty attributes in delete_by_attributes instead of raising error
- Changed delete_by_attributes() to return {} when attributes is empty - Changed adelete_by_attributes() to return {} when attributes is empty - Updated tests to verify empty attributes are ignored without calling API - This prevents accidentally calling API with empty dict which would cause 400 error Co-authored-by: abrookins <[email protected]>
1 parent 8d2549e commit 5d02f58

File tree

2 files changed

+24
-26
lines changed

2 files changed

+24
-26
lines changed

redisvl/extensions/cache/llm/langcache.py

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -582,20 +582,14 @@ def delete_by_attributes(self, attributes: Dict[str, Any]) -> Dict[str, Any]:
582582
583583
Args:
584584
attributes (Dict[str, Any]): Attributes to match for deletion.
585-
Cannot be empty.
585+
If empty, no deletion is performed.
586586
587587
Returns:
588588
Dict[str, Any]: Result of the deletion operation.
589-
590-
Raises:
591-
ValueError: If attributes is empty.
592589
"""
593590
if not attributes:
594-
raise ValueError(
595-
"attributes cannot be empty. Provide specific attributes to match, "
596-
"use delete() or clear() to delete all entries, "
597-
"or use delete_by_id(entry_id) to delete individual entries."
598-
)
591+
# No attributes provided, return empty result without calling API
592+
return {}
599593
result = self._client.delete_query(attributes=attributes)
600594
# Convert DeleteQueryResponse to dict
601595
return result.model_dump() if hasattr(result, "model_dump") else {}
@@ -605,20 +599,14 @@ async def adelete_by_attributes(self, attributes: Dict[str, Any]) -> Dict[str, A
605599
606600
Args:
607601
attributes (Dict[str, Any]): Attributes to match for deletion.
608-
Cannot be empty.
602+
If empty, no deletion is performed.
609603
610604
Returns:
611605
Dict[str, Any]: Result of the deletion operation.
612-
613-
Raises:
614-
ValueError: If attributes is empty.
615606
"""
616607
if not attributes:
617-
raise ValueError(
618-
"attributes cannot be empty. Provide specific attributes to match, "
619-
"use adelete() or aclear() to delete all entries, "
620-
"or use adelete_by_id(entry_id) to delete individual entries."
621-
)
608+
# No attributes provided, return empty result without calling API
609+
return {}
622610
result = await self._client.delete_query_async(attributes=attributes)
623611
# Convert DeleteQueryResponse to dict
624612
return result.model_dump() if hasattr(result, "model_dump") else {}

tests/unit/test_langcache_semantic_cache.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -455,19 +455,24 @@ def test_delete_by_attributes_with_valid_attributes(self, mock_langcache_client)
455455
assert result == {"deleted_count": 5}
456456
mock_client.delete_query.assert_called_once_with(attributes={"topic": "python"})
457457

458-
def test_delete_by_attributes_with_empty_attributes_raises_error(
458+
def test_delete_by_attributes_with_empty_attributes_returns_empty(
459459
self, mock_langcache_client
460460
):
461-
"""Test that delete_by_attributes raises ValueError with empty attributes."""
461+
"""Test that delete_by_attributes returns empty dict with empty attributes."""
462+
_, mock_client = mock_langcache_client
463+
462464
cache = LangCacheSemanticCache(
463465
name="test",
464466
server_url="https://api.example.com",
465467
cache_id="test-cache",
466468
api_key="test-key",
467469
)
468470

469-
with pytest.raises(ValueError, match="attributes cannot be empty"):
470-
cache.delete_by_attributes({})
471+
result = cache.delete_by_attributes({})
472+
473+
# Should return empty dict without calling delete_query
474+
assert result == {}
475+
mock_client.delete_query.assert_not_called()
471476

472477
@pytest.mark.asyncio
473478
async def test_adelete_by_attributes_with_valid_attributes(
@@ -495,19 +500,24 @@ async def test_adelete_by_attributes_with_valid_attributes(
495500
)
496501

497502
@pytest.mark.asyncio
498-
async def test_adelete_by_attributes_with_empty_attributes_raises_error(
503+
async def test_adelete_by_attributes_with_empty_attributes_returns_empty(
499504
self, mock_langcache_client
500505
):
501-
"""Test that async delete_by_attributes raises ValueError with empty attributes."""
506+
"""Test that async delete_by_attributes returns empty dict with empty attributes."""
507+
_, mock_client = mock_langcache_client
508+
502509
cache = LangCacheSemanticCache(
503510
name="test",
504511
server_url="https://api.example.com",
505512
cache_id="test-cache",
506513
api_key="test-key",
507514
)
508515

509-
with pytest.raises(ValueError, match="attributes cannot be empty"):
510-
await cache.adelete_by_attributes({})
516+
result = await cache.adelete_by_attributes({})
517+
518+
# Should return empty dict without calling delete_query_async
519+
assert result == {}
520+
mock_client.delete_query_async.assert_not_called()
511521

512522
def test_update_not_supported(self, mock_langcache_client):
513523
"""Test that update raises NotImplementedError."""

0 commit comments

Comments
 (0)