Skip to content

Commit 026f4d9

Browse files
update embeddings cache with methods by_key
1 parent a8257ba commit 026f4d9

File tree

1 file changed

+133
-18
lines changed

1 file changed

+133
-18
lines changed

redisvl/extensions/cache/embeddings/embeddings.py

Lines changed: 133 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Embeddings cache implementation for RedisVL."""
22

3-
from typing import Any, Dict, List, Mapping, Optional, Tuple, Union
3+
from typing import Any, Dict, List, Optional, Tuple
44

55
from redis import Redis
66

@@ -103,6 +103,23 @@ def _prepare_entry_data(
103103
)
104104
return key, entry.to_dict()
105105

106+
def _process_cache_data(
107+
self, data: Optional[Dict[str, Any]]
108+
) -> Optional[Dict[str, Any]]:
109+
"""Process Redis hash data into a cache entry response.
110+
111+
Args:
112+
data (Optional[Dict[str, Any]]): Raw Redis hash data.
113+
114+
Returns:
115+
Optional[Dict[str, Any]]: Processed cache entry or None if no data.
116+
"""
117+
if not data:
118+
return None
119+
120+
cache_hit = CacheEntry(**data)
121+
return cache_hit.model_dump(exclude_none=True)
122+
106123
def get(
107124
self,
108125
text: str,
@@ -127,17 +144,35 @@ def get(
127144
model_name="text-embedding-ada-002"
128145
)
129146
"""
130-
client = self._get_redis_client()
131147
key = self._make_cache_key(text, model_name)
148+
return self.get_by_key(key)
149+
150+
def get_by_key(self, key: str) -> Optional[Dict[str, Any]]:
151+
"""Get embedding by its full Redis key.
152+
153+
Retrieves a cached embedding for the given Redis key.
154+
If found, refreshes the TTL of the entry.
155+
156+
Args:
157+
key (str): The full Redis key for the embedding.
158+
159+
Returns:
160+
Optional[Dict[str, Any]]: Embedding cache entry or None if not found.
161+
162+
.. code-block:: python
163+
164+
embedding_data = cache.get_by_key("embedcache:1234567890abcdef")
165+
"""
166+
client = self._get_redis_client()
132167

133168
# Get all fields
134-
if data := client.hgetall(key):
135-
# Refresh TTL
169+
data = client.hgetall(key)
170+
171+
# Refresh TTL if data exists
172+
if data:
136173
self.expire(key)
137-
cache_hit = CacheEntry(**data)
138-
response = cache_hit.model_dump(exclude_none=True)
139-
return response
140-
return None
174+
175+
return self._process_cache_data(data)
141176

142177
async def aget(
143178
self,
@@ -163,16 +198,35 @@ async def aget(
163198
model_name="text-embedding-ada-002"
164199
)
165200
"""
166-
client = await self._get_async_redis_client()
167201
key = self._make_cache_key(text, model_name)
202+
return await self.aget_by_key(key)
203+
204+
async def aget_by_key(self, key: str) -> Optional[Dict[str, Any]]:
205+
"""Async get embedding by its full Redis key.
206+
207+
Asynchronously retrieves a cached embedding for the given Redis key.
208+
If found, refreshes the TTL of the entry.
209+
210+
Args:
211+
key (str): The full Redis key for the embedding.
212+
213+
Returns:
214+
Optional[Dict[str, Any]]: Embedding cache entry or None if not found.
168215
169-
if data := await client.hgetall(key):
170-
# Refresh TTL
216+
.. code-block:: python
217+
218+
embedding_data = await cache.aget_by_key("embedcache:1234567890abcdef")
219+
"""
220+
client = await self._get_async_redis_client()
221+
222+
# Get all fields
223+
data = await client.hgetall(key)
224+
225+
# Refresh TTL if data exists
226+
if data:
171227
await self.aexpire(key)
172-
cache_hit = CacheEntry(**data)
173-
response = cache_hit.model_dump(exclude_none=True)
174-
return response
175-
return None
228+
229+
return self._process_cache_data(data)
176230

177231
def exists(self, text: str, model_name: str) -> bool:
178232
"""Check if an embedding exists for the given text and model.
@@ -193,6 +247,23 @@ def exists(self, text: str, model_name: str) -> bool:
193247
key = self._make_cache_key(text, model_name)
194248
return bool(client.exists(key))
195249

250+
def exists_by_key(self, key: str) -> bool:
251+
"""Check if an embedding exists for the given Redis key.
252+
253+
Args:
254+
key (str): The full Redis key for the embedding.
255+
256+
Returns:
257+
bool: True if the embedding exists in the cache, False otherwise.
258+
259+
.. code-block:: python
260+
261+
if cache.exists_by_key("embedcache:1234567890abcdef"):
262+
print("Embedding is in cache")
263+
"""
264+
client = self._get_redis_client()
265+
return bool(client.exists(key))
266+
196267
async def aexists(self, text: str, model_name: str) -> bool:
197268
"""Async check if an embedding exists.
198269
@@ -210,8 +281,26 @@ async def aexists(self, text: str, model_name: str) -> bool:
210281
if await cache.aexists("What is machine learning?", "text-embedding-ada-002"):
211282
print("Embedding is in cache")
212283
"""
213-
client = await self._get_async_redis_client()
214284
key = self._make_cache_key(text, model_name)
285+
return await self.aexists_by_key(key)
286+
287+
async def aexists_by_key(self, key: str) -> bool:
288+
"""Async check if an embedding exists for the given Redis key.
289+
290+
Asynchronously checks if an embedding exists for the given Redis key.
291+
292+
Args:
293+
key (str): The full Redis key for the embedding.
294+
295+
Returns:
296+
bool: True if the embedding exists in the cache, False otherwise.
297+
298+
.. code-block:: python
299+
300+
if await cache.aexists_by_key("embedcache:1234567890abcdef"):
301+
print("Embedding is in cache")
302+
"""
303+
client = await self._get_async_redis_client()
215304
return bool(await client.exists(key))
216305

217306
def set(
@@ -316,8 +405,20 @@ def drop(self, text: str, model_name: str) -> None:
316405
model_name="text-embedding-ada-002"
317406
)
318407
"""
319-
client = self._get_redis_client()
320408
key = self._make_cache_key(text, model_name)
409+
self.drop_by_key(key)
410+
411+
def drop_by_key(self, key: str) -> None:
412+
"""Remove an embedding from the cache by its Redis key.
413+
414+
Args:
415+
key (str): The full Redis key for the embedding.
416+
417+
.. code-block:: python
418+
419+
cache.drop_by_key("embedcache:1234567890abcdef")
420+
"""
421+
client = self._get_redis_client()
321422
client.delete(key)
322423

323424
async def adrop(self, text: str, model_name: str) -> None:
@@ -336,6 +437,20 @@ async def adrop(self, text: str, model_name: str) -> None:
336437
model_name="text-embedding-ada-002"
337438
)
338439
"""
339-
client = await self._get_async_redis_client()
340440
key = self._make_cache_key(text, model_name)
441+
await self.adrop_by_key(key)
442+
443+
async def adrop_by_key(self, key: str) -> None:
444+
"""Async remove an embedding from the cache by its Redis key.
445+
446+
Asynchronously removes an embedding from the cache by its Redis key.
447+
448+
Args:
449+
key (str): The full Redis key for the embedding.
450+
451+
.. code-block:: python
452+
453+
await cache.adrop_by_key("embedcache:1234567890abcdef")
454+
"""
455+
client = await self._get_async_redis_client()
341456
await client.delete(key)

0 commit comments

Comments
 (0)