davidtran999 commited on
Commit
7c44149
·
verified ·
1 Parent(s): 45d532b

Upload backend/hue_portal/core/cache_utils.py with huggingface_hub

Browse files
backend/hue_portal/core/cache_utils.py ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Caching utilities for chatbot responses and search results.
3
+ """
4
+ from functools import lru_cache
5
+ from django.core.cache import cache
6
+ import hashlib
7
+ import time
8
+ from typing import Optional, Dict, Any
9
+
10
+
11
+ class ChatbotCache:
12
+ """Multi-level caching for chatbot responses."""
13
+
14
+ CACHE_TIMEOUT = 3600 # 1 hour
15
+ CACHE_PREFIX = "chatbot"
16
+ SEARCH_CACHE_PREFIX = "search"
17
+
18
+ # Cache statistics
19
+ cache_hits = 0
20
+ cache_misses = 0
21
+
22
+ @staticmethod
23
+ def get_cache_key(query: str, intent: str, session_id: Optional[str] = None) -> str:
24
+ """
25
+ Generate cache key for chatbot response.
26
+
27
+ Args:
28
+ query: User query string.
29
+ intent: Detected intent.
30
+ session_id: Optional session ID.
31
+
32
+ Returns:
33
+ Cache key string.
34
+ """
35
+ key_parts = [query.lower().strip(), intent]
36
+ if session_id:
37
+ key_parts.append(session_id)
38
+ key_str = "|".join(key_parts)
39
+ key_hash = hashlib.md5(key_str.encode('utf-8')).hexdigest()
40
+ return f"{ChatbotCache.CACHE_PREFIX}:{key_hash}"
41
+
42
+ @staticmethod
43
+ def get_cached_response(query: str, intent: str, session_id: Optional[str] = None) -> Optional[Dict[str, Any]]:
44
+ """
45
+ Get cached chatbot response.
46
+
47
+ Args:
48
+ query: User query string.
49
+ intent: Detected intent.
50
+ session_id: Optional session ID.
51
+
52
+ Returns:
53
+ Cached response dict or None.
54
+ """
55
+ cache_key = ChatbotCache.get_cache_key(query, intent, session_id)
56
+ cached = cache.get(cache_key)
57
+
58
+ if cached:
59
+ ChatbotCache.cache_hits += 1
60
+ return cached
61
+
62
+ ChatbotCache.cache_misses += 1
63
+ return None
64
+
65
+ @staticmethod
66
+ def set_cached_response(
67
+ query: str,
68
+ intent: str,
69
+ response: Dict[str, Any],
70
+ session_id: Optional[str] = None,
71
+ timeout: Optional[int] = None
72
+ ) -> None:
73
+ """
74
+ Cache chatbot response.
75
+
76
+ Args:
77
+ query: User query string.
78
+ intent: Detected intent.
79
+ response: Response dict to cache.
80
+ session_id: Optional session ID.
81
+ timeout: Cache timeout in seconds (default: CACHE_TIMEOUT).
82
+ """
83
+ cache_key = ChatbotCache.get_cache_key(query, intent, session_id)
84
+ timeout = timeout or ChatbotCache.CACHE_TIMEOUT
85
+
86
+ # Add timestamp for cache validation
87
+ cached_data = {
88
+ **response,
89
+ '_cached_at': time.time()
90
+ }
91
+
92
+ cache.set(cache_key, cached_data, timeout)
93
+
94
+ @staticmethod
95
+ def get_cached_search_results(query: str, model_name: str, text_fields: tuple) -> Optional[list]:
96
+ """
97
+ Get cached search results.
98
+
99
+ Args:
100
+ query: Search query.
101
+ model_name: Model name.
102
+ text_fields: Tuple of text fields searched.
103
+
104
+ Returns:
105
+ Cached results list or None.
106
+ """
107
+ key_str = f"{query}|{model_name}|{':'.join(text_fields)}"
108
+ key_hash = hashlib.md5(key_str.encode('utf-8')).hexdigest()
109
+ cache_key = f"{ChatbotCache.SEARCH_CACHE_PREFIX}:{key_hash}"
110
+
111
+ cached = cache.get(cache_key)
112
+ if cached:
113
+ ChatbotCache.cache_hits += 1
114
+ return cached
115
+
116
+ ChatbotCache.cache_misses += 1
117
+ return None
118
+
119
+ @staticmethod
120
+ def set_cached_search_results(
121
+ query: str,
122
+ model_name: str,
123
+ text_fields: tuple,
124
+ results: list,
125
+ timeout: Optional[int] = None
126
+ ) -> None:
127
+ """
128
+ Cache search results.
129
+
130
+ Args:
131
+ query: Search query.
132
+ model_name: Model name.
133
+ text_fields: Tuple of text fields searched.
134
+ results: Results list to cache.
135
+ timeout: Cache timeout in seconds (default: CACHE_TIMEOUT).
136
+ """
137
+ key_str = f"{query}|{model_name}|{':'.join(text_fields)}"
138
+ key_hash = hashlib.md5(key_str.encode('utf-8')).hexdigest()
139
+ cache_key = f"{ChatbotCache.SEARCH_CACHE_PREFIX}:{key_hash}"
140
+ timeout = timeout or ChatbotCache.CACHE_TIMEOUT
141
+
142
+ cache.set(cache_key, results, timeout)
143
+
144
+ @staticmethod
145
+ def invalidate_cache(query: Optional[str] = None, intent: Optional[str] = None) -> None:
146
+ """
147
+ Invalidate cache entries.
148
+
149
+ Args:
150
+ query: Optional query to invalidate (if None, invalidate all).
151
+ intent: Optional intent to invalidate.
152
+ """
153
+ if query and intent:
154
+ cache_key = ChatbotCache.get_cache_key(query, intent)
155
+ cache.delete(cache_key)
156
+ else:
157
+ # Invalidate all chatbot cache (use cache.clear() with caution)
158
+ # For production, use cache versioning instead
159
+ pass
160
+
161
+ @staticmethod
162
+ def get_cache_stats() -> Dict[str, Any]:
163
+ """
164
+ Get cache statistics.
165
+
166
+ Returns:
167
+ Dictionary with cache hit rate and counts.
168
+ """
169
+ total = ChatbotCache.cache_hits + ChatbotCache.cache_misses
170
+ if total == 0:
171
+ return {
172
+ "hit_rate": 0.0,
173
+ "hits": 0,
174
+ "misses": 0,
175
+ "total": 0
176
+ }
177
+
178
+ return {
179
+ "hit_rate": ChatbotCache.cache_hits / total,
180
+ "hits": ChatbotCache.cache_hits,
181
+ "misses": ChatbotCache.cache_misses,
182
+ "total": total
183
+ }
184
+
185
+ @staticmethod
186
+ def reset_stats() -> None:
187
+ """Reset cache statistics."""
188
+ ChatbotCache.cache_hits = 0
189
+ ChatbotCache.cache_misses = 0
190
+
191
+
192
+ @lru_cache(maxsize=1)
193
+ def get_all_synonyms():
194
+ """
195
+ Get all synonyms from database (cached).
196
+
197
+ Returns:
198
+ List of Synonym objects.
199
+ """
200
+ from .models import Synonym
201
+ try:
202
+ return list(Synonym.objects.all())
203
+ except Exception:
204
+ return []
205
+