siddhartharya commited on
Commit
7b16cc6
·
verified ·
1 Parent(s): 8f32801

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +166 -4
app.py CHANGED
@@ -159,7 +159,7 @@ def get_page_metadata(soup):
159
 
160
  async def generate_summary_async(bookmark):
161
  async with llm_semaphore:
162
- generate_summary(bookmark)
163
 
164
  def generate_summary(bookmark):
165
  """
@@ -270,7 +270,7 @@ Be concise and objective.
270
 
271
  async def assign_category_async(bookmark):
272
  async with llm_semaphore:
273
- assign_category(bookmark)
274
 
275
  def assign_category(bookmark):
276
  """
@@ -452,6 +452,10 @@ async def process_bookmarks_llm(bookmarks_list):
452
  tasks = []
453
  for bookmark in bookmarks_list:
454
  tasks.append(generate_summary_async(bookmark))
 
 
 
 
455
  tasks.append(assign_category_async(bookmark))
456
  await asyncio.gather(*tasks)
457
  logger.info("Completed LLM processing of bookmarks")
@@ -585,9 +589,167 @@ def process_uploaded_file(file):
585
 
586
  return message, bookmark_html, gr.update(choices=choices), bookmark_html
587
 
588
- # The rest of the code remains unchanged (e.g., delete_selected_bookmarks, edit_selected_bookmarks_category, etc.)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
589
 
590
- # Build and launch the Gradio app
591
  def build_app():
592
  """
593
  Build and launch the Gradio app.
 
159
 
160
  async def generate_summary_async(bookmark):
161
  async with llm_semaphore:
162
+ await asyncio.get_event_loop().run_in_executor(None, generate_summary, bookmark)
163
 
164
  def generate_summary(bookmark):
165
  """
 
270
 
271
  async def assign_category_async(bookmark):
272
  async with llm_semaphore:
273
+ await asyncio.get_event_loop().run_in_executor(None, assign_category, bookmark)
274
 
275
  def assign_category(bookmark):
