Ali Abdullah commited on
Commit
dd3a17d
Β·
verified Β·
1 Parent(s): 10d6769

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +307 -305
main.py CHANGED
@@ -1,305 +1,307 @@
1
- import gradio as gr
2
- import os
3
- import sys
4
- from typing import List, Tuple
5
- import time
6
- from datetime import datetime
7
-
8
- # Add the src directory to Python path
9
- sys.path.append(os.path.dirname(os.path.abspath(__file__)))
10
-
11
- from chatbot import RAGChatbot
12
-
13
- class ChatbotUI:
14
- def __init__(self):
15
- """Initialize the Gradio UI for RAG Chatbot"""
16
- print("πŸš€ Initializing Chatbot UI...")
17
- self.chatbot = RAGChatbot()
18
- self.chat_history = []
19
-
20
- def add_url(self, url: str) -> Tuple[str, str]:
21
- """
22
- Add URL to knowledge base
23
- Args:
24
- url: URL to ingest
25
- Returns:
26
- Tuple of (status_message, updated_stats)
27
- """
28
- if not url or not url.strip():
29
- return "❌ Please enter a valid URL", self.get_stats_display()
30
-
31
- url = url.strip()
32
- if not (url.startswith('http://') or url.startswith('https://')):
33
- url = 'https://' + url
34
-
35
- # Show processing message
36
- status_msg = f"πŸ“₯ Processing {url}..."
37
-
38
- try:
39
- result = self.chatbot.ingest_url(url)
40
-
41
- if result['success']:
42
- success_msg = f"""βœ… Successfully added: {result['title']}
43
- πŸ“Š Added {result['chunks_added']} chunks ({result['word_count']} words)
44
- πŸ”— Source: {url}"""
45
- return success_msg, self.get_stats_display()
46
- else:
47
- error_msg = f"❌ Failed to add URL: {result['message']}"
48
- return error_msg, self.get_stats_display()
49
-
50
- except Exception as e:
51
- error_msg = f"❌ Error processing URL: {str(e)}"
52
- return error_msg, self.get_stats_display()
53
-
54
- def chat_response(self, message: str, history: List[List[str]]) -> Tuple[str, List[List[str]]]:
55
- """
56
- Generate chat response
57
- Args:
58
- message: User message
59
- history: Chat history
60
- Returns:
61
- Tuple of (empty_string, updated_history)
62
- """
63
- if not message or not message.strip():
64
- return "", history
65
-
66
- # Get response from chatbot
67
- response_data = self.chatbot.chat(message.strip(), include_sources=True)
68
-
69
- # Format response with sources
70
- formatted_response = self.format_response(response_data)
71
-
72
- # Update history
73
- history.append([message, formatted_response])
74
-
75
- return "", history
76
-
77
- def format_response(self, response_data: dict) -> str:
78
- """Format the chatbot response with sources and timing info"""
79
- response = response_data['response']
80
-
81
- # Add timing information
82
- timing_info = f"\n\n⏱️ *Response time: {response_data['total_time']}s*"
83
-
84
- # Add sources if available
85
- if response_data.get('sources'):
86
- sources_text = "\n\nπŸ“š **Sources:**\n"
87
- for i, source in enumerate(response_data['sources'][:3], 1): # Limit to top 3 sources
88
- score = f"({source['similarity_score']:.3f})" if source['similarity_score'] else ""
89
- sources_text += f"{i}. **{source['title']}** {score}\n"
90
- sources_text += f" {source['snippet']}\n"
91
- sources_text += f" πŸ”— {source['url']}\n\n"
92
-
93
- response += sources_text
94
-
95
- response += timing_info
96
- return response
97
-
98
- def get_stats_display(self) -> str:
99
- """Get formatted knowledge base statistics"""
100
- try:
101
- stats = self.chatbot.get_knowledge_base_stats()
102
-
103
- stats_text = f"""πŸ“Š **Knowledge Base Statistics**
104
-
105
- πŸ—„οΈ **Total Documents:** {stats.get('total_documents', 0)}
106
- 🧠 **AI Model:** {stats.get('model_used', 'Unknown')}
107
- πŸ”€ **Embedding Model:** {stats.get('embedding_model', 'Unknown')}
108
- πŸ“ **Vector Dimension:** {stats.get('index_dimension', 0)}
109
- πŸ“ˆ **Index Fullness:** {stats.get('index_fullness', 0):.1%}
110
-
111
- *Last updated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*"""
112
-
113
- return stats_text
114
-
115
- except Exception as e:
116
- return f"❌ Error getting stats: {str(e)}"
117
-
118
- def clear_knowledge_base(self) -> Tuple[str, str]:
119
- """Clear all documents from knowledge base"""
120
- try:
121
- success = self.chatbot.clear_knowledge_base()
122
- if success:
123
- return "βœ… Knowledge base cleared successfully!", self.get_stats_display()
124
- else:
125
- return "❌ Failed to clear knowledge base", self.get_stats_display()
126
- except Exception as e:
127
- return f"❌ Error clearing knowledge base: {str(e)}", self.get_stats_display()
128
-
129
- def create_interface(self):
130
- """Create and return the Gradio interface"""
131
-
132
- # Custom CSS for better styling
133
- custom_css = """
134
- .gradio-container {
135
- max-width: 1200px !important;
136
- }
137
- .chat-container {
138
- height: 500px !important;
139
- }
140
- .input-container {
141
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
142
- padding: 20px !important;
143
- border-radius: 10px !important;
144
- }
145
- """
146
-
147
- with gr.Blocks(
148
- title="πŸ€– RAG Chatbot",
149
- theme=gr.themes.Soft(),
150
- css=custom_css
151
- ) as interface:
152
-
153
- # Header
154
- gr.Markdown("""
155
- # πŸ€– RAG-Powered AI Chatbot
156
- ### Intelligent Q&A with Web Content Integration
157
-
158
- **How to use:**
159
- 1. πŸ“₯ Add URLs containing articles or content you want the bot to learn from
160
- 2. πŸ’¬ Ask questions about the content - the bot will provide accurate answers with sources
161
- 3. πŸ“Š Monitor your knowledge base statistics in the sidebar
162
- """)
163
-
164
- with gr.Row():
165
- # Main chat area (left side)
166
- with gr.Column(scale=2):
167
- # URL Input Section
168
- gr.Markdown("## πŸ“₯ Add Content to Knowledge Base")
169
- with gr.Row():
170
- url_input = gr.Textbox(
171
- placeholder="Enter URL (e.g., https://medium.com/article-url)",
172
- label="Website URL",
173
- scale=3
174
- )
175
- add_btn = gr.Button("Add URL", variant="primary", scale=1)
176
-
177
- url_status = gr.Markdown(value="", visible=True)
178
-
179
- # Chat Interface
180
- gr.Markdown("## πŸ’¬ Chat with Your Knowledge Base")
181
-
182
- chatbot_interface = gr.Chatbot(
183
- value=[],
184
- height=400,
185
- label="RAG Chatbot",
186
- show_label=True,
187
- container=True,
188
- bubble_full_width=False
189
- )
190
-
191
- with gr.Row():
192
- msg_input = gr.Textbox(
193
- placeholder="Ask a question about your added content...",
194
- label="Your Message",
195
- scale=4,
196
- lines=1
197
- )
198
- send_btn = gr.Button("Send", variant="primary", scale=1)
199
-
200
- # Example questions
201
- gr.Markdown("### πŸ’‘ Example Questions:")
202
- example_questions = [
203
- "What is the main topic of this article?",
204
- "Can you summarize the key points?",
205
- "What are the benefits mentioned?",
206
- "How does this relate to AI/ML?"
207
- ]
208
-
209
- with gr.Row():
210
- for question in example_questions[:2]:
211
- gr.Button(question, size="sm").click(
212
- lambda q=question: (q, ""),
213
- outputs=[msg_input, url_status]
214
- )
215
-
216
- with gr.Row():
217
- for question in example_questions[2:]:
218
- gr.Button(question, size="sm").click(
219
- lambda q=question: (q, ""),
220
- outputs=[msg_input, url_status]
221
- )
222
-
223
- # Sidebar (right side)
224
- with gr.Column(scale=1):
225
- gr.Markdown("## πŸ“Š Knowledge Base")
226
-
227
- stats_display = gr.Markdown(
228
- value=self.get_stats_display(),
229
- label="Statistics"
230
- )
231
-
232
- refresh_stats_btn = gr.Button("πŸ”„ Refresh Stats", variant="secondary")
233
- clear_kb_btn = gr.Button("πŸ—‘οΈ Clear Knowledge Base", variant="stop")
234
-
235
- gr.Markdown("""
236
- ### ℹ️ About
237
- This RAG chatbot uses:
238
- - **Groq API** with Mixtral-8x7B for fast inference
239
- - **Faiss** for vector storage
240
- - **Sentence Transformers** for embeddings
241
- - **Beautiful Soup** for web scraping
242
-
243
- The bot retrieves relevant content and generates accurate answers based on your added sources.
244
-
245
- -Made By Ali Abdullah"""
246
- )
247
-
248
- # Event handlers
249
- add_btn.click(
250
- fn=self.add_url,
251
- inputs=[url_input],
252
- outputs=[url_status, stats_display]
253
- ).then(
254
- lambda: "", # Clear URL input after adding
255
- outputs=[url_input]
256
- )
257
-
258
- send_btn.click(
259
- fn=self.chat_response,
260
- inputs=[msg_input, chatbot_interface],
261
- outputs=[msg_input, chatbot_interface]
262
- )
263
-
264
- msg_input.submit(
265
- fn=self.chat_response,
266
- inputs=[msg_input, chatbot_interface],
267
- outputs=[msg_input, chatbot_interface]
268
- )
269
-
270
- refresh_stats_btn.click(
271
- fn=lambda: self.get_stats_display(),
272
- outputs=[stats_display]
273
- )
274
-
275
- clear_kb_btn.click(
276
- fn=self.clear_knowledge_base,
277
- outputs=[url_status, stats_display]
278
- )
279
-
280
- return interface
281
-
282
- def main():
283
- """Main function to run the Gradio app"""
284
- print("πŸš€ Starting RAG Chatbot UI...")
285
-
286
- try:
287
- # Initialize the UI
288
- ui = ChatbotUI()
289
-
290
- # Create and launch interface
291
- interface = ui.create_interface()
292
-
293
- # Launch with custom settings
294
- interface.launch(
295
- server_name="0.0.0.0", # Allow external access
296
- server_port=int(os.environ.get("PORT", 7860)), # Default Gradio port
297
- share=False # Set to True for public link
298
- )
299
-
300
- except Exception as e:
301
- print(f"❌ Failed to launch the app: {e}")
302
-
303
- if __name__ == "__main__":
304
- main()
305
-
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import sys
4
+ from typing import List, Tuple
5
+ import time
6
+ from datetime import datetime
7
+
8
+ # Add the src directory to Python path
9
+ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
10
+
11
+ from chatbot import RAGChatbot
12
+
13
+ class ChatbotUI:
14
+ def __init__(self):
15
+ """Initialize the Gradio UI for RAG Chatbot"""
16
+ print("πŸš€ Initializing Chatbot UI...")
17
+ self.chatbot = RAGChatbot()
18
+ self.chat_history = []
19
+
20
+ def add_url(self, url: str) -> Tuple[str, str]:
21
+ """
22
+ Add URL to knowledge base
23
+ Args:
24
+ url: URL to ingest
25
+ Returns:
26
+ Tuple of (status_message, updated_stats)
27
+ """
28
+ if not url or not url.strip():
29
+ return "❌ Please enter a valid URL", self.get_stats_display()
30
+
31
+ url = url.strip()
32
+ if not (url.startswith('http://') or url.startswith('https://')):
33
+ url = 'https://' + url
34
+
35
+ # Show processing message
36
+ status_msg = f"πŸ“₯ Processing {url}..."
37
+
38
+ try:
39
+ result = self.chatbot.ingest_url(url)
40
+
41
+ if result['success']:
42
+ success_msg = f"""βœ… Successfully added: {result['title']}
43
+ πŸ“Š Added {result['chunks_added']} chunks ({result['word_count']} words)
44
+ πŸ”— Source: {url}"""
45
+ return success_msg, self.get_stats_display()
46
+ else:
47
+ error_msg = f"❌ Failed to add URL: {result['message']}"
48
+ return error_msg, self.get_stats_display()
49
+
50
+ except Exception as e:
51
+ error_msg = f"❌ Error processing URL: {str(e)}"
52
+ return error_msg, self.get_stats_display()
53
+
54
+ def chat_response(self, message: str, history: List[List[str]]) -> Tuple[str, List[List[str]]]:
55
+ """
56
+ Generate chat response
57
+ Args:
58
+ message: User message
59
+ history: Chat history
60
+ Returns:
61
+ Tuple of (empty_string, updated_history)
62
+ """
63
+ if not message or not message.strip():
64
+ return "", history
65
+
66
+ # Get response from chatbot
67
+ response_data = self.chatbot.chat(message.strip(), include_sources=True)
68
+
69
+ # Format response with sources
70
+ formatted_response = self.format_response(response_data)
71
+
72
+ # Update history
73
+ history.append([message, formatted_response])
74
+
75
+ return "", history
76
+
77
+ def format_response(self, response_data: dict) -> str:
78
+ """Format the chatbot response with sources and timing info"""
79
+ response = response_data['response']
80
+
81
+ # Add timing information
82
+ timing_info = f"\n\n⏱️ *Response time: {response_data['total_time']}s*"
83
+
84
+ # Add sources if available
85
+ if response_data.get('sources'):
86
+ sources_text = "\n\nπŸ“š **Sources:**\n"
87
+ for i, source in enumerate(response_data['sources'][:3], 1): # Limit to top 3 sources
88
+ score = f"({source['similarity_score']:.3f})" if source['similarity_score'] else ""
89
+ sources_text += f"{i}. **{source['title']}** {score}\n"
90
+ sources_text += f" {source['snippet']}\n"
91
+ sources_text += f" πŸ”— {source['url']}\n\n"
92
+
93
+ response += sources_text
94
+
95
+ response += timing_info
96
+ return response
97
+
98
+ def get_stats_display(self) -> str:
99
+ """Get formatted knowledge base statistics"""
100
+ try:
101
+ stats = self.chatbot.get_knowledge_base_stats()
102
+
103
+ stats_text = f"""πŸ“Š **Knowledge Base Statistics**
104
+
105
+ πŸ—„οΈ **Total Documents:** {stats.get('total_documents', 0)}
106
+ 🧠 **AI Model:** {stats.get('model_used', 'Unknown')}
107
+ πŸ”€ **Embedding Model:** {stats.get('embedding_model', 'Unknown')}
108
+ πŸ“ **Vector Dimension:** {stats.get('index_dimension', 0)}
109
+ πŸ“ˆ **Index Fullness:** {stats.get('index_fullness', 0):.1%}
110
+
111
+ *Last updated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*"""
112
+
113
+ return stats_text
114
+
115
+ except Exception as e:
116
+ return f"❌ Error getting stats: {str(e)}"
117
+
118
+ def clear_knowledge_base(self) -> Tuple[str, str]:
119
+ """Clear all documents from knowledge base"""
120
+ try:
121
+ success = self.chatbot.clear_knowledge_base()
122
+ if success:
123
+ return "βœ… Knowledge base cleared successfully!", self.get_stats_display()
124
+ else:
125
+ return "❌ Failed to clear knowledge base", self.get_stats_display()
126
+ except Exception as e:
127
+ return f"❌ Error clearing knowledge base: {str(e)}", self.get_stats_display()
128
+
129
+ def create_interface(self):
130
+ """Create and return the Gradio interface"""
131
+
132
+ # Custom CSS for better styling
133
+ custom_css = """
134
+ .gradio-container {
135
+ max-width: 1200px !important;
136
+ }
137
+ .chat-container {
138
+ height: 500px !important;
139
+ }
140
+ .input-container {
141
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
142
+ padding: 20px !important;
143
+ border-radius: 10px !important;
144
+ }
145
+ """
146
+
147
+ with gr.Blocks(
148
+ title="πŸ€– RAG Chatbot",
149
+ theme=gr.themes.Soft(),
150
+ css=custom_css
151
+ ) as interface:
152
+
153
+ # Header
154
+ gr.Markdown("""
155
+ # πŸ€– RAG-Powered AI Chatbot
156
+ ### Intelligent Q&A with Web Content Integration
157
+
158
+ **How to use:**
159
+ 1. πŸ“₯ Add URLs containing articles or content you want the bot to learn from
160
+ 2. πŸ’¬ Ask questions about the content - the bot will provide accurate answers with sources
161
+ 3. πŸ“Š Monitor your knowledge base statistics in the sidebar
162
+ """)
163
+
164
+ with gr.Row():
165
+ # Main chat area (left side)
166
+ with gr.Column(scale=2):
167
+ # URL Input Section
168
+ gr.Markdown("## πŸ“₯ Add Content to Knowledge Base")
169
+ with gr.Row():
170
+ url_input = gr.Textbox(
171
+ placeholder="Enter URL (e.g., https://medium.com/article-url)",
172
+ label="Website URL",
173
+ scale=3
174
+ )
175
+ add_btn = gr.Button("Add URL", variant="primary", scale=1)
176
+
177
+ url_status = gr.Markdown(value="", visible=True)
178
+
179
+ # Chat Interface
180
+ gr.Markdown("## πŸ’¬ Chat with Your Knowledge Base")
181
+
182
+ chatbot_interface = gr.Chatbot(
183
+ value=[],
184
+ height=400,
185
+ label="RAG Chatbot",
186
+ show_label=True,
187
+ container=True,
188
+ bubble_full_width=False
189
+ )
190
+
191
+ with gr.Row():
192
+ msg_input = gr.Textbox(
193
+ placeholder="Ask a question about your added content...",
194
+ label="Your Message",
195
+ scale=4,
196
+ lines=1
197
+ )
198
+ send_btn = gr.Button("Send", variant="primary", scale=1)
199
+
200
+ # Example questions
201
+ gr.Markdown("### πŸ’‘ Example Questions:")
202
+ example_questions = [
203
+ "What is the main topic of this article?",
204
+ "Can you summarize the key points?",
205
+ "What are the benefits mentioned?",
206
+ "How does this relate to AI/ML?"
207
+ ]
208
+
209
+ with gr.Row():
210
+ for question in example_questions[:2]:
211
+ gr.Button(question, size="sm").click(
212
+ lambda q=question: (q, ""),
213
+ outputs=[msg_input, url_status]
214
+ )
215
+
216
+ with gr.Row():
217
+ for question in example_questions[2:]:
218
+ gr.Button(question, size="sm").click(
219
+ lambda q=question: (q, ""),
220
+ outputs=[msg_input, url_status]
221
+ )
222
+
223
+ # Sidebar (right side)
224
+ with gr.Column(scale=1):
225
+ gr.Markdown("## πŸ“Š Knowledge Base")
226
+
227
+ stats_display = gr.Markdown(
228
+ value=self.get_stats_display(),
229
+ label="Statistics"
230
+ )
231
+
232
+ refresh_stats_btn = gr.Button("πŸ”„ Refresh Stats", variant="secondary")
233
+ clear_kb_btn = gr.Button("πŸ—‘οΈ Clear Knowledge Base", variant="stop")
234
+
235
+ gr.Markdown("""
236
+ ### ℹ️ About
237
+ This RAG chatbot uses:
238
+ - **Groq API** with Mixtral-8x7B for fast inference
239
+ - **Faiss** for vector storage
240
+ - **Sentence Transformers** for embeddings
241
+ - **Beautiful Soup** for web scraping
242
+
243
+ The bot retrieves relevant content and generates accurate answers based on your added sources.
244
+
245
+ -Made By Ali Abdullah"""
246
+ )
247
+
248
+ # Event handlers
249
+ add_btn.click(
250
+ fn=self.add_url,
251
+ inputs=[url_input],
252
+ outputs=[url_status, stats_display]
253
+ ).then(
254
+ lambda: "", # Clear URL input after adding
255
+ outputs=[url_input]
256
+ )
257
+
258
+ send_btn.click(
259
+ fn=self.chat_response,
260
+ inputs=[msg_input, chatbot_interface],
261
+ outputs=[msg_input, chatbot_interface]
262
+ )
263
+
264
+ msg_input.submit(
265
+ fn=self.chat_response,
266
+ inputs=[msg_input, chatbot_interface],
267
+ outputs=[msg_input, chatbot_interface]
268
+ )
269
+
270
+ refresh_stats_btn.click(
271
+ fn=lambda: self.get_stats_display(),
272
+ outputs=[stats_display]
273
+ )
274
+
275
+ clear_kb_btn.click(
276
+ fn=self.clear_knowledge_base,
277
+ outputs=[url_status, stats_display]
278
+ )
279
+
280
+ return interface
281
+
282
+ def main():
283
+ """Main function to run the Gradio app"""
284
+ print("πŸš€ Starting RAG Chatbot UI...")
285
+
286
+ try:
287
+ # Initialize the UI
288
+ ui = ChatbotUI()
289
+
290
+ # Create and launch interface
291
+ interface = ui.create_interface()
292
+
293
+ # Launch with custom settings
294
+ interface.launch(
295
+ server_name="0.0.0.0", # Allow external access
296
+ server_port=int(os.environ.get("PORT", 7860)), # Default Gradio port
297
+ share=False # Set to True for public link
298
+ )
299
+
300
+ except Exception as e:
301
+ print(f"❌ Failed to launch the app: {e}")
302
+
303
+ if __name__ == "__main__":
304
+ main()
305
+ # For Hugging Face Spaces
306
+ ui = ChatbotUI()
307
+ interface = ui.create_interface()