mzaeem30 commited on
Commit
f7dc585
·
verified ·
1 Parent(s): ccb16b9

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +200 -0
app.py ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+ from groq import Groq
4
+ from PyPDF2 import PdfReader
5
+ from sentence_transformers import SentenceTransformer
6
+ import faiss
7
+ import numpy as np
8
+ import whisper
9
+ from gtts import gTTS
10
+ from tempfile import NamedTemporaryFile
11
+ import json
12
+ import gdown
13
+
14
+ # Initialize Groq client
15
+ client = Groq(api_key="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")
16
+
17
+ # Load embedding model
18
+ embedding_model = SentenceTransformer("all-MiniLM-L6-v2")
19
+
20
+ # Load Whisper model
21
+ whisper_model = whisper.load_model("base")
22
+
23
+ # Initialize FAISS
24
+ embedding_dimension = 384 # Dimension of embeddings from the model
25
+ index = faiss.IndexFlatL2(embedding_dimension)
26
+ metadata = []
27
+
28
+ # List of Google Drive PDF links
29
+ google_drive_links = [
30
+ "https://drive.google.com/file/d/1_9vZ5jw6Lpoh7jDnqqIiyq082d3uT2dp/view?usp=sharing"
31
+ ]
32
+
33
+ # Streamlit App Configuration
34
+ st.set_page_config(page_title="Voice/Text Chatbot with RAG PDF Query", page_icon="🔊", layout="wide")
35
+
36
+ # Title
37
+ st.markdown("<h1 style='text-align: center; color: #006400;'> ProManage AI </h1>", unsafe_allow_html=True)
38
+ st.markdown("---")
39
+
40
+ # Sidebar for PDF Upload
41
+ st.sidebar.header("Upload Your PDF File")
42
+ uploaded_file = st.sidebar.file_uploader("Upload a PDF file", type="pdf")
43
+
44
+ # Function to extract file ID from Google Drive link
45
+ def extract_file_id(drive_link):
46
+ return drive_link.split("/d/")[1].split("/view")[0]
47
+
48
+ # Function to download PDF from Google Drive
49
+ def download_pdf_from_google_drive(file_id, output_path):
50
+ download_url = f"https://drive.google.com/uc?id={file_id}"
51
+ gdown.download(download_url, output_path, quiet=False)
52
+
53
+ # Function for text extraction from PDF
54
+ def extract_text_from_pdf(file):
55
+ reader = PdfReader(file)
56
+ text = ""
57
+ for page in reader.pages:
58
+ text += page.extract_text()
59
+ return text
60
+
61
+ # Function for text-to-speech
62
+ def text_to_speech(response_text):
63
+ tts = gTTS(text=response_text, lang="en")
64
+ audio_file = NamedTemporaryFile(delete=False, suffix=".mp3")
65
+ tts.save(audio_file.name)
66
+ return audio_file.name
67
+
68
+ # Save embeddings and metadata
69
+ def save_database(faiss_index, metadata, file_path="vector_database.json"):
70
+ all_embeddings = []
71
+ for i in range(faiss_index.ntotal):
72
+ all_embeddings.append(faiss_index.reconstruct(i).tolist())
73
+ data = {
74
+ "embeddings": all_embeddings,
75
+ "metadata": metadata
76
+ }
77
+ with open(file_path, "w") as f:
78
+ json.dump(data, f)
79
+ st.success(f"Vector database saved to {file_path}!")
80
+
81
+ # Process Google Drive PDFs
82
+ st.sidebar.header("Processing Google Drive PDFs")
83
+ with st.spinner("Downloading and processing Google Drive PDFs..."):
84
+ for link in google_drive_links:
85
+ file_id = extract_file_id(link)
86
+ output_pdf_path = f"downloaded_{file_id}.pdf"
87
+
88
+ # Download PDF
89
+ if not os.path.exists(output_pdf_path): # Avoid re-downloading
90
+ download_pdf_from_google_drive(file_id, output_pdf_path)
91
+
92
+ # Extract text and process
93
+ pdf_text = extract_text_from_pdf(output_pdf_path)
94
+ if pdf_text.strip():
95
+ # Split text into chunks and create embeddings
96
+ chunk_size = 500
97
+ chunks = [pdf_text[i:i + chunk_size] for i in range(0, len(pdf_text), chunk_size)]
98
+ embeddings = embedding_model.encode(chunks, convert_to_numpy=True)
99
+ index.add(embeddings)
100
+
101
+ # Store metadata
102
+ metadata.extend([{"chunk": chunk, "source": f"Google Drive: {output_pdf_path}"} for chunk in chunks])
103
+
104
+ # PDF Text Processing
105
+ if uploaded_file:
106
+ pdf_text = extract_text_from_pdf(uploaded_file)
107
+ if pdf_text.strip():
108
+ st.success("PDF text successfully extracted!")
109
+ with st.expander("View Extracted Text", expanded=False):
110
+ st.write(pdf_text[:3000] + "..." if len(pdf_text) > 3000 else pdf_text)
111
+
112
+ # Split text into chunks and create embeddings
113
+ chunk_size = 500
114
+ chunks = [pdf_text[i:i + chunk_size] for i in range(0, len(pdf_text), chunk_size)]
115
+ embeddings = embedding_model.encode(chunks, convert_to_numpy=True)
116
+ index.add(embeddings)
117
+
118
+ # Store metadata
119
+ metadata.extend([{"chunk": chunk, "source": uploaded_file.name} for chunk in chunks])
120
+ save_database(index, metadata)
121
+
122
+ st.success(f"Processed {len(chunks)} chunks and stored embeddings in FAISS!")
123
+
124
+ # Main Chatbot Interface
125
+ st.header("🤖 Gen-AI Powered Chatbot")
126
+
127
+ # Input Method Selection
128
+ input_method = st.radio("Select Input Method:", options=["Text", "Audio"])
129
+
130
+ if input_method == "Text":
131
+ st.subheader("💬 Text Query Input")
132
+ text_query = st.text_input("Enter your query:")
133
+ if st.button("Submit Text Query"):
134
+ if text_query:
135
+ try:
136
+ # Search FAISS for nearest chunks
137
+ query_embedding = embedding_model.encode([text_query], convert_to_numpy=True)
138
+ distances, indices = index.search(query_embedding, k=5)
139
+ relevant_chunks = [metadata[idx]["chunk"] for idx in indices[0]]
140
+
141
+ # Generate response using Groq API
142
+ prompt = f"Use these references to answer the query:\n\n{relevant_chunks}\n\nQuery: {text_query}"
143
+ chat_completion = client.chat.completions.create(
144
+ messages=[{"role": "user", "content": prompt}],
145
+ model="llama-3.3-70b-versatile",
146
+ )
147
+ response = chat_completion.choices[0].message.content
148
+
149
+ # Display text response
150
+ st.write(f"**Chatbot Response:** {response}")
151
+
152
+ # Generate and play audio response
153
+ response_audio_path = text_to_speech(response)
154
+ st.audio(response_audio_path, format="audio/mp3", start_time=0)
155
+
156
+ except Exception as e:
157
+ st.error(f"Error processing your query: {e}")
158
+
159
+ elif input_method == "Audio":
160
+ st.subheader("🎤 Audio Query Input")
161
+ uploaded_audio = st.file_uploader("Upload your audio file", type=["m4a", "mp3", "wav"])
162
+
163
+ if uploaded_audio:
164
+ try:
165
+ audio_data = uploaded_audio.read()
166
+ audio_file = NamedTemporaryFile(delete=False, suffix=".m4a")
167
+ audio_file.write(audio_data)
168
+ audio_file_path = audio_file.name
169
+
170
+ st.success("Audio file uploaded successfully!")
171
+
172
+ # Transcribe the audio using Whisper model
173
+ transcription = whisper_model.transcribe(audio_file_path)["text"]
174
+ st.write(f"**You said:** {transcription}")
175
+
176
+ # Search FAISS for nearest chunks
177
+ query_embedding = embedding_model.encode([transcription], convert_to_numpy=True)
178
+ distances, indices = index.search(query_embedding, k=5)
179
+ relevant_chunks = [metadata[idx]["chunk"] for idx in indices[0]]
180
+
181
+ # Generate response using Groq API
182
+ prompt = f"Use these references to answer the query:\n\n{relevant_chunks}\n\nQuery: {transcription}"
183
+ chat_completion = client.chat.completions.create(
184
+ messages=[{"role": "user", "content": prompt}],
185
+ model="llama-3.3-70b-versatile",
186
+ )
187
+ response = chat_completion.choices[0].message.content
188
+
189
+ # Display text response
190
+ st.write(f"**Chatbot Response:** {response}")
191
+
192
+ # Generate and play audio response
193
+ response_audio_path = text_to_speech(response)
194
+ st.audio(response_audio_path, format="audio/mp3", start_time=0)
195
+
196
+ except Exception as e:
197
+ st.error(f"Error processing your query: {e}")
198
+
199
+ # Footer
200
+ st.markdown("<p style='text-align: center;'> Muhammad Zaeem Ilyas-PMP®| PMO NESPAK </p>", unsafe_allow_html=True)