siddhartharya commited on
Commit
3ed7877
·
verified ·
1 Parent(s): ac8ac70

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -65
app.py CHANGED
@@ -15,6 +15,7 @@ import sys
15
  import concurrent.futures
16
  from concurrent.futures import ThreadPoolExecutor
17
  import threading
 
18
 
19
  # Import OpenAI library
20
  import openai
@@ -80,7 +81,10 @@ if not GROQ_API_KEY:
80
  logger.error("GROQ_API_KEY environment variable not set.")
81
 
82
  openai.api_key = GROQ_API_KEY
83
- openai.api_base = "https://api.groq.com/openai/v1"
 
 
 
84
 
85
  # Global variables for models to enable lazy loading
86
  embedding_model = None
@@ -168,21 +172,20 @@ def generate_summary_and_assign_category(bookmark):
168
  """
169
  logger.info(f"Generating summary and assigning category for bookmark: {bookmark.get('url')}")
170
 
171
- max_retries = 3
172
  retry_count = 0
 
173
 
174
  while retry_count < max_retries:
175
  try:
176
  html_content = bookmark.get('html_content', '')
177
 
178
- # Get the HTML soup object from the bookmark
179
  soup = BeautifulSoup(html_content, 'html.parser')
180
-
181
- # Extract metadata and main content
182
  metadata = get_page_metadata(soup)
183
  main_content = extract_main_content(soup)
184
 
185
- # Prepare content for the prompt
186
  content_parts = []
187
  if metadata['title']:
188
  content_parts.append(f"Title: {metadata['title']}")
@@ -195,18 +198,17 @@ def generate_summary_and_assign_category(bookmark):
195
 
196
  content_text = '\n'.join(content_parts)
197
 
198
- # Detect insufficient or erroneous content
199
  error_keywords = ['Access Denied', 'Security Check', 'Cloudflare', 'captcha', 'unusual traffic']
200
  if not content_text or len(content_text.split()) < 50:
201
  use_prior_knowledge = True
202
- logger.info(f"Content for {bookmark.get('url')} is insufficient. Instructing LLM to use prior knowledge.")
203
  elif any(keyword.lower() in content_text.lower() for keyword in error_keywords):
204
  use_prior_knowledge = True
205
- logger.info(f"Content for {bookmark.get('url')} contains error messages. Instructing LLM to use prior knowledge.")
206
  else:
207
  use_prior_knowledge = False
208
 
209
- # Shortened prompts
210
  if use_prior_knowledge:
211
  prompt = f"""
212
  You are a knowledgeable assistant with up-to-date information as of 2023.
@@ -235,52 +237,28 @@ Summary: [Your summary]
235
  Category: [One category]
236
  """
237
 
238
- # Estimate tokens
239
- def estimate_tokens(text):
240
- return len(text) / 4 # Approximate token estimation
241
-
242
- prompt_tokens = estimate_tokens(prompt)
243
- max_tokens = 150 # Reduced from 200
244
- total_tokens = prompt_tokens + max_tokens
245
-
246
- # Calculate required delay
247
- tokens_per_minute = 60000 # Adjust based on your rate limit
248
- tokens_per_second = tokens_per_minute / 60
249
- required_delay = total_tokens / tokens_per_second
250
- sleep_time = max(required_delay, 1)
251
-
252
- # Call the LLM via Groq Cloud API
253
- response = openai.ChatCompletion.create(
254
- model='llama-3.1-70b-versatile', # Using the specified model
255
- messages=[
256
- {"role": "user", "content": prompt}
257
- ],
258
- max_tokens=int(max_tokens),
259
- temperature=0.5,
260
- )
261
  content = response['choices'][0]['message']['content'].strip()
262
  if not content:
263
  raise ValueError("Empty response received from the model.")
264
 
265
- # Parse the response
266
  summary_match = re.search(r"Summary:\s*(.*)", content)
267
  category_match = re.search(r"Category:\s*(.*)", content)
268
 
269
- if summary_match:
270
- bookmark['summary'] = summary_match.group(1).strip()
271
- else:
272
- bookmark['summary'] = 'No summary available.'
273
-
274
- if category_match:
275
- category = category_match.group(1).strip().strip('"')
276
- if category in CATEGORIES:
277
- bookmark['category'] = category
278
- else:
279
- bookmark['category'] = 'Uncategorized'
280
- else:
281
- bookmark['category'] = 'Uncategorized'
282
 
283
- # Simple keyword-based validation (Optional)
284
  summary_lower = bookmark['summary'].lower()
285
  url_lower = bookmark['url'].lower()
286
  if 'social media' in summary_lower or 'twitter' in summary_lower or 'x.com' in url_lower:
@@ -289,20 +267,23 @@ Category: [One category]
289
  bookmark['category'] = 'Reference and Knowledge Bases'
290
 
291
  logger.info("Successfully generated summary and assigned category")
292
- time.sleep(sleep_time)
293
- break # Exit the retry loop upon success
294
 
295
  except openai.error.RateLimitError as e:
296
  retry_count += 1
297
- wait_time = int(e.headers.get("Retry-After", 5))
298
- logger.warning(f"Rate limit reached. Waiting for {wait_time} seconds before retrying...")
299
  time.sleep(wait_time)
300
  except Exception as e:
301
  logger.error(f"Error generating summary and assigning category: {e}", exc_info=True)
302
- # Ensure 'summary' is always set, even on failure
303
  bookmark['summary'] = 'No summary available.'
304
  bookmark['category'] = 'Uncategorized'
305
- break # Exit the retry loop on other exceptions
 
 
 
 
 
306
 
307
  def parse_bookmarks(file_content):
308
  """
