zami44 commited on
Commit
fd38d42
·
verified ·
1 Parent(s): 2d17520

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +271 -0
  2. requirements.txt +13 -0
app.py ADDED
@@ -0,0 +1,271 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from langchain_core.messages import AIMessage, HumanMessage
3
+ from langchain_openai import ChatOpenAI
4
+ from langchain_core.output_parsers import StrOutputParser
5
+ from langchain_core.prompts import ChatPromptTemplate
6
+ from PyPDF2 import PdfReader
7
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
8
+ from langchain_google_genai import GoogleGenerativeAIEmbeddings
9
+ from langchain_community.vectorstores import FAISS
10
+ from tavily import TavilyClient
11
+ from streamlit_pdf_viewer import pdf_viewer
12
+ import hashlib
13
+ import io
14
+ import os
15
+ import pickle
16
+ import tempfile
17
+ from google.oauth2.credentials import Credentials
18
+ from google_auth_oauthlib.flow import InstalledAppFlow
19
+ from googleapiclient.discovery import build
20
+ from googleapiclient.http import MediaFileUpload
21
+ import getpass
22
+
23
+ # Initialize API keys
24
+ google_api_key = 'AIzaSyDiZjRdBVZNqmhCQHnqDjz_fjgdfARyZp4'
25
+ tvly_api_key = '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'
26
+ openai_api_key = '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'
27
+
28
+ # Validate API keys
29
+ if not all([google_api_key, tvly_api_key, openai_api_key]):
30
+ st.error("Please set up your API keys.")
31
+ st.stop()
32
+
33
+ # Initialize Tavily client
34
+ web_tool_search = TavilyClient(api_key=tvly_api_key)
35
+
36
+ # Set up Streamlit page
37
+ st.set_page_config(page_title="AI Professor", page_icon="👨‍🏫")
38
+ st.title("👨‍🏫 AI Professor")
39
+
40
+ # Authentication function for Google Drive
41
+ SCOPES = ['https://www.googleapis.com/auth/drive.file']
42
+ def authenticate_google_drive():
43
+ creds = None
44
+ if os.path.exists('token.pickle'):
45
+ with open('token.pickle', 'rb') as token:
46
+ creds = pickle.load(token)
47
+
48
+ if not creds or not creds.valid:
49
+ if creds and creds.expired and creds.refresh_token:
50
+ creds.refresh(Request())
51
+ else:
52
+ flow = InstalledAppFlow.from_client_secrets_file(
53
+ 'credentials.json', SCOPES)
54
+ creds = flow.run_local_server(port=0)
55
+ with open('token.pickle', 'wb') as token:
56
+ pickle.dump(creds, token)
57
+
58
+ return build('drive', 'v3', credentials=creds)
59
+
60
+ def upload_to_drive(content, filename="conversation.txt"):
61
+ service = authenticate_google_drive()
62
+ file_metadata = {'name': filename}
63
+ media = MediaFileUpload(filename, mimetype='text/plain')
64
+
65
+ with open(filename, 'w') as f:
66
+ f.write(content)
67
+
68
+ file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
69
+ st.success(f"Conversation uploaded to Google Drive! File ID: {file.get('id')}")
70
+ return file.get('id')
71
+
72
+ # Simple login system
73
+ def login():
74
+ username = st.text_input("Username", "")
75
+ password = st.text_input("Password", "", type="password")
76
+
77
+ if st.button("Login"):
78
+ if username == "admin" and password == "password123":
79
+ st.session_state.logged_in = True
80
+ st.success("Login successful!")
81
+ else:
82
+ st.session_state.logged_in = False
83
+ st.error("Invalid credentials. Please try again.")
84
+
85
+ # Initialize session state variables
86
+ if "logged_in" not in st.session_state:
87
+ st.session_state.logged_in = False
88
+
89
+ if not st.session_state.logged_in:
90
+ login()
91
+
92
+ def get_pdf_text(pdf_docs):
93
+ text = ""
94
+ if isinstance(pdf_docs, list):
95
+ for pdf in pdf_docs:
96
+ pdf_reader = PdfReader(pdf)
97
+ for page in pdf_reader.pages:
98
+ text += page.extract_text()
99
+ else:
100
+ pdf_reader = PdfReader(pdf_docs)
101
+ for page in pdf_reader.pages:
102
+ text += page.extract_text()
103
+ return text
104
+
105
+ def get_text_chunks(text):
106
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=10000, chunk_overlap=1000)
107
+ chunks = text_splitter.split_text(text)
108
+ return chunks
109
+
110
+ def get_vector_store(text_chunks):
111
+ try:
112
+ embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001", google_api_key=google_api_key)
113
+ vector_store = FAISS.from_texts(text_chunks, embedding=embeddings)
114
+ return vector_store
115
+ except Exception as e:
116
+ st.error(f"Error creating vector store: {str(e)}")
117
+ return None
118
+
119
+ def get_response(user_query, chat_history, vector_store):
120
+ if vector_store is None:
121
+ return "Please upload a PDF document first."
122
+
123
+ template = """
124
+ You are a helpful assistant. Answer the following questions considering the history of the conversation and the document provided:
125
+
126
+ Context: {context}
127
+ Chat history: {chat_history}
128
+ User question: {user_question}
129
+ """
130
+
131
+ prompt = ChatPromptTemplate.from_template(template)
132
+
133
+ try:
134
+ llm = ChatOpenAI(
135
+ base_url="https://api.groq.com/openai/v1",
136
+ api_key=openai_api_key,
137
+ model_name="gpt-4o-mini",
138
+ temperature=1,
139
+ max_tokens=1024
140
+ )
141
+
142
+ docs = vector_store.similarity_search(user_query)
143
+ context = "\n".join(doc.page_content for doc in docs)
144
+
145
+ chain = prompt | llm | StrOutputParser()
146
+
147
+ return chain.invoke({
148
+ "context": context,
149
+ "chat_history": chat_history,
150
+ "user_question": user_query,
151
+ })
152
+ except Exception as e:
153
+ return f"Error generating response: {str(e)}"
154
+
155
+ def get_youtube_url(query):
156
+ try:
157
+ response = web_tool_search.search(
158
+ query=query,
159
+ search_depth="basic",
160
+ include_domains=["youtube.com"],
161
+ max_results=1
162
+ )
163
+
164
+ for result in response['results']:
165
+ if 'youtube.com/watch' in result['url']:
166
+ return result['url']
167
+
168
+ return None
169
+ except Exception as e:
170
+ st.error(f"Error searching for video: {str(e)}")
171
+ return None
172
+
173
+ def get_pdfs_hash(pdf_docs):
174
+ combined_hash = hashlib.md5()
175
+ if isinstance(pdf_docs, list):
176
+ for pdf in pdf_docs:
177
+ content = pdf.read()
178
+ combined_hash.update(content)
179
+ pdf.seek(0)
180
+ else:
181
+ content = pdf_docs.read()
182
+ combined_hash.update(content)
183
+ pdf_docs.seek(0)
184
+ return combined_hash.hexdigest()
185
+
186
+
187
+ # If logged in, continue with the chatbot functionality
188
+ if st.session_state.logged_in:
189
+ # Initialize session state variables
190
+ if "chat_history" not in st.session_state:
191
+ st.session_state.chat_history = [
192
+ AIMessage(content="Hello, I am Chatbot professor assistant. How can I help you?")
193
+ ]
194
+ if "vector_store" not in st.session_state:
195
+ st.session_state.vector_store = None
196
+
197
+ # Sidebar for PDF upload and settings
198
+ with st.sidebar:
199
+ st.title("Menu:")
200
+ pdf_docs = st.file_uploader("Upload your PDF Files", accept_multiple_files=False)
201
+ quiz_button = st.button("🗒️ Make a quiz")
202
+ video_button = st.button("📺 Search a video")
203
+ view = st.toggle("👁️ View PDF")
204
+
205
+ if view and pdf_docs:
206
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as temp_file:
207
+ temp_file.write(pdf_docs.read())
208
+ temp_pdf_path = temp_file.name
209
+ pdf_viewer(temp_pdf_path, width=800)
210
+
211
+ # Display chat history
212
+ for message in st.session_state.chat_history:
213
+ if isinstance(message, AIMessage):
214
+ with st.chat_message("AI"):
215
+ st.write(message.content)
216
+ elif isinstance(message, HumanMessage):
217
+ with st.chat_message("Human"):
218
+ st.write(message.content)
219
+
220
+ # Process PDF upload
221
+ if pdf_docs:
222
+ # Convert PDF to text and split into chunks for embedding
223
+ text = get_pdf_text(pdf_docs)
224
+ text_chunks = get_text_chunks(text)
225
+ st.session_state.vector_store = get_vector_store(text_chunks)
226
+ st.success("Document uploaded and ready for conversation.")
227
+
228
+ # Process user query
229
+ user_query = st.chat_input("Type your message here...")
230
+ if user_query:
231
+ st.session_state.chat_history.append(HumanMessage(content=user_query))
232
+ with st.chat_message("Human"):
233
+ st.write(user_query)
234
+
235
+ response = get_response(user_query, st.session_state.chat_history, st.session_state.vector_store)
236
+ st.session_state.chat_history.append(AIMessage(content=response))
237
+ with st.chat_message("AI"):
238
+ st.write(response)
239
+
240
+ # Upload conversation to Google Drive
241
+ # upload_to_drive("".join([msg.content for msg in st.session_state.chat_history]), "chat_conversation.txt")
242
+
243
+ # Handle quiz generation
244
+ if quiz_button:
245
+ with st.spinner("Generating quiz..."):
246
+ quiz_prompt = """
247
+ Based on the document content, create a quiz with 5 multiple choice questions.
248
+ Format each question like this:
249
+ Question X:
250
+ **A)** Answer 1
251
+ **B)** Answer 2
252
+ **C)** Answer 3
253
+ **D)** Answer 4
254
+ """
255
+ response = get_response(quiz_prompt, st.session_state.chat_history, st.session_state.vector_store)
256
+ st.write(response)
257
+ st.session_state.chat_history.append(AIMessage(content=response))
258
+
259
+ # Handle video search
260
+ if video_button:
261
+ with st.spinner("Searching for relevant video..."):
262
+ video_prompt = """
263
+ Extract the main topic and key concepts from the document and the last conversation.
264
+ """
265
+ response = get_response(video_prompt, st.session_state.chat_history, st.session_state.vector_store)
266
+ youtube_url = get_youtube_url(f"Course on {response}")
267
+ if youtube_url:
268
+ st.write(f"📺 Here's a video about {response}: {youtube_url}")
269
+ st.video(youtube_url)
270
+ video_message = f"📺 Here's a video about {response}:\n{youtube_url}"
271
+ st.session_state.chat_history.append(AIMessage(content=video_message))
requirements.txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ langchain_core
3
+ langchain_openai
4
+ langchain_google_genai
5
+ langchain_community
6
+ PyPDF2
7
+ faiss-cpu
8
+ tavily-python
9
+ streamlit-pdf-viewer
10
+ google-auth
11
+ google-auth-oauthlib
12
+ google-auth-httplib2
13
+ google-api-python-client