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
55from 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