@@ -521,12 +502,12 @@ def process_uploaded_file(file, state_bookmarks):
521
 
522
  # Fetch bookmark info concurrently
523
  logger.info("Fetching URL info concurrently")
524
- with ThreadPoolExecutor(max_workers=10) as executor: # Adjusted max_workers
525
  executor.map(fetch_url_info, bookmarks)
526
 
527
  # Generate summaries and assign categories
528
  logger.info("Generating summaries and assigning categories")
529
- with ThreadPoolExecutor(max_workers=3) as executor: # Adjusted max_workers
530
  executor.map(generate_summary_and_assign_category, bookmarks)
531
 
532
  # Log bookmarks to verify 'summary' and 'category' presence
@@ -725,15 +706,16 @@ Bookmarks:
725
  Provide a concise and helpful response.
726
  """
727
 
728
- # Call the LLM via Groq Cloud API
729
- response = openai.ChatCompletion.create(
730
- model='llama-3.1-70b-versatile', # Using the specified model
731
- messages=[
732
- {"role": "user", "content": prompt}
733
- ],
734
- max_tokens=300,
735
- temperature=0.7,
736
- )
 
737
  answer = response['choices'][0]['message']['content'].strip()
738
  logger.info("Chatbot response generated")
739
  return chat_history + [{"role": "user", "content": user_query}, {"role": "assistant", "content": answer}]
 
15
  import concurrent.futures
16
  from concurrent.futures import ThreadPoolExecutor
17
  import threading
18
+ from ratelimiter import RateLimiter # Optional
19
 
20
  # Import OpenAI library
21
  import openai
 
81
  logger.error("GROQ_API_KEY environment variable not set.")
82
 
83
  openai.api_key = GROQ_API_KEY
84
+ openai.api_base = "https://api.groq.com/openai/v1" # Ensure this is the correct base URL
85
+
86
+ # Initialize rate limiter (optional, adjust based on rate limits)
87
+ llm_rate_limiter = RateLimiter(max_calls=20, period=60) # Example: 20 calls per minute
88
 
89
  # Global variables for models to enable lazy loading
90
  embedding_model = None
 
172
  """
173
  logger.info(f"Generating summary and assigning category for bookmark: {bookmark.get('url')}")
174
 
175
+ max_retries = 5
176
  retry_count = 0
177
+ base_wait = 1 # Initial wait time in seconds
178
 
179
  while retry_count < max_retries:
180
  try:
181
  html_content = bookmark.get('html_content', '')
182
 
183
+ # Parse HTML content
184
  soup = BeautifulSoup(html_content, 'html.parser')
 
 
185
  metadata = get_page_metadata(soup)
186
  main_content = extract_main_content(soup)
187
 
188
+ # Prepare prompt
189
  content_parts = []
190
  if metadata['title']:
191
  content_parts.append(f"Title: {metadata['title']}")
 
198
 
199
  content_text = '\n'.join(content_parts)
200
 
201
+ # Determine prompt type
202
  error_keywords = ['Access Denied', 'Security Check', 'Cloudflare', 'captcha', 'unusual traffic']
203
  if not content_text or len(content_text.split()) < 50:
