Vamshiboss8055 commited on
Commit
8a3667f
·
verified ·
1 Parent(s): f2b1872

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +538 -0
  2. requirements.txt +5 -0
  3. users_db.json +1 -0
app.py ADDED
@@ -0,0 +1,538 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ from typing import Optional
4
+ from datetime import datetime
5
+ import google.generativeai as genai
6
+ import gradio as gr
7
+ import bcrypt
8
+ from tinydb import TinyDB, Query
9
+
10
+ GEMINI_API_KEY = "AIzaSyBSHcHdbVcvo5IvKDAq2fY1xsWDDb2-JUI"
11
+ MODEL_NAME = "models/gemini-2.5-flash"
12
+ DB_PATH = "users_db.json"
13
+
14
+ # Configure the API
15
+ genai.configure(api_key=GEMINI_API_KEY)
16
+
17
+ # Initialize TinyDB
18
+ db = TinyDB(DB_PATH)
19
+ User = Query()
20
+
21
+ # Global state for current user session
22
+ current_user = {"logged_in": False, "user_data": None}
23
+
24
+ class UserAuthentication:
25
+ """Handle user authentication and database operations"""
26
+
27
+ def __init__(self, db_path: str = DB_PATH):
28
+ self.db = TinyDB(db_path)
29
+
30
+ @staticmethod
31
+ def hash_password(password: str) -> str:
32
+ """Hash password using bcrypt"""
33
+ return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
34
+
35
+ @staticmethod
36
+ def verify_password(password: str, hashed: str) -> bool:
37
+ """Verify password against hash"""
38
+ return bcrypt.checkpw(password.encode('utf-8'), hashed.encode('utf-8'))
39
+
40
+ def user_exists(self, email: str) -> bool:
41
+ """Check if user already exists"""
42
+ return self.db.search(User.email == email) != []
43
+
44
+ def signup(self, username: str, email: str, password: str, phone: str = "") -> tuple[bool, str]:
45
+ """Register a new user"""
46
+ try:
47
+ if not username or not email or not password:
48
+ return False, "All fields are required"
49
+
50
+ if self.user_exists(email):
51
+ return False, "Email already registered"
52
+
53
+ if len(password) < 6:
54
+ return False, "Password must be at least 6 characters"
55
+
56
+ hashed_password = self.hash_password(password)
57
+
58
+ user_data = {
59
+ "username": username,
60
+ "email": email,
61
+ "password": hashed_password,
62
+ "phone": phone,
63
+ "created_at": datetime.now().isoformat(),
64
+ "last_login": None
65
+ }
66
+
67
+ self.db.insert(user_data)
68
+ return True, f"✓ Account created successfully! Welcome, {username}!"
69
+
70
+ except Exception as e:
71
+ return False, f"Signup error: {str(e)}"
72
+
73
+ def login(self, email: str, password: str) -> tuple[bool, str, Optional[dict]]:
74
+ """Authenticate user"""
75
+ try:
76
+ if not email or not password:
77
+ return False, "Email and password required", None
78
+
79
+ users = self.db.search(User.email == email)
80
+
81
+ if not users:
82
+ return False, "Email not found", None
83
+
84
+ user = users[0]
85
+
86
+ if not self.verify_password(password, user['password']):
87
+ return False, "Incorrect password", None
88
+
89
+ # Update last login
90
+ self.db.update(
91
+ {'last_login': datetime.now().isoformat()},
92
+ User.email == email
93
+ )
94
+
95
+ return True, f"✓ Login successful! Welcome, {user['username']}!", user
96
+
97
+ except Exception as e:
98
+ return False, f"Login error: {str(e)}", None
99
+
100
+ def get_user_profile(self, email: str) -> Optional[dict]:
101
+ """Get user profile"""
102
+ users = self.db.search(User.email == email)
103
+ if users:
104
+ user = users[0].copy()
105
+ user.pop('password', None) # Remove password from profile
106
+ return user
107
+ return None
108
+
109
+ class GeminiChatBot:
110
+ """Main chatbot class with context management and multiple modes"""
111
+
112
+ def __init__(self, model_name: str = MODEL_NAME):
113
+ self.model = genai.GenerativeModel(model_name)
114
+ self.conversation_history = []
115
+ self.chat_session = None
116
+ self.system_prompt = ""
117
+
118
+ def set_system_prompt(self, mode: str):
119
+ """Set system prompt based on chatbot mode"""
120
+ prompts = {
121
+ "general": """You are a helpful, accurate, and friendly AI assistant.
122
+ Provide clear, concise, and informative responses.
123
+ Always be honest about limitations and uncertainty.""",
124
+
125
+ "technical": """You are an expert technical support assistant.
126
+ Provide detailed technical solutions, code examples, and best practices.
127
+ When unsure, ask clarifying questions. Always suggest verification steps.""",
128
+
129
+ "creative": """You are a creative writing assistant with strong storytelling abilities.
130
+ Help users with creative writing, brainstorming, and narrative development.
131
+ Provide engaging and imaginative content.""",
132
+
133
+ "educational": """You are an educational tutor. Explain concepts clearly,
134
+ break down complex topics, and provide examples.
135
+ Encourage learning and ask clarifying questions.""",
136
+
137
+ "medical": """You are a medical information assistant.
138
+ Provide accurate health information and general guidance.
139
+ Always recommend consulting healthcare professionals for serious concerns.
140
+ Do NOT provide emergency medical advice."""
141
+ }
142
+ self.system_prompt = prompts.get(mode, prompts["general"])
143
+
144
+ def chat(self, user_message: str, mode: str = "general", temperature: float = 0.7) -> str:
145
+ """Generate response using Gemini with context"""
146
+ try:
147
+ self.set_system_prompt(mode)
148
+
149
+ # Build messages with system context
150
+ messages = [
151
+ {"role": "user", "parts": [f"[SYSTEM: {self.system_prompt}]\n\n{user_message}"]}
152
+ ]
153
+
154
+ # Add conversation history for context (last 5 exchanges)
155
+ if self.conversation_history:
156
+ history_context = "\n".join([
157
+ f"Previous: {msg}"
158
+ for msg in self.conversation_history[-5:]
159
+ ])
160
+ full_message = f"[Conversation Context]\n{history_context}\n\n[New Message]\n{user_message}"
161
+ else:
162
+ full_message = user_message
163
+
164
+ # Generate response
165
+ response = self.model.generate_content(
166
+ full_message,
167
+ generation_config=genai.types.GenerationConfig(
168
+ temperature=temperature,
169
+ top_p=0.95,
170
+ top_k=40
171
+ )
172
+ )
173
+
174
+ bot_response = response.text
175
+
176
+ # Store in history
177
+ self.conversation_history.append(f"User: {user_message[:100]}...")
178
+ self.conversation_history.append(f"Bot: {bot_response[:100]}...")
179
+
180
+ return bot_response
181
+
182
+ except Exception as e:
183
+ return f"Error: {str(e)}\n\nMake sure your API key is valid. Get it from: https://aistudio.google.com/app/apikey"
184
+
185
+ # Initialize chatbot
186
+ chatbot = GeminiChatBot()
187
+
188
+ # Gradio Interface Functions
189
+ def clear_history():
190
+ """Clear conversation history"""
191
+ chatbot.conversation_history = []
192
+ return [], ""
193
+
194
+ def export_chat(chat_history: list) -> str:
195
+ """Export chat as JSON"""
196
+ if not chat_history:
197
+ return "No chat history to export"
198
+
199
+ export_data = {
200
+ "timestamp": datetime.now().isoformat(),
201
+ "conversation": chat_history
202
+ }
203
+ return json.dumps(export_data, indent=2)
204
+
205
+ # Initialize authentication system
206
+ auth_system = UserAuthentication(DB_PATH)
207
+
208
+ # Create demo account if it doesn't exist
209
+ demo_email = "demo@example.com"
210
+ if not auth_system.user_exists(demo_email):
211
+ auth_system.signup("Demo User", demo_email, "password123")
212
+ print("✅ Demo account created successfully!")
213
+ print(" Email: demo@example.com")
214
+ print(" Password: password123")
215
+
216
+ # ===== AUTHENTICATION FUNCTIONS =====
217
+ def signup_user(username: str, email: str, password: str, confirm_password: str) -> tuple[str, str]:
218
+ """Handle user signup"""
219
+ if not password or password != confirm_password:
220
+ return "❌ Passwords do not match!", ""
221
+
222
+ success, message = auth_system.signup(username, email, password)
223
+ if success:
224
+ return "✅ " + message, ""
225
+ else:
226
+ return "❌ " + message, ""
227
+
228
+ def login_user(email: str, password: str) -> tuple[str, str, bool]:
229
+ """Handle user login"""
230
+ success, message, user = auth_system.login(email, password)
231
+ if success:
232
+ current_user["logged_in"] = True
233
+ current_user["user_data"] = user
234
+ username = user['username'] if user else ""
235
+ return "✅ " + message, username, True
236
+ else:
237
+ return "❌ " + message, "", False
238
+
239
+ def logout_user() -> None:
240
+ """Handle user logout"""
241
+ current_user["logged_in"] = False
242
+ current_user["user_data"] = None
243
+ chatbot.conversation_history = []
244
+
245
+ # ===== CHAT FUNCTIONS WITH USER SESSION =====
246
+ def respond_authenticated(message: str, chat_history: list, mode: str, temperature: float):
247
+ """Respond to user message (only when authenticated)"""
248
+ if not current_user["logged_in"]:
249
+ return "", chat_history
250
+
251
+ response = chatbot.chat(message, mode=mode, temperature=temperature)
252
+ chat_history.append({"role": "user", "content": message})
253
+ chat_history.append({"role": "assistant", "content": response})
254
+ return "", chat_history
255
+
256
+ def get_current_username() -> str:
257
+ """Get currently logged-in username"""
258
+ if current_user["logged_in"] and current_user["user_data"]:
259
+ return current_user["user_data"].get("username", "User")
260
+ return "Guest"
261
+
262
+ # Create Unified Gradio Application
263
+ with gr.Blocks(title="Nexus ChatBot", theme=gr.themes.Soft()) as demo:
264
+ # State to track if user is logged in
265
+ auth_state = gr.State(value=False)
266
+
267
+ gr.Markdown("""
268
+ # 🤖 Nexus Intelligent ChatBot
269
+
270
+ Your Intelligent AI Assistant powered by Google's Gemini AI
271
+ """)
272
+
273
+ # AUTHENTICATION SECTION (shown when not logged in)
274
+ with gr.Group(visible=True) as auth_section:
275
+ gr.Markdown("### 🔐 Authentication")
276
+
277
+ with gr.Tabs():
278
+ # LOGIN TAB
279
+ with gr.TabItem("🔐 Login"):
280
+ gr.Markdown("#### Sign In to Your Account")
281
+
282
+ with gr.Column():
283
+ login_email = gr.Textbox(
284
+ label="Email",
285
+ placeholder="Enter your email",
286
+ type="text"
287
+ )
288
+ login_password = gr.Textbox(
289
+ label="Password",
290
+ placeholder="Enter your password",
291
+ type="password"
292
+ )
293
+ login_msg = gr.Textbox(
294
+ label="Status",
295
+ interactive=False,
296
+ visible=False
297
+ )
298
+
299
+ login_btn = gr.Button("🔓 Login", variant="primary", size="lg")
300
+
301
+ # Success notification
302
+ login_popup = gr.HTML(
303
+ value="",
304
+ visible=False
305
+ )
306
+
307
+ gr.Markdown("---")
308
+ gr.Markdown("""
309
+ **📌 Demo Account Available:**
310
+ - Email: `demo@example.com`
311
+ - Password: `password123`
312
+
313
+ Or create a new account in the Sign Up tab!
314
+ """)
315
+
316
+ # SIGNUP TAB
317
+ with gr.TabItem("📝 Sign Up"):
318
+ gr.Markdown("#### Create a New Account")
319
+
320
+ with gr.Column():
321
+ signup_username = gr.Textbox(
322
+ label="Username",
323
+ placeholder="Choose a username",
324
+ type="text"
325
+ )
326
+ signup_email = gr.Textbox(
327
+ label="Email",
328
+ placeholder="Enter your email",
329
+ type="text"
330
+ )
331
+ signup_password = gr.Textbox(
332
+ label="Password",
333
+ placeholder="Create a password (min 6 chars)",
334
+ type="password"
335
+ )
336
+ signup_confirm = gr.Textbox(
337
+ label="Confirm Password",
338
+ placeholder="Confirm your password",
339
+ type="password"
340
+ )
341
+ signup_msg = gr.Textbox(
342
+ label="✅ Status",
343
+ interactive=False,
344
+ visible=False
345
+ )
346
+
347
+ signup_btn = gr.Button("✍️ Sign Up", variant="primary", size="lg")
348
+
349
+ # Success notification
350
+ success_popup = gr.HTML(
351
+ value="",
352
+ visible=False
353
+ )
354
+
355
+ # CHAT SECTION (shown when logged in)
356
+ with gr.Group(visible=False) as chat_section:
357
+ # User info bar
358
+ with gr.Row():
359
+ with gr.Column(scale=4):
360
+ gr.Markdown("### 💬 Chat Interface")
361
+ with gr.Column(scale=1):
362
+ current_user_display = gr.Textbox(
363
+ label="👤 Logged In As",
364
+ value=get_current_username(),
365
+ interactive=False
366
+ )
367
+
368
+ with gr.Row():
369
+ with gr.Column(scale=3):
370
+ chatbot_ui = gr.Chatbot(
371
+ label="💬 Chat History",
372
+ height=500,
373
+ show_label=True
374
+ )
375
+
376
+ with gr.Column(scale=1):
377
+ gr.Markdown("### ⚙️ Settings")
378
+
379
+ mode = gr.Radio(
380
+ choices=["general", "technical", "creative", "educational", "medical"],
381
+ value="general",
382
+ label="Chat Mode",
383
+ info="Select conversation style"
384
+ )
385
+
386
+ temperature = gr.Slider(
387
+ minimum=0,
388
+ maximum=2,
389
+ value=0.7,
390
+ step=0.1,
391
+ label="Creativity",
392
+ info="Higher = more creative, Lower = focused"
393
+ )
394
+
395
+ with gr.Row():
396
+ msg_input = gr.Textbox(
397
+ placeholder="Type your message here...",
398
+ label="Your Message",
399
+ lines=2
400
+ )
401
+
402
+ with gr.Row():
403
+ send_btn = gr.Button("✉️ Send", variant="primary", scale=2)
404
+ clear_btn = gr.Button("🗑️ Clear Chat", scale=1)
405
+ export_btn = gr.Button("📥 Export", scale=1)
406
+ logout_btn = gr.Button("🚪 Logout", variant="stop", scale=1)
407
+
408
+ export_output = gr.Textbox(
409
+ label="📋 Exported Chat (JSON)",
410
+ interactive=False,
411
+ visible=False
412
+ )
413
+
414
+ gr.Markdown("""
415
+ ### 📝 Chat Modes:
416
+ - **General**: Everyday questions and assistance
417
+ - **Technical**: Code help and tech support
418
+ - **Creative**: Storytelling and creative writing
419
+ - **Educational**: Learning and explanations
420
+ - **Medical**: Health information
421
+ """)
422
+
423
+ # === EVENT HANDLERS ===
424
+
425
+ # Login handler
426
+ def handle_login(email: str, password: str):
427
+ success, message, user = auth_system.login(email, password)
428
+ if success:
429
+ current_user["logged_in"] = True
430
+ current_user["user_data"] = user
431
+ username = user['username'] if user else ""
432
+ success_html = f'<div style="background-color: #ccffcc; border: 2px solid #00cc00; padding: 15px; border-radius: 5px; color: #009900; font-weight: bold; text-align: center; font-size: 18px;">✅ {message}<br><small>Redirecting to chat...</small></div>'
433
+ return (
434
+ success_html,
435
+ gr.update(visible=False), # Hide auth section
436
+ gr.update(visible=True), # Show chat section
437
+ username
438
+ )
439
+ else:
440
+ error_html = f'<div style="background-color: #ffcccc; border: 2px solid #ff0000; padding: 15px; border-radius: 5px; color: #cc0000; font-weight: bold;">❌ {message}</div>'
441
+ return error_html, gr.update(visible=True), gr.update(visible=False), ""
442
+
443
+ # Signup handler
444
+ def handle_signup(username: str, email: str, password: str, confirm_password: str):
445
+ if not password or password != confirm_password:
446
+ error_html = '<div style="background-color: #ffcccc; border: 2px solid #ff0000; padding: 15px; border-radius: 5px; color: #cc0000; font-weight: bold;">❌ Passwords do not match!</div>'
447
+ return "❌ Passwords do not match!", error_html, gr.update(visible=True)
448
+
449
+ success, message = auth_system.signup(username, email, password)
450
+ if success:
451
+ success_html = f'<div style="background-color: #ccffcc; border: 2px solid #00cc00; padding: 15px; border-radius: 5px; color: #009900; font-weight: bold; text-align: center; font-size: 18px;">✅ {message}<br><small>You can now login with your email and password</small></div>'
452
+ return message, success_html, gr.update(visible=True)
453
+ else:
454
+ error_html = f'<div style="background-color: #ffcccc; border: 2px solid #ff0000; padding: 15px; border-radius: 5px; color: #cc0000; font-weight: bold;">❌ {message}</div>'
455
+ return message, error_html, gr.update(visible=True)
456
+
457
+ # Logout handler
458
+ def handle_logout():
459
+ current_user["logged_in"] = False
460
+ current_user["user_data"] = None
461
+ chatbot.conversation_history = []
462
+ return (
463
+ gr.update(visible=True), # Show auth section
464
+ gr.update(visible=False), # Hide chat section
465
+ "", # Clear message
466
+ [], # Clear chat history
467
+ )
468
+
469
+ # Login click event
470
+ login_btn.click(
471
+ handle_login,
472
+ inputs=[login_email, login_password],
473
+ outputs=[login_popup, auth_section, chat_section, current_user_display]
474
+ )
475
+
476
+ # Signup click event
477
+ signup_btn.click(
478
+ handle_signup,
479
+ inputs=[signup_username, signup_email, signup_password, signup_confirm],
480
+ outputs=[signup_msg, success_popup, success_popup]
481
+ )
482
+
483
+ # Chat send button
484
+ send_btn.click(
485
+ respond_authenticated,
486
+ inputs=[msg_input, chatbot_ui, mode, temperature],
487
+ outputs=[msg_input, chatbot_ui]
488
+ )
489
+
490
+ # Chat input submit (Enter key)
491
+ msg_input.submit(
492
+ respond_authenticated,
493
+ inputs=[msg_input, chatbot_ui, mode, temperature],
494
+ outputs=[msg_input, chatbot_ui]
495
+ )
496
+
497
+ # Clear chat
498
+ clear_btn.click(
499
+ clear_history,
500
+ outputs=[chatbot_ui, msg_input]
501
+ )
502
+
503
+ # Export chat
504
+ def get_and_show_export(chat_history):
505
+ return export_chat(chat_history), gr.update(visible=True)
506
+
507
+ export_btn.click(
508
+ get_and_show_export,
509
+ inputs=[chatbot_ui],
510
+ outputs=[export_output, export_output]
511
+ )
512
+
513
+ # Logout
514
+ logout_btn.click(
515
+ handle_logout,
516
+ outputs=[auth_section, chat_section, login_popup, chatbot_ui]
517
+ )
518
+
519
+ # Main application logic
520
+ if __name__ == "__main__":
521
+ """
522
+ Start the Gradio application
523
+ - Authentication page (Login/Sign Up) appears first
524
+ - After successful login, chat interface opens automatically
525
+ - Logout returns to authentication
526
+ """
527
+ print("🚀 Starting Nexus ChatBot Application...")
528
+ print("📍 Opening Authentication Page...")
529
+ print("\n💡 Demo Account for Testing:")
530
+ print(" Email: demo@example.com")
531
+ print(" Password: password123")
532
+ print("\n✨ Features:")
533
+ print(" • Secure login and registration")
534
+ print(" • Multiple chat modes (general, technical, creative, educational, medical)")
535
+ print(" • Export conversations")
536
+ print(" • Powered by Google's Gemini AI")
537
+
538
+ demo.launch(share=False)
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ gradio==4.36.0
2
+ google-generativeai==0.3.0
3
+ requests==2.31.0
4
+ tinydb==4.8.0
5
+ bcrypt==4.1.1
users_db.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"_default": {"1": {"username": "Demo User", "email": "demo@example.com", "password": "$2b$12$Al4KJljFpNXQtUsUmrNZpewDir/UOZvRav4xvpateTTGNrBqS7eFC", "phone": "", "created_at": "2026-02-12T22:17:46.607542", "last_login": null}, "2": {"username": "vamshi.namani", "email": "vamshi.namani@gmail.com", "password": "$2b$12$..QroxmItC2dFZLtGnK4IegNmsj5Q1W.UP2Hqq9tc2lM3VxJoJKhi", "phone": "", "created_at": "2026-02-12T22:18:17.378345", "last_login": "2026-02-12T22:18:50.741228"}, "3": {"username": "vamshi.namani1@gmail.com", "email": "vamshi.namani1@gmail.com", "password": "$2b$12$xfUJOu0lXG2T6wGt8qqDC.x4B6ygdfDXWcLncwDIJEoDMUtQfr1Mu", "phone": "", "created_at": "2026-02-12T22:22:01.302731", "last_login": "2026-02-12T22:23:01.029272"}}}