Koshti10 commited on
Commit
b775716
1 Parent(s): 4516456

add clear_chat_history/new_chat buttons

Browse files
Files changed (1) hide show
  1. app_drive.py +225 -71
app_drive.py CHANGED
@@ -1,75 +1,229 @@
1
- # ADDING GOOGLE DRIVE SUPPORT
2
 
3
- import io
 
 
4
  import os
5
- import csv
6
- import PyPDF2
7
-
8
- from google.oauth2 import service_account
9
- from googleapiclient.discovery import build
10
- from googleapiclient.http import MediaIoBaseUpload, MediaIoBaseDownload
11
- from driveapi.service import get_credentials
12
-
13
- credentials_info = get_credentials()
14
- credentials = service_account.Credentials.from_service_account_info(credentials_info)
15
- service = build('drive', 'v3', credentials=credentials)
16
-
17
- logs_id = os.environ.get('LOGS_ID')
18
-
19
- # Save Logs
20
- def upload_chat_to_drive(chat_history, file_name):
21
- # Convert chat history to CSV
22
- csv_output = io.StringIO()
23
- writer = csv.writer(csv_output)
24
- writer.writerows(chat_history)
25
- csv_output.seek(0)
26
-
27
- # File metadata
28
- file_metadata = {
29
- 'name': file_name,
30
- 'mimeType': 'application/vnd.google-apps.spreadsheet',
31
- 'parents': [logs_id]
32
- }
33
-
34
- # Upload file
35
- media = MediaIoBaseUpload(csv_output, mimetype='text/csv')
36
- file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
37
-
38
-
39
- ## Read PDF files
40
- def download_file(file_id):
41
- service = build('drive', 'v3', credentials=credentials)
42
- request = service.files().get_media(fileId=file_id)
43
- fh = io.BytesIO()
44
- downloader = MediaIoBaseDownload(fh, request)
45
- done = False
46
- while done is False:
47
- status, done = downloader.next_chunk()
48
- fh.seek(0)
49
- return fh
50
-
51
- # Function to process a PDF file
52
- def process_pdf(file_stream):
53
- if isinstance(file_stream, dict): # Check if PDF was obtained using Drag and Drop or Drive link
54
- file_path = file_stream['name'] # Use 'path' for local testing and 'name' for Gradio
55
- pdf_reader = PyPDF2.PdfReader(file_path)
56
  else:
57
- pdf_reader = PyPDF2.PdfReader(file_stream)
58
- text = ""
59
- for page_num in range(len(pdf_reader.pages)):
60
- page = pdf_reader.pages[page_num]
61
- text += page.extract_text()
62
- return text
63
-
64
- def drive_content(shared_folder_id):
65
- # List files in the folder
66
- results = service.files().list(q=f"'{shared_folder_id}' in parents", fields="files(id, name, mimeType)").execute()
67
- items = results.get('files', [])
68
-
69
- content = ''
70
- for item in items:
71
- print(f"Processing file: {item['name']}")
72
- file_stream = download_file(item['id'])
73
- content += str(process_pdf(file_stream))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
- return content
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Application file for Gradio App for OpenAI Model
2
 
3
+ import gradio as gr
4
+ import time
5
+ import datetime
6
  import os
