vikramvasudevan commited on
Commit
9ff89e7
·
verified ·
1 Parent(s): 0f51378

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. sanatan_assistant.py +85 -7
sanatan_assistant.py CHANGED
@@ -3,6 +3,10 @@ from typing import Any, Literal
3
  from dotenv import load_dotenv
4
  from config import SanatanConfig
5
  from db import MetadataWhereClause, SanatanDatabase
 
 
 
 
6
 
7
  load_dotenv(override=True)
8
  logger = logging.getLogger(__name__)
@@ -17,6 +21,72 @@ allowedScriptureTitles = Literal[
17
  *[scripture["title"] for scripture in sanatanConfig.scriptures]
18
  ]
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  def format_scripture_answer(
21
  collection_name: allowedCollections, question: str, query_tool_output: str
22
  ):
@@ -146,13 +216,21 @@ def query(
146
  except:
147
  raise
148
 
149
- response = sanatanDatabase.search(
150
- collection_name=collection_name,
151
- query=query,
152
- metadata_where_clause=metadata_where_clause,
153
- n_results=n_results,
154
- search_type=search_type,
155
- )
 
 
 
 
 
 
 
 
156
 
157
  return "\n\n".join(
158
  f"Document: {doc}\nMetadata: {meta}\nID: {id_}"
 
3
  from dotenv import load_dotenv
4
  from config import SanatanConfig
5
  from db import MetadataWhereClause, SanatanDatabase
6
+ import time
7
+ import random
8
+ import logging
9
+ from typing import Optional
10
 
11
  load_dotenv(override=True)
12
  logger = logging.getLogger(__name__)
 
21
  *[scripture["title"] for scripture in sanatanConfig.scriptures]
22
  ]
23
 
24
+ MAX_RETRIES = 3
25
+ BASE_BACKOFF = 0.8 # seconds
26
+ MAX_BACKOFF = 5.0
27
+
28
+ class RateLimitedError(Exception):
29
+ pass
30
+
31
+
32
+ def _is_rate_limit_error(exc: Exception) -> bool:
33
+ msg = str(exc).lower()
34
+ return (
35
+ "429" in msg
36
+ or "rate limit" in msg
37
+ or "<html" in msg # HF sends HTML error pages
38
+ )
39
+
40
+
41
+ def safe_search(
42
+ *,
43
+ collection_name,
44
+ query,
45
+ metadata_where_clause,
46
+ n_results,
47
+ search_type,
48
+ ):
49
+ last_exc: Optional[Exception] = None
50
+
51
+ for attempt in range(1, MAX_RETRIES + 1):
52
+ try:
53
+ return sanatanDatabase.search(
54
+ collection_name=collection_name,
55
+ query=query,
56
+ metadata_where_clause=metadata_where_clause,
57
+ n_results=n_results,
58
+ search_type=search_type,
59
+ )
60
+
61
+ except Exception as exc:
62
+ last_exc = exc
63
+
64
+ if not _is_rate_limit_error(exc):
65
+ # Non-transient error → fail fast
66
+ logger.exception("Non-retriable DB error")
67
+ raise
68
+
69
+ # Rate limit / transient error
70
+ if attempt >= MAX_RETRIES:
71
+ break
72
+
73
+ backoff = min(
74
+ BASE_BACKOFF * (2 ** (attempt - 1)) + random.uniform(0, 0.2),
75
+ MAX_BACKOFF,
76
+ )
77
+
78
+ logger.warning(
79
+ "DB rate-limited (attempt %s/%s). Retrying in %.2fs",
80
+ attempt,
81
+ MAX_RETRIES,
82
+ backoff,
83
+ )
84
+ time.sleep(backoff)
85
+
86
+ logger.error("DB search failed after retries")
87
+ raise RateLimitedError("Database temporarily unavailable") from last_exc
88
+
89
+
90
  def format_scripture_answer(
91
  collection_name: allowedCollections, question: str, query_tool_output: str
92
  ):
 
216
  except:
217
  raise
218
 
219
+ try:
220
+ response = safe_search(
221
+ collection_name=collection_name,
222
+ query=query,
223
+ metadata_where_clause=metadata_where_clause,
224
+ n_results=n_results,
225
+ search_type=search_type,
226
+ )
227
+ except RateLimitedError:
228
+ logger.warning(
229
+ "Falling back due to DB rate limit: collection=%s search_type=%s",
230
+ collection_name,
231
+ search_type,
232
+ )
233
+ return ""
234
 
235
  return "\n\n".join(
236
  f"Document: {doc}\nMetadata: {meta}\nID: {id_}"