JaweriaGenAI commited on
Commit
1bb9233
Β·
verified Β·
1 Parent(s): 43a4b95

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +289 -94
app.py CHANGED
@@ -9,6 +9,7 @@ import base64
9
  import whisper
10
  import uuid
11
  import json
 
12
  from openai import OpenAI
13
 
14
  # Load Whisper model
@@ -27,105 +28,299 @@ CHAT_HISTORY_DIR = "chat_history"
27
  os.makedirs(CHAT_HISTORY_DIR, exist_ok=True)
28
 
29
  def extract_text_from_file(file):
30
- name = file.name if hasattr(file, "name") else file
31
- ext = os.path.splitext(name)[1].lower()
32
-
33
- if ext == ".pdf":
34
- with pdfplumber.open(file) as pdf:
35
- text = "\n".join(page.extract_text() or "" for page in pdf.pages)
36
- elif ext == ".docx":
37
- doc = docx.Document(file)
38
- text = "\n".join(p.text for p in doc.paragraphs)
39
- elif ext == ".xlsx":
40
- df = pd.read_excel(file)
41
- text = df.to_string()
42
- elif ext in [".png", ".jpg", ".jpeg"]:
43
- img = Image.open(file)
44
- buffer = BytesIO()
45
- img.save(buffer, format="PNG")
46
- encoded = base64.b64encode(buffer.getvalue()).decode("utf-8")
47
- text = f"[Image uploaded: data:image/png;base64,{encoded[:100]}... (truncated)]"
48
- else:
49
- text = file.read().decode("utf-8", errors="ignore")
50
-
51
- return text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
  def transcribe_audio(audio_path):
54
- result = whisper_model.transcribe(audio_path)
55
- return result["text"]
 
 
 
 
 
 
56
 
57
  def generate_reply(history):
58
- messages = [{"role": "system", "content": "You are a helpful assistant."}]
59
- for user_msg, bot_msg in history:
60
- messages.append({"role": "user", "content": user_msg})
61
- messages.append({"role": "assistant", "content": bot_msg})
62
-
63
- response = client.chat.completions.create(
64
- model="llama3-8b-8192",
65
- messages=messages,
66
- temperature=0.7
67
- )
68
- return response.choices[0].message.content
69
-
70
- def respond(message, history):
71
- reply = generate_reply(history + [[message, ""]])
72
- history.append([message, reply])
73
- return history, ""
74
-
75
- def handle_file_upload(file, message):
76
- if file is None:
77
- return message
78
- file_content = extract_text_from_file(file)
79
- return f"{message}\n\n--- File Content Start ---\n{file_content}\n--- File Content End ---"
80
-
81
- def handle_audio_upload(audio, message):
82
- if audio is None:
83
- return message
84
- transcription = transcribe_audio(audio)
85
- return f"{message}\n\n--- Transcription ---\n{transcription}"
86
-
87
- def save_chat(history):
88
- chat_id = str(uuid.uuid4())
89
- path = os.path.join(CHAT_HISTORY_DIR, f"{chat_id}.json")
90
- with open(path, "w", encoding="utf-8") as f:
91
- json.dump(history, f, ensure_ascii=False, indent=2)
92
- return f"Chat saved as {chat_id}.json"
93
-
94
- def load_chat(file):
95
- if file is None:
96
- return [], ""
97
- path = file.name
98
- with open(path, "r", encoding="utf-8") as f:
99
- history = json.load(f)
100
- return history, ""
101
-
102
- def reset_chat():
103
- return [], ""
104
-
105
- with gr.Blocks(css="body { background-color: white; color: black }") as demo:
106
- gr.Markdown("<h1 style='text-align: center;'>🧠 Neobot</h1>")
107
- chatbot = gr.Chatbot(label="Chat", elem_id="chatbox", height=450)
108
- history = gr.State([])
109
 
110
- with gr.Row():
111
- txt = gr.Textbox(placeholder="Type a message or edit file/transcription content...", scale=5, show_label=False)
112
- send_btn = gr.Button("Send", scale=1)
 
 
 
 
 
 
113
 
