ZainabFatimaa commited on
Commit
68963d4
Β·
verified Β·
1 Parent(s): 3b2ce1a

Update src/app.py

Browse files
Files changed (1) hide show
  1. src/app.py +115 -32
src/app.py CHANGED
@@ -61,46 +61,101 @@ from reportlab.lib.units import inch
61
 
62
  # Claude Chatbot Class
63
  import time
 
 
 
 
64
 
65
  class ClaudeChatbot:
66
  def __init__(self):
67
  self.api_key = os.getenv('OPENROUTER_API_KEY')
68
  self.base_url = "https://openrouter.ai/api/v1/chat/completions"
69
 
70
- # Use a single reliable free model
71
  self.model = "meta-llama/llama-3.2-3b-instruct:free"
72
 
73
- # Rate limiting variables
74
  self.last_request_time = 0
75
- self.min_request_interval = 6 # 6 seconds between requests for OpenRouter free tier
76
  self.daily_requests = 0
77
- self.max_daily_requests = 50 # OpenRouter free tier limit
 
 
 
78
 
79
  if not self.api_key:
80
  st.error("❌ OPENROUTER_API_KEY not found in environment variables!")
81
  st.info("Please set your OpenRouter API key in the environment variables.")
 
 
82
 
83
  def _wait_for_rate_limit(self):
84
- """Ensure we don't exceed rate limits - OpenRouter free tier requires 5+ second intervals"""
85
  current_time = time.time()
86
  time_since_last_request = current_time - self.last_request_time
87
 
88
- # OpenRouter free tier requires 5+ seconds between requests
89
  if time_since_last_request < self.min_request_interval:
90
  sleep_time = self.min_request_interval - time_since_last_request
91
- st.info(f"Rate limiting: waiting {sleep_time:.1f} seconds...")
 
92
  time.sleep(sleep_time)
93
 
94
  self.last_request_time = time.time()
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  def generate_response(self, prompt, context="", max_tokens=1000):
97
- """Generate response using the configured model with rate limiting"""
98
  if not self.api_key:
99
  return "Error: API key not configured. Please set OPENROUTER_API_KEY in your environment variables."
100
 
101
  # Check daily limit
102
  if self.daily_requests >= self.max_daily_requests:
103
- return f"Daily request limit reached ({self.max_daily_requests} requests). Please try again tomorrow or add credits to your OpenRouter account."
104
 
105
  # Rate limiting
106
  self._wait_for_rate_limit()
@@ -116,7 +171,7 @@ class ClaudeChatbot:
116
 
117
  if context:
118
  # Limit context to avoid token limits
119
- system_prompt += f"\n\nContext about the user's resume:\n{context[:1500]}"
120
 
121
  data = {
122
  "model": self.model,
@@ -130,40 +185,71 @@ class ClaudeChatbot:
130
  "frequency_penalty": 0.1
131
  }
132
 
 
 
 
 
 
 
133
  try:
134
- st.info(f"Making API request... (Daily requests used: {self.daily_requests}/{self.max_daily_requests})")
 
 
135
  response = requests.post(self.base_url, headers=headers, json=data, timeout=30)
136
 
137
- # Log response status for debugging
138
- st.info(f"API Response Status: {response.status_code}")
 
139
 
140
- # Handle different error codes
141
  if response.status_code == 429:
142
- error_data = response.json() if response.headers.get('content-type') == 'application/json' else {}
143
- return f"Rate limit exceeded. Error details: {error_data.get('error', {}).get('message', 'Unknown rate limit error')}"
 
 
 
 
 
144
  elif response.status_code == 402:
145
- return "This model requires payment. Please add credits to your OpenRouter account or wait for the daily limit to reset."
 
146
  elif response.status_code == 401:
147
  return "Invalid API key. Please check your OPENROUTER_API_KEY environment variable."
 
148
  elif response.status_code == 400:
149
- error_data = response.json() if response.headers.get('content-type') == 'application/json' else {}
150
- return f"Bad request. Error: {error_data.get('error', {}).get('message', 'Invalid request format')}"
 
 
 
 
 
 
 
151
  elif response.status_code != 200:
152
  try:
153
  error_data = response.json()
154
- return f"API Error {response.status_code}: {error_data.get('error', {}).get('message', response.text[:200])}"
 
155
  except:
156
  return f"API Error {response.status_code}: {response.text[:200]}"
157
 