204
  use_prior_knowledge = True
205
+ logger.info(f"Content for {bookmark.get('url')} is insufficient. Using prior knowledge.")
206
  elif any(keyword.lower() in content_text.lower() for keyword in error_keywords):
207
  use_prior_knowledge = True
208
+ logger.info(f"Content for {bookmark.get('url')} contains error messages. Using prior knowledge.")
209
  else:
210
  use_prior_knowledge = False
211
 
 
212
  if use_prior_knowledge:
213
  prompt = f"""
214
  You are a knowledgeable assistant with up-to-date information as of 2023.
 
237
  Category: [One category]
238
  """
239
 
240
+ # Call the LLM via Groq Cloud API with rate limiting
241
+ with llm_rate_limiter:
242
+ response = openai.ChatCompletion.create(
243
+ model='llama-3.1-70b-versatile', # Ensure this is the correct model name
244
+ messages=[
245
+ {"role": "user", "content": prompt}
246
+ ],
247
+ max_tokens=150,
248
+ temperature=0.5,
249
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  content = response['choices'][0]['message']['content'].strip()
251
  if not content:
252
  raise ValueError("Empty response received from the model.")
253
 
254
+ # Parse response
255
  summary_match = re.search(r"Summary:\s*(.*)", content)
256
  category_match = re.search(r"Category:\s*(.*)", content)
257
 
258
+ bookmark['summary'] = summary_match.group(1).strip() if summary_match else 'No summary available.'
259
+ bookmark['category'] = category_match.group(1).strip().strip('"') if category_match else 'Uncategorized'
 
 
 
 
 
 
 
 
 
 
 
260
 
261
+ # Additional validation (optional)
262
  summary_lower = bookmark['summary'].lower()
263
  url_lower = bookmark['url'].lower()
264
  if 'social media' in summary_lower or 'twitter' in summary_lower or 'x.com' in url_lower:
 
267
  bookmark['category'] = 'Reference and Knowledge Bases'
268
 
269
  logger.info("Successfully generated summary and assigned category")
270
+ break # Exit loop on success
 
271
 
272
  except openai.error.RateLimitError as e:
273
  retry_count += 1
274
+ wait_time = base_wait * (2 ** retry_count) # Exponential backoff
275
+ logger.warning(f"Rate limit reached. Waiting for {wait_time} seconds before retrying... (Attempt {retry_count}/{max_retries})")
276
  time.sleep(wait_time)
277
  except Exception as e:
278
  logger.error(f"Error generating summary and assigning category: {e}", exc_info=True)
 
279
  bookmark['summary'] = 'No summary available.'
280
  bookmark['category'] = 'Uncategorized'
281
+ break # Exit loop on non-rate limit errors
282
+
283
+ if retry_count == max_retries:
284
+ logger.error(f"Failed to generate summary for {bookmark.get('url')} after {max_retries} attempts.")
285
+ bookmark['summary'] = 'No summary available.'
286
+ bookmark['category'] = 'Uncategorized'
287
 
288
  def parse_bookmarks(file_content):
289
  """
 
502
 
503
  # Fetch bookmark info concurrently
504
  logger.info("Fetching URL info concurrently")
505
+ with ThreadPoolExecutor(max_workers=5) as executor: # Reduced max_workers from 10 to 5
506
  executor.map(fetch_url_info, bookmarks)
507
 
508
  # Generate summaries and assign categories
509
  logger.info("Generating summaries and assigning categories")
510
+ with ThreadPoolExecutor(max_workers=2) as executor: # Reduced max_workers from 3 to 2
511
  executor.map(generate_summary_and_assign_category, bookmarks)
512
 
513
  # Log bookmarks to verify 'summary' and 'category' presence
 
706
  Provide a concise and helpful response.
707
  """
708
 
709
+ # Call the LLM via Groq Cloud API with rate limiting
710
+ with llm_rate_limiter:
711
+ response = openai.ChatCompletion.create(
712
+ model='llama-3.1-70b-versatile', # Ensure this is the correct model name
713
+ messages=[
714
+ {"role": "user", "content": prompt}
715
+ ],
716
+ max_tokens=300,
717
+ temperature=0.7,
718
+ )
719
  answer = response['choices'][0]['message']['content'].strip()
720
  logger.info("Chatbot response generated")
721
  return chat_history + [{"role": "user", "content": user_query}, {"role": "assistant", "content": answer}]