7
+
8
+ from lc_base.chain import openai_chain
9
+ from lc_base.dnd_database import create_dnd_database
10
+ from driveapi.drive import upload_chat_to_drive
11
+ from driveapi.drive_database import create_chroma_db
12
+
13
+ ############################# Global Params #############################
14
+
15
+ time_diff = 0
16
+ # model_name="gpt-3.5-turbo-1106" # FOR TESTING
17
+ # model_name = "gpt-4-1106-preview"
18
+ model_name = "gpt-4-0125-preview"
19
+ search_type = "stuff"
20
+ input_question = ""
21
+ model_response = ""
22
+ user_feedback = ""
23
+
24
+ dir = ""
25
+ title = """<h1 align="center">ResearchBuddy</h1>"""
26
+ description = """<br><br><h3 align="center">This is a GPT based Research Buddy to assist in navigating new research topics.</h3>"""
27
+
28
+ DEFAULT_STATUS = "⬆️Submit a (shared) drive link containing only PDFs \n-or- \n⬅️Upload PDF files"
29
+ DEFAULT_TEXT_FEEDBACK = ""
30
+ DEFAULT_NUM_FEEDBACK = "None"
31
+ ############################# Drive API specific function #############################
32
+ def create_data_from_drive(drive_link):
33
+ global db
34
+
35
+ drive_link += "?usp=sharing"
36
+ os.environ['DRIVE_LINK'] = str(drive_link)
37
+ print("Drive link saved in the environment! Creating Database...")
38
+
39
+ db = create_chroma_db()
40
+ return "Processing Completed - You can start the chat now!"
41
+
42
+ ############################# Drag and Drop PDF processing #############################
43
+ def check_pdfs(pdf_files):
44
+ global db
45
+ db = create_dnd_database(pdf_files)
46
+ if not db:
47
+ return "Please upload a PDF file again or submit a drive link containing only PDFs."
 
 
 
 
 
 
 
 
 
 
48
  else:
49
+ return "Processing Completed - You can start the chat now!"
50
+
51
+ ############################# Chatbot Specific functions #############################
52
+ def user(user_message, history):
53
+ return "", history + [[user_message, None]]
54
+
55
+ def respond(message, chat_history):
56
+
57
+ global time_diff, model_response, input_question
58
+
59
+ question = str(message)
60
+ chain = openai_chain(inp_dir=dir)
61
+
62
+ query = question
63
+ start_time = time.time()
64
+
65
+ output = chain.get_response_from_drive(query=query, database=db, k=10, model_name=model_name, type=search_type)
66
+
67
+ # Update global variables for logging
68
+ time_diff = time.time() - start_time
69
+ model_response = output
70
+ input_question = question
71
+ save_text_feedback(feedback="Default Conversation Save!!!") # Upload chatlog to drive after every response irrespective of feedback
72
+
73
+ bot_message = output
74
+ chat_history.append((message, bot_message))
75
+
76
+ time.sleep(1) # Pause for a second to avoid overloading
77
+ return " ", chat_history
78
+
79
+ ############################# Feedback Specific functions #############################
80
+
81
+ def save_feedback(feedback):
82
+ global user_feedback
83
+ user_feedback = feedback
84
+
85
+ curr_date = datetime.datetime.now()
86
+ file_name = f"chat_{curr_date.day}_{curr_date.month}_{curr_date.hour}_{curr_date.minute}_{curr_date.second}.csv"
87
+ log_data = [
88
+ ["Question", "Response", "Model", "Time", "Feedback"],
89
+ [input_question, model_response, model_name, time_diff, user_feedback]
90
+ ]
91
+
92
+ if model_response and user_feedback[0] != "None":
93
+ upload_chat_to_drive(log_data, file_name)
94
+
95
+
96
+ def default_feedback():
97
+ return "None"
98
+
99
+ def default_text():
100
+ return ""
101
+
102
+ def save_text_feedback(feedback):
103
+ global text_feedback
104
+ text_feedback = feedback
105
+
106
+ curr_date = datetime.datetime.now()
107
+ file_name = f"chat_{curr_date.day}_{curr_date.month}_{curr_date.hour}_{curr_date.minute}_{curr_date.second}.csv"
108
+ log_data = [
109
+ ["Question", "Response", "Model", "Time", "Feedback"],
110
+ [input_question, model_response, model_name, time_diff, text_feedback]
111
+ ]
112
+
113
+ upload_chat_to_drive(log_data, file_name)
114
+
115
+
116
+ ############################# Gradio Application Block #############################
117
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="emerald", neutral_hue="slate")) as chat:
118
+ gr.HTML(title)
119
+
120
+ global db
121
+
122
+ # PDF Drag and Drop + Drive link Input + Status containers
123
+ with gr.Row(equal_height=True):
124
+ with gr.Column():
125
+ with gr.Row():
126
+ pdf_files_dnd = gr.File(file_count='multiple', height=250, label="Upload PDF Files")
127
+
128
+ with gr.Column():
129
+ with gr.Row():
130
+ drive_link_input = gr.Textbox(lines=1, label="Enter your shared drive link, then press Enter...")
131
+ with gr.Row():
132
+ status_message = gr.Text(label="Status", value=DEFAULT_STATUS, text_align='center')
133
+
134
+
135
+ # What happens when PDF is uploaded or a drive link is submitted
136
+ drive_link_input.submit(
137
+ fn = create_data_from_drive,
138
+ inputs = [drive_link_input],
139
+ outputs = [status_message])
140
+
141
+ pdf_files_dnd.change(
142
+ fn=check_pdfs,
143
+ inputs=[pdf_files_dnd],
144
+ outputs=[status_message],
145
+ preprocess=False,
146
+ postprocess=False) # Set preprocess and postprocess to False, to avoid the tmpfile object creation, instead get a Dict
147
+
148
+ # Chatbot container
149
+ chatbot = gr.Chatbot(height=750)
150
+ msg = gr.Textbox(label="Send a message", placeholder="Send a message",
151
+ show_label=False, container=False)
152
+
153
+ with gr.Row():
154
+ with gr.Column():
155
+ clear_history_button = gr.ClearButton(value="Clear Chat History")
156
+
157
+ with gr.Column():
158
+ new_chat_button = gr.ClearButton(value="New Chat")
159
+
160
+ # Sample questions
161
+ with gr.Row():
162
+ with gr.Column():
163
+ gr.Examples([
164
+ ["Explain these documents to me in simpler terms."],
165
+ ["What does these documents talk about?"],
166
+ ["Give the key topics covered in these documents in less than 10 words."],
167
+ ["What are the key findings in these documents?"],
168
+ ], inputs=msg, label= "Click on any example to copy in the chatbox"
169
+ )
170
+
171
+ # Feedback options container
172
+ with gr.Row():
173
+ with gr.Column():
174
+ feedback_radio = gr.Radio(
175
+ choices=["1", "2", "3", "4", "5", "6", "None"],
176
+ value=["None"],
177
+ label="On a scale from 1 (very unsatisfied) to 6 (very satisfied), how would you rate the current response?",
178
+ )
179
 