158
- result = response.json()
159
-
160
- if 'choices' in result and len(result['choices']) > 0:
161
- self.daily_requests += 1 # Increment only on successful response
162
- response_text = result['choices'][0]['message']['content'].strip()
163
- st.success(f"Response generated successfully! (Remaining daily requests: {self.max_daily_requests - self.daily_requests})")
164
- return response_text
165
- else:
166
- return f"Error: Unexpected response format. Response: {json.dumps(result, indent=2)[:500]}"
 
 
 
 
 
 
 
167
 
168
  except requests.exceptions.Timeout:
169
  return "Request timed out after 30 seconds. Please try again with a shorter question."
@@ -171,12 +257,9 @@ class ClaudeChatbot:
171
  return "Connection error. Please check your internet connection and try again."
172
  except requests.exceptions.RequestException as e:
173
  return f"Request error: {str(e)}"
174
- except json.JSONDecodeError as e:
175
- return f"Error: Invalid JSON response from API. Raw response: {response.text[:200]}"
176
  except Exception as e:
177
  return f"Unexpected error: {str(e)}"
178
 
179
-
180
  # Download NLTK data if not already present
181
  @st.cache_resource
182
  def download_nltk_data():
 
61
 
62
  # Claude Chatbot Class
63
  import time
64
+ import os
65
+ import requests
66
+ import json
67
+ import streamlit as st
68
 
69
  class ClaudeChatbot:
70
  def __init__(self):
71
  self.api_key = os.getenv('OPENROUTER_API_KEY')
72
  self.base_url = "https://openrouter.ai/api/v1/chat/completions"
73
 
74
+ # Use a reliable free model
75
  self.model = "meta-llama/llama-3.2-3b-instruct:free"
76
 
77
+ # More lenient rate limiting
78
  self.last_request_time = 0
79
+ self.min_request_interval = 2 # Reduced to 2 seconds
80
  self.daily_requests = 0
81
+ self.max_daily_requests = 200 # Increased limit
82
+
83
+ # Debug mode
84
+ self.debug = True
85
 
86
  if not self.api_key:
87
  st.error("❌ OPENROUTER_API_KEY not found in environment variables!")
88
  st.info("Please set your OpenRouter API key in the environment variables.")
89
+ if self.debug:
90
+ st.write("**Debug**: Checked environment variable 'OPENROUTER_API_KEY'")
91
 
92
  def _wait_for_rate_limit(self):
93
+ """Ensure we don't exceed rate limits"""
94
  current_time = time.time()
95
  time_since_last_request = current_time - self.last_request_time
96
 
 
97
  if time_since_last_request < self.min_request_interval:
98
  sleep_time = self.min_request_interval - time_since_last_request
99
+ if self.debug:
100
+ st.info(f"Rate limiting: waiting {sleep_time:.1f} seconds...")
101
  time.sleep(sleep_time)
102
 
103
  self.last_request_time = time.time()
104
 
105
+ def test_connection(self):
106
+ """Test the API connection with a simple request"""
107
+ if not self.api_key:
108
+ return "Error: No API key found"
109
+
110
+ headers = {
111
+ "Authorization": f"Bearer {self.api_key}",
112
+ "Content-Type": "application/json",
113
+ "HTTP-Referer": "https://streamlit-resume-analyzer.com",
114
+ "X-Title": "AI Resume Analyzer"
115
+ }
116
+
117
+ test_data = {
118
+ "model": self.model,
119
+ "messages": [
120
+ {"role": "system", "content": "You are a helpful assistant."},
121
+ {"role": "user", "content": "Say 'Connection test successful'"}
122
+ ],
123
+ "max_tokens": 50,
124
+ "temperature": 0.1
125
+ }
126
+
127
+ try:
128
+ response = requests.post(self.base_url, headers=headers, json=test_data, timeout=10)
129
+
130
+ if self.debug:
131
+ st.write(f"**Debug - Test Response Status**: {response.status_code}")
132
+ st.write(f"**Debug - Response Headers**: {dict(response.headers)}")
133
+
134
+ if response.status_code == 200:
135
+ result = response.json()
136
+ if 'choices' in result and len(result['choices']) > 0:
137
+ return f"βœ… Connection successful: {result['choices'][0]['message']['content']}"
138
+ else:
139
+ return f"❌ Unexpected response format: {result}"
140
+ else:
141
+ error_text = response.text
142
+ return f"❌ Connection failed ({response.status_code}): {error_text}"
143
+
144
+ except requests.exceptions.Timeout:
145
+ return "❌ Connection test timed out"
146
+ except requests.exceptions.ConnectionError:
147
+ return "❌ Connection error - check internet connection"
148
+ except Exception as e:
149
+ return f"❌ Test failed: {str(e)}"
150
+
151
  def generate_response(self, prompt, context="", max_tokens=1000):