114
- with gr.Row():
115
- upload_btn = gr.File(label="πŸ“Ž Upload File", file_types=[".pdf", ".docx", ".txt", ".xlsx", ".png", ".jpg", ".jpeg"])
116
- audio_in = gr.Audio(label="πŸŽ™οΈ Upload Audio", type="filepath")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  with gr.Row():
119
- save_btn = gr.Button("πŸ’Ύ Save Chat")
120
- new_btn = gr.Button("πŸ†• New Chat")
121
- load_btn = gr.File(label="πŸ“‚ Load Chat", file_types=[".json"])
122
-
123
- # Events
124
- send_btn.click(respond, [txt, history], [chatbot, txt])
125
- upload_btn.change(handle_file_upload, [upload_btn, txt], txt)
126
- audio_in.change(handle_audio_upload, [audio_in, txt], txt)
127
- save_btn.click(lambda h: gr.Textbox.update(value=save_chat(h)), [history])
128
- load_btn.change(load_chat, [load_btn], [history, txt])
129
- new_btn.click(reset_chat, outputs=[history, txt, chatbot])
130
-
131
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  import whisper
10
  import uuid
11
  import json
12
+ from datetime import datetime
13
  from openai import OpenAI
14
 
15
  # Load Whisper model
 
28
  os.makedirs(CHAT_HISTORY_DIR, exist_ok=True)
29
 
30
  def extract_text_from_file(file):
31
+ """Extract text content from various file types"""
32
+ try:
33
+ if file is None:
34
+ return ""
35
+
36
+ name = file.name if hasattr(file, "name") else str(file)
37
+ ext = os.path.splitext(name)[1].lower()
38
+
39
+ if ext == ".pdf":
40
+ with pdfplumber.open(file) as pdf:
41
+ text = "\n".join(page.extract_text() or "" for page in pdf.pages)
42
+ elif ext == ".docx":
43
+ doc = docx.Document(file)
44
+ text = "\n".join(p.text for p in doc.paragraphs)
45
+ elif ext == ".xlsx" or ext == ".xls":
46
+ df = pd.read_excel(file)
47
+ text = df.to_string()
48
+ elif ext == ".csv":
49
+ df = pd.read_csv(file)
50
+ text = df.to_string()
51
+ elif ext in [".png", ".jpg", ".jpeg", ".gif", ".bmp"]:
52
+ img = Image.open(file)
53
+ # For images, we'll include a description and base64 data
54
+ text = f"[Image uploaded: {name}]\nImage format: {img.format}\nImage size: {img.size}\nImage mode: {img.mode}"
55
+ elif ext in [".txt", ".md", ".py", ".js", ".html", ".css", ".json"]:
56
+ with open(file, 'r', encoding='utf-8', errors='ignore') as f:
57
+ text = f.read()
58
+ else:
59
+ # Try to read as text file
60
+ try:
61
+ with open(file, 'r', encoding='utf-8', errors='ignore') as f:
62
+ text = f.read()
63
+ except:
64
+ text = f"[File uploaded: {name}] - Unable to extract text content"
65
+
66
+ return text
67
+ except Exception as e:
68
+ return f"Error processing file: {str(e)}"
69
 
70
  def transcribe_audio(audio_path):
71
+ """Transcribe audio file using Whisper"""
72
+ try:
73
+ if audio_path is None:
74
+ return ""
75
+ result = whisper_model.transcribe(audio_path)
76
+ return result["text"]
77
+ except Exception as e:
78
+ return f"Error transcribing audio: {str(e)}"
79
 
80
  def generate_reply(history):
81
+ """Generate AI reply using the chat history"""
82
+ try:
83
+ messages = [{"role": "system", "content": "You are a helpful assistant. When users upload files or audio, acknowledge the content and provide relevant responses based on the uploaded material."}]
84
+
85
+ for user_msg, bot_msg in history:
86
+ if user_msg:
87
+ messages.append({"role": "user", "content": user_msg})
88
+ if bot_msg:
89
+ messages.append({"role": "assistant", "content": bot_msg})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
+ response = client.chat.completions.create(
92
+ model="llama3-8b-8192",
93
+ messages=messages,
94
+ temperature=0.7,
95
+ max_tokens=2048
96
+ )
97
+ return response.choices[0].message.content
98
+ except Exception as e:
99
+ return f"Error generating response: {str(e)}"
100
 
