adAstra144 commited on
Commit
ff65d27
·
verified ·
1 Parent(s): 9bdced2

Thread lock 2

Browse files
Files changed (1) hide show
  1. app.py +29 -3
app.py CHANGED
@@ -36,16 +36,32 @@ if not OPENROUTER_API_KEY:
36
  # outbound OpenRouter calls behind a single lock and enforce a minimum gap
37
  # between them. Whichever request arrives second simply waits its turn.
38
  # ---------------------------------------------------------------------------
39
- MIN_INTERVAL_SECONDS = float(os.environ.get("OPENROUTER_MIN_INTERVAL", "2.0"))
 
 
40
 
41
  _or_lock = threading.Lock()
42
  _last_call_time = 0.0
43
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  def call_openrouter(payload: dict, headers: dict, timeout: int = 20):
45
  """Thread-safe, rate-limited call to OpenRouter's chat completions endpoint.
46
 
47
- Ensures at least MIN_INTERVAL_SECONDS has elapsed since the previous
48
- OpenRouter call (across ALL endpoints) before firing this one.
 
 
49
  """
50
  global _last_call_time
51
 
@@ -62,6 +78,16 @@ def call_openrouter(payload: dict, headers: dict, timeout: int = 20):
62
  response = requests.post(url, headers=headers, json=payload, timeout=timeout)
63
  _last_call_time = time.monotonic()
64
 
 
 
 
 
 
 
 
 
 
 
65
  return response
66
 
67
 
 
36
  # outbound OpenRouter calls behind a single lock and enforce a minimum gap
37
  # between them. Whichever request arrives second simply waits its turn.
38
  # ---------------------------------------------------------------------------
39
+ MIN_INTERVAL_SECONDS = float(os.environ.get("OPENROUTER_MIN_INTERVAL", "6.0"))
40
+ MAX_RETRIES = int(os.environ.get("OPENROUTER_MAX_RETRIES", "3"))
41
+ RETRY_BACKOFF_SECONDS = float(os.environ.get("OPENROUTER_RETRY_BACKOFF", "5.0"))
42
 
43
  _or_lock = threading.Lock()
44
  _last_call_time = 0.0
45
 
46
+ def _is_rate_limited(response: requests.Response) -> bool:
47
+ """Detect a 429 whether it comes as an HTTP status or embedded in a 200 body
48
+ (OpenRouter sometimes returns 200 with {"error": {"code": 429, ...}})."""
49
+ if response.status_code == 429:
50
+ return True
51
+ try:
52
+ body = response.json()
53
+ except ValueError:
54
+ return False
55
+ return isinstance(body, dict) and body.get("error", {}).get("code") == 429
56
+
57
+
58
  def call_openrouter(payload: dict, headers: dict, timeout: int = 20):
59
  """Thread-safe, rate-limited call to OpenRouter's chat completions endpoint.
60
 
61
+ - Ensures at least MIN_INTERVAL_SECONDS has elapsed since the previous
62
+ OpenRouter call (across ALL endpoints) before firing this one.
63
+ - If the provider still returns a 429 (as a status code or embedded in the
64
+ JSON body), retries with exponential backoff up to MAX_RETRIES times.
65
  """
66
  global _last_call_time
67
 
 
78
  response = requests.post(url, headers=headers, json=payload, timeout=timeout)
79
  _last_call_time = time.monotonic()
80
 
81
+ attempt = 0
82
+ while _is_rate_limited(response) and attempt < MAX_RETRIES:
83
+ backoff = RETRY_BACKOFF_SECONDS * (2 ** attempt)
84
+ logger.warning(f"OpenRouter rate limited (attempt {attempt + 1}/{MAX_RETRIES}); "
85
+ f"backing off {backoff:.1f}s before retry")
86
+ time.sleep(backoff)
87
+ response = requests.post(url, headers=headers, json=payload, timeout=timeout)
88
+ _last_call_time = time.monotonic()
89
+ attempt += 1
90
+
91
  return response
92
 
93