152
+ """Generate response with improved error handling and debugging"""
153
  if not self.api_key:
154
  return "Error: API key not configured. Please set OPENROUTER_API_KEY in your environment variables."
155
 
156
  # Check daily limit
157
  if self.daily_requests >= self.max_daily_requests:
158
+ return f"Daily request limit reached ({self.max_daily_requests} requests). Please try again tomorrow."
159
 
160
  # Rate limiting
161
  self._wait_for_rate_limit()
 
171
 
172
  if context:
173
  # Limit context to avoid token limits
174
+ system_prompt += f"\n\nContext about the user's resume:\n{context[:1000]}"
175
 
176
  data = {
177
  "model": self.model,
 
185
  "frequency_penalty": 0.1
186
  }
187
 
188
+ if self.debug:
189
+ st.write(f"**Debug - Request URL**: {self.base_url}")
190
+ st.write(f"**Debug - Model**: {self.model}")
191
+ st.write(f"**Debug - Prompt length**: {len(prompt)} chars")
192
+ st.write(f"**Debug - Context length**: {len(context)} chars")
193
+
194
  try:
195
+ if self.debug:
196
+ st.info(f"Making API request... (Daily requests used: {self.daily_requests}/{self.max_daily_requests})")
197
+
198
  response = requests.post(self.base_url, headers=headers, json=data, timeout=30)
199
 
200
+ if self.debug:
201
+ st.write(f"**Debug - Response Status**: {response.status_code}")
202
+ st.write(f"**Debug - Response Headers**: {dict(response.headers)}")
203
 
204
+ # Handle different error codes with more detail
205
  if response.status_code == 429:
206
+ try:
207
+ error_data = response.json()
208
+ error_message = error_data.get('error', {}).get('message', 'Rate limit exceeded')
209
+ return f"Rate limit exceeded: {error_message}. Please wait and try again."
210
+ except:
211
+ return "Rate limit exceeded. Please wait a few minutes and try again."
212
+
213
  elif response.status_code == 402:
214
+ return "This request requires payment. Please add credits to your OpenRouter account."
215
+
216
  elif response.status_code == 401:
217
  return "Invalid API key. Please check your OPENROUTER_API_KEY environment variable."
218
+
219
  elif response.status_code == 400:
220
+ try:
221
+ error_data = response.json()
222
+ error_message = error_data.get('error', {}).get('message', 'Bad request')
223
+ if self.debug:
224
+ st.write(f"**Debug - 400 Error Details**: {error_data}")
225
+ return f"Bad request: {error_message}"
226
+ except:
227
+ return f"Bad request. Raw response: {response.text[:200]}"
228
+
229
  elif response.status_code != 200:
230
  try:
231
  error_data = response.json()
232
+ error_message = error_data.get('error', {}).get('message', response.text[:200])
233
+ return f"API Error {response.status_code}: {error_message}"
234
  except:
235
  return f"API Error {response.status_code}: {response.text[:200]}"
236
 
237
+ # Success case
238
+ try:
239
+ result = response.json()
240
+ if self.debug:
241
+ st.write(f"**Debug - Response keys**: {list(result.keys())}")
242
+
243
+ if 'choices' in result and len(result['choices']) > 0:
244
+ self.daily_requests += 1
245
+ response_text = result['choices'][0]['message']['content'].strip()
246
+ if self.debug:
247
+ st.success(f"Response generated successfully! (Remaining: {self.max_daily_requests - self.daily_requests})")
248
+ return response_text
249
+ else:
250
+ return f"Error: Unexpected response format. Response keys: {list(result.keys())}"
251
+ except json.JSONDecodeError as e:
252
+ return f"Error: Invalid JSON response. Raw response: {response.text[:200]}"
253
 
254
  except requests.exceptions.Timeout:
255
  return "Request timed out after 30 seconds. Please try again with a shorter question."
 
257
  return "Connection error. Please check your internet connection and try again."
258
  except requests.exceptions.RequestException as e:
259
  return f"Request error: {str(e)}"
 
 
260
  except Exception as e:
261
  return f"Unexpected error: {str(e)}"
262
 
 
263
  # Download NLTK data if not already present
264
  @st.cache_resource
265
  def download_nltk_data():