180
+ with gr.Column():
181
+ feedback_text = gr.Textbox(lines=1, label="Additional comments on the current response...")
182
+
183
+
184
+ # Get a response when a message is submitted to the chatbot
185
+ msg.submit(
186
+ fn = respond,
187
+ inputs = [msg, chatbot],
188
+ outputs = [msg, chatbot],
189
+ queue = True)
190
+
191
+
192
+ # Set default feedback to None after a message is submitted
193
+ msg.submit(
194
+ fn = default_feedback,
195
+ outputs=[feedback_radio],
196
+ queue = True
197
+ )
198
+
199
+ # Change whenever some feedback is given (Numeric or Text)
200
+ feedback_radio.change(
201
+ fn=save_feedback,
202
+ inputs=[feedback_radio]
203
+ )
204
+
205
+ feedback_text.submit(
206
+ fn=save_text_feedback,
207
+ inputs=[feedback_text],
208
+ queue=True
209
+ )
210
+
211
+ # Clear the text feedback after it is submitted
212
+ feedback_text.submit(
213
+ fn=default_text,
214
+ outputs=[feedback_text],
215
+ queue=True
216
+ )
217
+
218
+ # Clear the chat history/ New chat
219
+ clear_history_button.click(lambda: [None, None], outputs=[msg, chatbot])
220
+ new_chat_button.click(
221
+ lambda: [None, None, None, None, DEFAULT_STATUS, DEFAULT_NUM_FEEDBACK, DEFAULT_TEXT_FEEDBACK],
222
+ outputs=[msg, chatbot, pdf_files_dnd, drive_link_input, status_message, feedback_radio, feedback_text])
223
+
224
+ # Description at the bottom of the application
225
+ gr.HTML(description)
226
+
227
+ # Enable queing
228
+ chat.queue()
229
+ chat.launch()