101
+ def process_message_with_files(message, file_upload, audio_upload, history):
102
+ """Process user message along with any uploaded files or audio"""
103
+ full_message = message if message else ""
104
+
105
+ # Process uploaded file
106
+ if file_upload is not None:
107
+ file_content = extract_text_from_file(file_upload)
108
+ if file_content:
109
+ file_name = file_upload.name if hasattr(file_upload, 'name') else 'uploaded_file'
110
+ full_message += f"\n\nπŸ“Ž **File Upload: {file_name}**\n```\n{file_content}\n```"
111
+
112
+ # Process uploaded audio
113
+ if audio_upload is not None:
114
+ transcription = transcribe_audio(audio_upload)
115
+ if transcription:
116
+ full_message += f"\n\nπŸŽ™οΈ **Audio Transcription:**\n{transcription}"
117
+
118
+ if not full_message.strip():
119
+ return history, "", None, None, "Please enter a message or upload a file/audio."
120
+
121
+ # Generate AI response
122
+ reply = generate_reply(history + [[full_message, ""]])
123
+
124
+ # Update history
125
+ new_history = history + [[full_message, reply]]
126
+
127
+ return new_history, "", None, None, ""
128
+
129
+ def save_chat_history(history):
130
+ """Save chat history to a JSON file"""
131
+ try:
132
+ if not history:
133
+ return "No chat history to save."
134
+
135
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
136
+ chat_id = f"chat_{timestamp}_{str(uuid.uuid4())[:8]}"
137
+ filename = f"{chat_id}.json"
138
+ filepath = os.path.join(CHAT_HISTORY_DIR, filename)
139
+
140
+ chat_data = {
141
+ "timestamp": datetime.now().isoformat(),
142
+ "chat_id": chat_id,
143
+ "history": history
144
+ }
145
+
146
+ with open(filepath, "w", encoding="utf-8") as f:
147
+ json.dump(chat_data, f, ensure_ascii=False, indent=2)
148
+
149
+ return f"βœ… Chat saved successfully as: {filename}"
150
+ except Exception as e:
151
+ return f"❌ Error saving chat: {str(e)}"
152
 
153
+ def load_chat_history(file_upload):
154
+ """Load chat history from a JSON file"""
155
+ try:
156
+ if file_upload is None:
157
+ return [], "Please select a chat file to load."
158
+
159
+ with open(file_upload.name, "r", encoding="utf-8") as f:
160
+ chat_data = json.load(f)
161
+
162
+ # Handle both old and new format
163
+ if isinstance(chat_data, list):
164
+ history = chat_data
165
+ else:
166
+ history = chat_data.get("history", [])
167
+
168
+ return history, f"βœ… Chat loaded successfully from: {os.path.basename(file_upload.name)}"
169
+ except Exception as e:
170
+ return [], f"❌ Error loading chat: {str(e)}"
171
+
172
+ def clear_chat():
173
+ """Clear the current chat"""
174
+ return [], "Chat cleared."
175
+
176
+ def get_saved_chats():
177
+ """Get list of saved chat files"""
178
+ try:
179
+ files = [f for f in os.listdir(CHAT_HISTORY_DIR) if f.endswith('.json')]
180
+ files.sort(reverse=True) # Most recent first
181
+ return files[:10] # Return last 10 chats
182
+ except:
183
+ return []
184
+
185
+ # Custom CSS for better styling
186
+ custom_css = """
187
+ .gradio-container {
188
+ max-width: 1200px !important;
189
+ margin: auto !important;
190
+ }
191
+ .chat-container {
192
+ height: 500px !important;
193
+ }
194
+ .upload-area {
195
+ border: 2px dashed #ccc !important;
196
+ border-radius: 10px !important;
197
+ padding: 20px !important;
198
+ text-align: center !important;
199
+ }
200
+ .button-row {
201
+ display: flex !important;
202
+ gap: 10px !important;
203
+ justify-content: center !important;
204
+ }
205
+ """
206
+
207
+ # Create the Gradio interface
208
+ with gr.Blocks(css=custom_css, title="🧠 Neobot - Advanced Chatbot") as demo:
209
+ gr.Markdown("""
210
+ # 🧠 Neobot - Advanced AI Chatbot
211
+
212
+ **Features:**
213
+ - πŸ’¬ Natural conversation with AI
214
+ - πŸ“Ž Upload and process various file types (PDF, DOCX, TXT, CSV, Excel, Images)
215
+ - πŸŽ™οΈ Audio transcription and processing
216
+ - πŸ’Ύ Save and load chat conversations
217
+ - πŸ†• Start new conversations anytime
218
+ """)
219
+
220
+ # Chat interface
221
+ chatbot = gr.Chatbot(
222
+ label="Chat History",
223
+ elem_id="chatbox",
224
+ height=500,
225
+ show_copy_button=True,
226
+ bubble_full_width=False
227
+ )
228
+
229
+ # Message input area
230
  with gr.Row():
