Chamin09 commited on
Commit
f55e54c
·
verified ·
1 Parent(s): 5b7858c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +222 -217
app.py CHANGED
@@ -1,217 +1,222 @@
1
- import os
2
- import gradio as gr
3
- import tempfile
4
- from pathlib import Path
5
- import base64
6
- from PIL import Image
7
- import io
8
- import time
9
-
10
- # Import our components
11
- from models.llm_setup import setup_llm
12
- from indexes.csv_index_builder import EnhancedCSVReader
13
- from indexes.index_manager import CSVIndexManager
14
- from indexes.query_engine import CSVQueryEngine
15
- from tools.data_tools import PandasDataTools
16
- from tools.visualization import VisualizationTools
17
- from tools.export import ExportTools
18
-
19
- # Setup temporary directory for uploaded files
20
- UPLOAD_DIR = Path(tempfile.mkdtemp())
21
- EXPORT_DIR = Path(tempfile.mkdtemp())
22
-
23
- class CSVChatApp:
24
- """Main application class for CSV chatbot."""
25
-
26
- def __init__(self):
27
- """Initialize the application components."""
28
- # Initialize the language model
29
- self.llm = setup_llm()
30
-
31
- # Initialize the index manager
32
- self.index_manager = CSVIndexManager()
33
-
34
- # Initialize tools
35
- self.data_tools = PandasDataTools(str(UPLOAD_DIR))
36
- self.viz_tools = VisualizationTools(str(UPLOAD_DIR))
37
- self.export_tools = ExportTools(str(EXPORT_DIR))
38
-
39
- # Initialize query engine with tools
40
- self.query_engine = self._setup_query_engine()
41
-
42
- # Track conversation history
43
- self.chat_history = []
44
- self.uploaded_files = []
45
-
46
- def _setup_query_engine(self):
47
- """Set up the query engine with tools."""
48
- # Get all tools
49
- tools = (
50
- self.data_tools.get_tools() +
51
- self.viz_tools.get_tools() +
52
- self.export_tools.get_tools()
53
- )
54
-
55
- # Create query engine with tools
56
- query_engine = CSVQueryEngine(self.index_manager, self.llm)
57
-
58
- return query_engine
59
-
60
- def handle_file_upload(self, files):
61
- """Process uploaded CSV files."""
62
- file_info = []
63
-
64
- for file in files:
65
- if file is None:
66
- continue
67
-
68
- # Get file path
69
- file_path = Path(file.name)
70
-
71
- # Only process CSV files
72
- if not file_path.suffix.lower() == '.csv':
73
- continue
74
-
75
- # Copy to upload directory
76
- dest_path = UPLOAD_DIR / file_path.name
77
- with open(dest_path, 'wb') as f:
78
- f.write(file_path.read_bytes())
79
-
80
- # Create index for this file
81
- try:
82
- self.index_manager.create_index(str(dest_path))
83
- file_info.append(f"✅ Indexed: {file_path.name}")
84
- self.uploaded_files.append(str(dest_path))
85
- except Exception as e:
86
- file_info.append(f"❌ Failed to index {file_path.name}: {str(e)}")
87
-
88
- # Return information about processed files
89
- if file_info:
90
- return "\n".join(file_info)
91
- else:
92
- return "No CSV files were uploaded."
93
-
94
- def process_query(self, query, history):
95
- """Process a user query and generate a response."""
96
- if not self.uploaded_files:
97
- return "Please upload CSV files before asking questions."
98
-
99
- # Add user message to history
100
- self.chat_history.append({"role": "user", "content": query})
101
-
102
- # Process the query
103
- try:
104
- response = self.query_engine.query(query)
105
- answer = response["answer"]
106
-
107
- # Check if response contains an image
108
- if isinstance(answer, dict) and "image" in answer:
109
- # Handle image in response
110
- img_data = answer["image"]
111
- img = Image.open(io.BytesIO(base64.b64decode(img_data)))
112
- img_path = EXPORT_DIR / f"viz_{int(time.time())}.png"
113
- img.save(img_path)
114
-
115
- # Update answer to include image path
116
- text_response = answer.get("text", "Generated visualization")
117
- answer = (text_response, str(img_path))
118
-
119
- # Add assistant message to history
120
- self.chat_history.append({"role": "assistant", "content": answer})
121
-
122
- return answer
123
-
124
- except Exception as e:
125
- error_msg = f"Error processing query: {str(e)}"
126
- self.chat_history.append({"role": "assistant", "content": error_msg})
127
- return error_msg
128
-
129
- def export_conversation(self):
130
- """Export the conversation as a report."""
131
- if not self.chat_history:
132
- return "No conversation to export."
133
-
134
- # Extract content for report
135
- title = "CSV Chat Conversation Report"
136
- content = ""
137
- images = []
138
-
139
- for msg in self.chat_history:
140
- role = msg["role"]
141
- content_text = msg["content"]
142
-
143
- # Handle content that might contain images
144
- if isinstance(content_text, tuple) and len(content_text) == 2:
145
- text, img_path = content_text
146
- content += f"\n\n{'User' if role == 'user' else 'Assistant'}: {text}"
147
-
148
- # Add image to report
149
- try:
150
- with open(img_path, "rb") as img_file:
151
- img_data = base64.b64encode(img_file.read()).decode('utf-8')
152
- images.append(img_data)
153
- except Exception:
154
- pass
155
- else:
156
- content += f"\n\n{'User' if role == 'user' else 'Assistant'}: {content_text}"
157
-
158
- # Generate report
159
- result = self.export_tools.generate_report(title, content, images)
160
-
161
- if result["success"]:
162
- return f"Report exported to: {result['report_path']}"
163
- else:
164
- return "Failed to export report."
165
-
166
- # Create the Gradio interface
167
- def create_interface():
168
- """Create the Gradio web interface."""
169
- app = CSVChatApp()
170
-
171
- with gr.Blocks(title="CSV Chat Assistant") as interface:
172
- gr.Markdown("# CSV Chat Assistant")
173
- gr.Markdown("Upload CSV files and ask questions in natural language.")
174
-
175
- with gr.Row():
176
- with gr.Column(scale=1):
177
- file_upload = gr.File(
178
- label="Upload CSV Files",
179
- file_count="multiple",
180
- type="file"
181
- )
182
- upload_button = gr.Button("Process Files")
183
- file_status = gr.Textbox(label="File Status")
184
-
185
- export_button = gr.Button("Export Conversation")
186
- export_status = gr.Textbox(label="Export Status")
187
-
188
- with gr.Column(scale=2):
189
- chatbot = gr.Chatbot(label="Conversation")
190
- msg = gr.Textbox(label="Your Question")
191
- submit_button = gr.Button("Submit")
192
-
193
- # Set up event handlers
194
- upload_button.click(
195
- fn=app.handle_file_upload,
196
- inputs=[file_upload],
197
- outputs=[file_status]
198
- )
199
-
200
- submit_button.click(
201
- fn=app.process_query,
202
- inputs=[msg, chatbot],
203
- outputs=[chatbot]
204
- )
205
-
206
- export_button.click(
207
- fn=app.export_conversation,
208
- inputs=[],
209
- outputs=[export_status]
210
- )
211
-
212
- return interface
213
-
214
- # Launch the app
215
- if __name__ == "__main__":
216
- interface = create_interface()
217
- interface.launch()
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ import tempfile
4
+ from pathlib import Path
5
+ import base64
6
+ from PIL import Image
7
+ import io
8
+ import time
9
+
10
+
11
+ current_dir = os.path.dirname(os.path.abspath(__file__))
12
+ sys.path.append(current_dir)
13
+
14
+
15
+ # Import our components
16
+ from models.llm_setup import setup_llm
17
+ from indexes.csv_index_builder import EnhancedCSVReader
18
+ from indexes.index_manager import CSVIndexManager
19
+ from indexes.query_engine import CSVQueryEngine
20
+ from tools.data_tools import PandasDataTools
21
+ from tools.visualization import VisualizationTools
22
+ from tools.export import ExportTools
23
+
24
+ # Setup temporary directory for uploaded files
25
+ UPLOAD_DIR = Path(tempfile.mkdtemp())
26
+ EXPORT_DIR = Path(tempfile.mkdtemp())
27
+
28
+ class CSVChatApp:
29
+ """Main application class for CSV chatbot."""
30
+
31
+ def __init__(self):
32
+ """Initialize the application components."""
33
+ # Initialize the language model
34
+ self.llm = setup_llm()
35
+
36
+ # Initialize the index manager
37
+ self.index_manager = CSVIndexManager()
38
+
39
+ # Initialize tools
40
+ self.data_tools = PandasDataTools(str(UPLOAD_DIR))
41
+ self.viz_tools = VisualizationTools(str(UPLOAD_DIR))
42
+ self.export_tools = ExportTools(str(EXPORT_DIR))
43
+
44
+ # Initialize query engine with tools
45
+ self.query_engine = self._setup_query_engine()
46
+
47
+ # Track conversation history
48
+ self.chat_history = []
49
+ self.uploaded_files = []
50
+
51
+ def _setup_query_engine(self):
52
+ """Set up the query engine with tools."""
53
+ # Get all tools
54
+ tools = (
55
+ self.data_tools.get_tools() +
56
+ self.viz_tools.get_tools() +
57
+ self.export_tools.get_tools()
58
+ )
59
+
60
+ # Create query engine with tools
61
+ query_engine = CSVQueryEngine(self.index_manager, self.llm)
62
+
63
+ return query_engine
64
+
65
+ def handle_file_upload(self, files):
66
+ """Process uploaded CSV files."""
67
+ file_info = []
68
+
69
+ for file in files:
70
+ if file is None:
71
+ continue
72
+
73
+ # Get file path
74
+ file_path = Path(file.name)
75
+
76
+ # Only process CSV files
77
+ if not file_path.suffix.lower() == '.csv':
78
+ continue
79
+
80
+ # Copy to upload directory
81
+ dest_path = UPLOAD_DIR / file_path.name
82
+ with open(dest_path, 'wb') as f:
83
+ f.write(file_path.read_bytes())
84
+
85
+ # Create index for this file
86
+ try:
87
+ self.index_manager.create_index(str(dest_path))
88
+ file_info.append(f"✅ Indexed: {file_path.name}")
89
+ self.uploaded_files.append(str(dest_path))
90
+ except Exception as e:
91
+ file_info.append(f"❌ Failed to index {file_path.name}: {str(e)}")
92
+
93
+ # Return information about processed files
94
+ if file_info:
95
+ return "\n".join(file_info)
96
+ else:
97
+ return "No CSV files were uploaded."
98
+
99
+ def process_query(self, query, history):
100
+ """Process a user query and generate a response."""
101
+ if not self.uploaded_files:
102
+ return "Please upload CSV files before asking questions."
103
+
104
+ # Add user message to history
105
+ self.chat_history.append({"role": "user", "content": query})
106
+
107
+ # Process the query
108
+ try:
109
+ response = self.query_engine.query(query)
110
+ answer = response["answer"]
111
+
112
+ # Check if response contains an image
113
+ if isinstance(answer, dict) and "image" in answer:
114
+ # Handle image in response
115
+ img_data = answer["image"]
116
+ img = Image.open(io.BytesIO(base64.b64decode(img_data)))
117
+ img_path = EXPORT_DIR / f"viz_{int(time.time())}.png"
118
+ img.save(img_path)
119
+
120
+ # Update answer to include image path
121
+ text_response = answer.get("text", "Generated visualization")
122
+ answer = (text_response, str(img_path))
123
+
124
+ # Add assistant message to history
125
+ self.chat_history.append({"role": "assistant", "content": answer})
126
+
127
+ return answer
128
+
129
+ except Exception as e:
130
+ error_msg = f"Error processing query: {str(e)}"
131
+ self.chat_history.append({"role": "assistant", "content": error_msg})
132
+ return error_msg
133
+
134
+ def export_conversation(self):
135
+ """Export the conversation as a report."""
136
+ if not self.chat_history:
137
+ return "No conversation to export."
138
+
139
+ # Extract content for report
140
+ title = "CSV Chat Conversation Report"
141
+ content = ""
142
+ images = []
143
+
144
+ for msg in self.chat_history:
145
+ role = msg["role"]
146
+ content_text = msg["content"]
147
+
148
+ # Handle content that might contain images
149
+ if isinstance(content_text, tuple) and len(content_text) == 2:
150
+ text, img_path = content_text
151
+ content += f"\n\n{'User' if role == 'user' else 'Assistant'}: {text}"
152
+
153
+ # Add image to report
154
+ try:
155
+ with open(img_path, "rb") as img_file:
156
+ img_data = base64.b64encode(img_file.read()).decode('utf-8')
157
+ images.append(img_data)
158
+ except Exception:
159
+ pass
160
+ else:
161
+ content += f"\n\n{'User' if role == 'user' else 'Assistant'}: {content_text}"
162
+
163
+ # Generate report
164
+ result = self.export_tools.generate_report(title, content, images)
165
+
166
+ if result["success"]:
167
+ return f"Report exported to: {result['report_path']}"
168
+ else:
169
+ return "Failed to export report."
170
+
171
+ # Create the Gradio interface
172
+ def create_interface():
173
+ """Create the Gradio web interface."""
174
+ app = CSVChatApp()
175
+
176
+ with gr.Blocks(title="CSV Chat Assistant") as interface:
177
+ gr.Markdown("# CSV Chat Assistant")
178
+ gr.Markdown("Upload CSV files and ask questions in natural language.")
179
+
180
+ with gr.Row():
181
+ with gr.Column(scale=1):
182
+ file_upload = gr.File(
183
+ label="Upload CSV Files",
184
+ file_count="multiple",
185
+ type="file"
186
+ )
187
+ upload_button = gr.Button("Process Files")
188
+ file_status = gr.Textbox(label="File Status")
189
+
190
+ export_button = gr.Button("Export Conversation")
191
+ export_status = gr.Textbox(label="Export Status")
192
+
193
+ with gr.Column(scale=2):
194
+ chatbot = gr.Chatbot(label="Conversation")
195
+ msg = gr.Textbox(label="Your Question")
196
+ submit_button = gr.Button("Submit")
197
+
198
+ # Set up event handlers
199
+ upload_button.click(
200
+ fn=app.handle_file_upload,
201
+ inputs=[file_upload],
202
+ outputs=[file_status]
203
+ )
204
+
205
+ submit_button.click(
206
+ fn=app.process_query,
207
+ inputs=[msg, chatbot],
208
+ outputs=[chatbot]
209
+ )
210
+
211
+ export_button.click(
212
+ fn=app.export_conversation,
213
+ inputs=[],
214
+ outputs=[export_status]
215
+ )
216
+
217
+ return interface
218
+
219
+ # Launch the app
220
+ if __name__ == "__main__":
221
+ interface = create_interface()
222
+ interface.launch()