1
- from sql import inspect
2
- from sql .run import run
3
- from sql .connection import ConnectionManager
4
- from sql .magic import SqlMagic , load_ipython_extension
5
- from IPython .core .interactiveshell import InteractiveShell
6
-
7
-
8
1
import uuid
9
2
import requests
10
3
from functools import partial
11
4
5
+ import openai
12
6
import solara
13
7
import solara .lab
14
8
from solara .components .file_drop import FileDrop
15
9
10
+ from sql import inspect
11
+ from sql .run import run
12
+ from sql .connection import ConnectionManager
13
+ from sql .magic import SqlMagic , load_ipython_extension
14
+ from IPython .core .interactiveshell import InteractiveShell
16
15
from sql .plot import boxplot , histogram
16
+ from sqlalchemy .exc import ProgrammingError
17
17
18
18
from chat import *
19
19
28
28
margin: auto;
29
29
padding: 1em;
30
30
}
31
+
32
+ #app > div > div:nth-child(2) > div:nth-child(2) {
33
+ display: none;
34
+ }
31
35
"""
32
36
33
37
openai .api_key = "YOUR_API_KEY"
@@ -78,37 +82,47 @@ def delete_data():
78
82
79
83
80
84
class State :
81
- package = solara .reactive ("Matplotlib" )
82
85
initial_prompt = solara .reactive ("" )
83
86
sample_data_loaded = solara .reactive (False )
84
87
upload_data = solara .reactive (False )
85
88
upload_data_error = solara .reactive ("" )
86
89
results = solara .reactive (20 )
90
+ input = solara .reactive ("" )
91
+ loading_data = solara .reactive (False )
87
92
88
93
@staticmethod
89
94
def load_sample ():
90
95
State .reset ()
91
96
name = gen_name ()
97
+ State .loading_data .value = True
92
98
url = "https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv"
93
99
response = requests .get (url )
94
100
if response .status_code == 200 :
95
101
with open (name , "wb" ) as f :
96
102
f .write (response .content )
97
103
cols = load_data (name )
98
104
State .sample_data_loaded .value = True
105
+ State .loading_data .value = False
99
106
State .initial_prompt .value = prompt_template .format (cols )
100
107
else :
101
108
solara .Warning ("Failed to fetch the data. Check the URL and try again." )
102
109
103
110
@staticmethod
104
111
def load_from_file (file ):
112
+ if not file ["name" ].endswith (".csv" ):
113
+ State .upload_data_error .value = "Only csv files are supported"
114
+ return
105
115
State .reset ()
106
116
name = gen_name ()
117
+ State .loading_data .value = True
107
118
try :
108
119
df = pd .read_csv (file ["file_obj" ])
120
+ df .columns = df .columns .str .strip ()
121
+ df .columns = df .columns .str .replace (' ' , '_' )
109
122
df .to_csv (name , index = False )
110
123
cols = load_data (name )
111
124
State .upload_data .value = True
125
+ State .loading_data .value = False
112
126
State .initial_prompt .value = prompt_template .format (cols )
113
127
except Exception as e :
114
128
State .upload_data_error .value = str (e )
@@ -117,10 +131,10 @@ def load_from_file(file):
117
131
118
132
@staticmethod
119
133
def reset ():
120
- delete_data ()
121
- State .initial_prompt .value = ""
122
134
State .sample_data_loaded .value = False
123
135
State .upload_data .value = False
136
+ delete_data ()
137
+ State .initial_prompt .value = ""
124
138
State .upload_data_error .value = ""
125
139
126
140
@staticmethod
@@ -162,9 +176,11 @@ def Chat() -> None:
162
176
input , set_input = solara .use_state ("" )
163
177
164
178
def ask_chatgpt ():
179
+ input = State .input .value
165
180
_messages = messages + [Message (role = "user" , content = input , df = None , fig = None )]
166
181
user_input = input
167
182
set_input ("" )
183
+ State .input .value = ""
168
184
set_messages (_messages )
169
185
if State .initial_prompt .value :
170
186
final = None
@@ -173,46 +189,55 @@ def ask_chatgpt():
173
189
174
190
if final .startswith ("%sqlplot" ):
175
191
_ , name , column = final .split (" " )
192
+
176
193
fig = Figure ()
177
194
ax = fig .subplots ()
178
195
179
196
fn_map = {"histogram" : partial (histogram , bins = 50 ),
180
197
"boxplot" : boxplot }
181
198
182
199
fn = fn_map [name ]
183
- ax = fn ("my_data" , column , ax = ax )
184
- set_messages (_messages + [Message (role = "assistant" , content = "" , df = None , fig = fig )])
185
- #[Message(role="assistant", content=final, df=None, fig=None)])
200
+ try :
201
+ ax = fn ("my_data" , column , ax = ax )
202
+ set_messages (_messages + [Message (role = "assistant" , content = "" , df = None , fig = fig )])
203
+ except Exception as e :
204
+ set_messages (_messages + [
205
+ Message (role = "assistant" , content = "Please pass relevant columns" , df = None , fig = None )])
186
206
else :
187
- messages_list = ';' .join ([msg .content for msg in _messages ])
188
- query_result = run .run_statements (conn , final , sqlmagic )
189
- set_messages (_messages + [Message (role = "assistant" , content = "" , df = query_result , fig = None )])
190
- # [Message(role="assistant", content=f"Setting in else part: {final} {user_input} "
191
- # f"{messages_list}",
192
- # df=None, fig=None)])
207
+ error = "Sorry, we couldn't run your query on the data"
208
+ try :
209
+ query_result = run .run_statements (conn , final , sqlmagic )
210
+ set_messages (_messages + [Message (role = "assistant" , content = "" , df = query_result , fig = None )])
211
+ except ProgrammingError as e :
212
+ set_messages (_messages + [
213
+ Message (role = "assistant" , content = error , df = None , fig = None )])
214
+ except Exception as e :
215
+ set_messages (_messages + [
216
+ Message (role = "assistant" , content = error , df = None , fig = None )])
217
+
193
218
else :
194
- set_messages (_messages + [Message (role = "assistant" , content = "Please load some data first!" , df = None , fig = None )])
219
+ set_messages (_messages + [Message (role = "assistant" ,
220
+ content = "Please load some data first!" , df = None , fig = None )])
195
221
196
222
with solara .VBox ():
197
223
for message in messages :
198
224
ChatBox (message )
199
225
200
226
with solara .Row (justify = "center" ):
201
227
with solara .HBox (align_items = "center" , classes = ["chat-input" ]):
202
- rv . Textarea ( v_model = input , on_v_model = set_input , solo = True , hide_details = True , outlined = True ,
203
- rows = 1 ,
204
- auto_grow = True )
205
- solara . IconButton ( "send" , on_click = ask_chatgpt )
228
+ solara . InputText ( label = "Query" , value = State . input , continuous_update = False )
229
+
230
+ if State . input . value :
231
+ ask_chatgpt ( )
206
232
207
233
208
234
@solara .component
209
235
def Page ():
210
- package = State .package .value
211
236
initial_prompt = State .initial_prompt .value
212
237
sample_data_loaded = State .sample_data_loaded .value
213
238
upload_data = State .upload_data .value
214
239
upload_data_error = State .upload_data_error .value
215
- results = State .results .value
240
+ results = State .results .value
216
241
217
242
with solara .AppBarTitle ():
218
243
solara .Text ("Data Querying and Visualisation App" )
@@ -235,11 +260,13 @@ def Page():
235
260
solara .Button ("Clear dataset" , color = "primary" , text = True , outlined = True , on_click = State .reset )
236
261
FileDrop (on_file = State .load_from_file , on_total_progress = lambda * args : None ,
237
262
label = "Drag a .csv file here" )
263
+ if State .loading_data .value :
264
+ with solara .Div ():
265
+ solara .Text ("Loading csv..." )
266
+ solara .ProgressLinear (True )
238
267
if initial_prompt :
239
268
solara .InputInt ("Number of preview rows" , value = State .results , continuous_update = True )
240
269
241
- solara .Select (label = "Visualisation Library" , value = State .package , values = ['Matplotlib' , 'Plotly' , 'Altair' ])
242
-
243
270
solara .Markdown ("Hosted in [Ploomber Cloud](https://ploomber.io/)" )
244
271
245
272
if sample_data_loaded :
0 commit comments