231
+ message_input = gr.Textbox(
232
+ placeholder="Type your message here...",
233
+ scale=4,
234
+ show_label=False,
235
+ container=False
236
+ )
237
+ send_button = gr.Button("Send πŸ“€", scale=1, variant="primary")
238
+
239
+ # File upload area
240
+ with gr.Row():
241
+ with gr.Column(scale=1):
242
+ file_upload = gr.File(
243
+ label="πŸ“Ž Upload File",
244
+ file_types=[".pdf", ".docx", ".txt", ".xlsx", ".xls", ".csv", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".py", ".js", ".html", ".css", ".json", ".md"],
245
+ elem_classes="upload-area"
246
+ )
247
+ with gr.Column(scale=1):
248
+ audio_upload = gr.Audio(
249
+ label="πŸŽ™οΈ Upload Audio",
250
+ type="filepath",
251
+ elem_classes="upload-area"
252
+ )
253
+
254
+ # Control buttons
255
+ with gr.Row(elem_classes="button-row"):
256
+ save_button = gr.Button("πŸ’Ύ Save Chat", variant="secondary")
257
+ clear_button = gr.Button("πŸ†• New Chat", variant="secondary")
258
+
259
+ with gr.Row():
260
+ load_file = gr.File(
261
+ label="πŸ“‚ Load Saved Chat",
262
+ file_types=[".json"]
263
+ )
264
+
265
+ # Status message
266
+ status_message = gr.Textbox(
267
+ label="Status",
268
+ interactive=False,
269
+ visible=True
270
+ )
271
+
272
+ # State management
273
+ chat_history = gr.State([])
274
+
275
+ # Event handlers
276
+ send_button.click(
277
+ fn=process_message_with_files,
278
+ inputs=[message_input, file_upload, audio_upload, chat_history],
279
+ outputs=[chat_history, message_input, file_upload, audio_upload, status_message]
280
+ ).then(
281
+ fn=lambda history: history,
282
+ inputs=[chat_history],
283
+ outputs=[chatbot]
284
+ )
285
+
286
+ message_input.submit(
287
+ fn=process_message_with_files,
288
+ inputs=[message_input, file_upload, audio_upload, chat_history],
289
+ outputs=[chat_history, message_input, file_upload, audio_upload, status_message]
290
+ ).then(
291
+ fn=lambda history: history,
292
+ inputs=[chat_history],
293
+ outputs=[chatbot]
294
+ )
295
+
296
+ save_button.click(
297
+ fn=save_chat_history,
298
+ inputs=[chat_history],
299
+ outputs=[status_message]
300
+ )
301
+
302
+ clear_button.click(
303
+ fn=clear_chat,
304
+ outputs=[chat_history, status_message]
305
+ ).then(
306
+ fn=lambda: [],
307
+ outputs=[chatbot]
308
+ )
309
+
310
+ load_file.change(
311
+ fn=load_chat_history,
312
+ inputs=[load_file],
313
+ outputs=[chat_history, status_message]
314
+ ).then(
315
+ fn=lambda history: history,
316
+ inputs=[chat_history],
317
+ outputs=[chatbot]
318
+ )
319
+
320
+ if __name__ == "__main__":
321
+ demo.launch(
322
+ server_name="0.0.0.0",
323
+ server_port=7860,
324
+ share=False,
325
+ debug=True
326
+ )