276
  """
 
452
  tasks = []
453
  for bookmark in bookmarks_list:
454
  tasks.append(generate_summary_async(bookmark))
455
+ await asyncio.gather(*tasks)
456
+
457
+ tasks = []
458
+ for bookmark in bookmarks_list:
459
  tasks.append(assign_category_async(bookmark))
460
  await asyncio.gather(*tasks)
461
  logger.info("Completed LLM processing of bookmarks")
 
589
 
590
  return message, bookmark_html, gr.update(choices=choices), bookmark_html
591
 
592
+ def delete_selected_bookmarks(selected_indices):
593
+ """
594
+ Delete selected bookmarks and remove their vectors from the FAISS index.
595
+ """
596
+ global bookmarks, faiss_index
597
+ if not selected_indices:
598
+ return "⚠️ No bookmarks selected.", gr.update(choices=[]), display_bookmarks()
599
+
600
+ ids_to_delete = []
601
+ indices_to_delete = []
602
+ for s in selected_indices:
603
+ idx = int(s.split('.')[0]) - 1
604
+ if 0 <= idx < len(bookmarks):
605
+ bookmark_id = bookmarks[idx]['id']
606
+ ids_to_delete.append(bookmark_id)
607
+ indices_to_delete.append(idx)
608
+ logger.info(f"Deleting bookmark at index {idx + 1}")
609
+
610
+ # Remove vectors from FAISS index
611
+ if faiss_index is not None and ids_to_delete:
612
+ faiss_index.remove_ids(np.array(ids_to_delete, dtype=np.int64))
613
+
614
+ # Remove bookmarks from the list (reverse order to avoid index shifting)
615
+ for idx in sorted(indices_to_delete, reverse=True):
616
+ bookmarks.pop(idx)
617
+
618
+ message = "🗑️ Selected bookmarks deleted successfully."
619
+ logger.info(message)
620
+ choices = [f"{i+1}. {bookmark['title']} (Category: {bookmark['category']})"
621
+ for i, bookmark in enumerate(bookmarks)]
622
+
623
+ return message, gr.update(choices=choices), display_bookmarks()
624
+
625
+ def edit_selected_bookmarks_category(selected_indices, new_category):
626
+ """
627
+ Edit category of selected bookmarks.
628
+ """
629
+ if not selected_indices:
630
+ return "⚠️ No bookmarks selected.", gr.update(choices=[]), display_bookmarks()
631
+ if not new_category:
632
+ return "⚠️ No new category selected.", gr.update(choices=[]), display_bookmarks()
633
+
634
+ indices = [int(s.split('.')[0])-1 for s in selected_indices]
635
+ for idx in indices:
636
+ if 0 <= idx < len(bookmarks):
637
+ bookmarks[idx]['category'] = new_category
638
+ logger.info(f"Updated category for bookmark {idx + 1} to {new_category}")
639
+
640
+ message = "✏️ Category updated for selected bookmarks."
641
+ logger.info(message)
642
+
643
+ # Update choices and display
644
+ choices = [f"{i+1}. {bookmark['title']} (Category: {bookmark['category']})"
645
+ for i, bookmark in enumerate(bookmarks)]
646
+
647
+ return message, gr.update(choices=choices), display_bookmarks()
648
+
649
+ def export_bookmarks():
650
+ """
651
+ Export bookmarks to HTML file.
652
+ """
653
+ if not bookmarks:
654
+ logger.warning("No bookmarks to export")
655
+ return "⚠️ No bookmarks to export."
656
+
657
+ try:
658
+ logger.info("Exporting bookmarks to HTML")
659
+ soup = BeautifulSoup("<!DOCTYPE NETSCAPE-Bookmark-file-1><Title>Bookmarks</Title><H1>Bookmarks</H1>", 'html.parser')
660
+ dl = soup.new_tag('DL')
661
+ for bookmark in bookmarks:
662
+ dt = soup.new_tag('DT')
663
+ a = soup.new_tag('A', href=bookmark['url'])
664
+ a.string = bookmark['title']
665
+ dt.append(a)
666
+ dl.append(dt)
667
+ soup.append(dl)
668
+ html_content = str(soup)
669
+ b64 = base64.b64encode(html_content.encode()).decode()
670
+ href = f'data:text/html;base64,{b64}'
671
+ logger.info("Bookmarks exported successfully")
672
+ return f'<a href="{href}" download="bookmarks.html">💾 Download Exported Bookmarks</a>'
673
+ except Exception as e:
674
+ logger.error(f"Error exporting bookmarks: {e}", exc_info=True)
675
+ return "⚠️ Error exporting bookmarks."
676
+
677
+ def chatbot_response(user_query):
678
+ """
679
+ Generate chatbot response using the FAISS index and embeddings.
680
+ """
681
+ if not bookmarks or faiss_index is None:
682
+ logger.warning("No bookmarks available for chatbot")
683
+ return "⚠️ No bookmarks available. Please upload and process your bookmarks first."
684
+
685
+ logger.info(f"Chatbot received query: {user_query}")
686
+
687
+ try:
688
+ # Encode the user query
689
+ query_vector = embedding_model.encode([user_query]).astype('float32')
690
+
691
+ # Search the FAISS index
692
+ k = 5 # Number of results to return
693
+ distances, ids = faiss_index.search(query_vector, k)
694
+ ids = ids.flatten()
695
+
696
+ # Retrieve the bookmarks
697
+ id_to_bookmark = {bookmark['id']: bookmark for bookmark in bookmarks}
698
+ matching_bookmarks = [id_to_bookmark.get(id) for id in ids if id in id_to_bookmark]
699
+
700
+ if not matching_bookmarks:
701
+ return "No relevant bookmarks found for your query."
702
+
703
+ # Format the response
704
+ bookmarks_info = "\n".join([
705
+ f"Title: {bookmark['title']}\nURL: {bookmark['url']}\nSummary: {bookmark['summary']}"
706
+ for bookmark in matching_bookmarks
707
+ ])
708
+
709
+ # Use the LLM via Groq Cloud API to generate a response
710
+ prompt = f"""
711
+ A user asked: "{user_query}"
712
+
713
+ Based on the bookmarks below, provide a helpful answer to the user's query, referencing the relevant bookmarks.
714
+
715
+ Bookmarks:
716
+ {bookmarks_info}
717
+
718
+ Provide a concise and helpful response.
719
+ """
720
+
721
+ retries = 0
722
+ max_retries = 5
723
+ while retries <= max_retries:
724
+ try:
725
+ response = openai.ChatCompletion.create(
726
+ model='llama-3.1-70b-versatile',
727
+ messages=[
728
+ {"role": "user", "content": prompt}
729
+ ],
730
+ max_tokens=500,
731
+ temperature=0.7,
732
+ )
733
+ break # Exit loop if successful
734
+ except openai.error.RateLimitError as e:
735
+ retry_after = extract_retry_after(str(e)) or exponential_backoff(retries)
736
+ logger.warning(f"Rate limit exceeded. Retrying after {retry_after} seconds.")
737
+ time.sleep(retry_after)
738
+ retries += 1
739
+ except Exception as e:
740
+ error_message = f"⚠️ Error processing your query: {str(e)}"
741
+ logger.error(error_message, exc_info=True)
742
+ return error_message
743
+
744
+ answer = response['choices'][0]['message']['content'].strip()
745
+ logger.info("Chatbot response generated using Groq Cloud API")
746
+ return answer
747
+
748
+ except Exception as e:
749
+ error_message = f"⚠️ Error processing your query: {str(e)}"
750
+ logger.error(error_message, exc_info=True)
751
+ return error_message
752
 
 
753
  def build_app():
754
  """
755
  Build and launch the Gradio app.