Skip to content

Commit 627121d

Browse files
committed
Use a slightly less ugly lazy import
1 parent 524e8f6 commit 627121d

File tree

3 files changed

+37
-30
lines changed

3 files changed

+37
-30
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ dev = [
7777
"testcontainers>=4.3.1,<5",
7878
"cryptography>=44.0.1 ; python_version > '3.9.1'",
7979
"codespell>=2.4.1,<3",
80+
"langcache>=0.9.0",
8081
]
8182
docs = [
8283
"sphinx>=4.4.0",

redisvl/extensions/cache/llm/langcache.py

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@
1515
logger = get_logger(__name__)
1616

1717

18-
# Placeholders for test patching; actual imports happen at runtime in __init__
19-
LangCacheClient = None # type: ignore
20-
SearchStrategy = None # type: ignore
21-
22-
2318
class LangCacheWrapper(BaseLLMCache):
2419
"""LLM Cache implementation using the LangCache managed service.
2520
@@ -84,23 +79,6 @@ def __init__(
8479
raise ValueError("distance_scale must be 'normalized' or 'redis'")
8580
self._distance_scale = distance_scale
8681

87-
# Import optional dependency at use time; raise clear error if missing
88-
global LangCacheClient, SearchStrategy
89-
try:
90-
if LangCacheClient is None or SearchStrategy is None:
91-
from langcache import LangCache as _LangCacheClient
92-
from langcache.models import SearchStrategy as _SearchStrategy
93-
94-
if LangCacheClient is None:
95-
LangCacheClient = _LangCacheClient
96-
if SearchStrategy is None:
97-
SearchStrategy = _SearchStrategy
98-
except ImportError as e:
99-
raise ImportError(
100-
"The langcache package is required to use LangCacheWrapper. "
101-
"Install it with: pip install redisvl[langcache]"
102-
) from e
103-
10482
if not cache_id:
10583
raise ValueError("cache_id is required for LangCacheWrapper")
10684
if not api_key:
@@ -115,17 +93,36 @@ def __init__(
11593
# Determine search strategies
11694
self._search_strategies = []
11795
if use_exact_search:
118-
self._search_strategies.append(SearchStrategy.EXACT)
96+
self._search_strategies.append("exact")
11997
if use_semantic_search:
120-
self._search_strategies.append(SearchStrategy.SEMANTIC)
98+
self._search_strategies.append("semantic")
12199

122100
if not self._search_strategies:
123101
raise ValueError(
124102
"At least one of use_exact_search or use_semantic_search must be True"
125103
)
126104

127-
# Initialize the LangCache client
128-
self._client = LangCacheClient(
105+
self._client = self._create_client()
106+
107+
def _create_client(self):
108+
"""
109+
Initialize the LangCache client.
110+
111+
Returns:
112+
LangCacheClient: The LangCache client.
113+
114+
Raises:
115+
ImportError: If the langcache package is not installed.
116+
"""
117+
try:
118+
from langcache import LangCacheClient
119+
except ImportError as e:
120+
raise ImportError(
121+
"The langcache package is required to use LangCacheWrapper. "
122+
"Install it with: pip install langcache"
123+
) from e
124+
125+
return LangCacheClient(
129126
server_url=self._server_url,
130127
cache_id=self._cache_id,
131128
api_key=self._api_key,
@@ -151,9 +148,17 @@ def _build_search_kwargs(
151148
similarity_threshold: Optional[float],
152149
attributes: Optional[Dict[str, Any]],
153150
) -> Dict[str, Any]:
151+
from langcache.models import SearchStrategy
152+
153+
# Build enum list lazily here instead of during __init__ to avoid
154+
# import errors at startup. By now, we know langcache is installed.
155+
search_strategies = [
156+
SearchStrategy.EXACT if "exact" in self._search_strategies else None,
157+
SearchStrategy.SEMANTIC if "semantic" in self._search_strategies else None,
158+
]
154159
kwargs: Dict[str, Any] = {
155160
"prompt": prompt,
156-
"search_strategies": self._search_strategies,
161+
"search_strategies": search_strategies,
157162
"similarity_threshold": similarity_threshold,
158163
}
159164
if attributes:

uv.lock

Lines changed: 4 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)