mgbam commited on
Commit
f72077b
Β·
verified Β·
1 Parent(s): d332562

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +46 -39
app.py CHANGED
@@ -77,7 +77,7 @@ def safe_exec(code_string: str, local_vars: dict):
77
  def load_and_process_file(file_obj, state_dict):
78
  """Loads a CSV, processes it, and updates the entire UI state."""
79
  if file_obj is None:
80
- return state_dict, "Please upload a file.", *[gr.update(visible=False)] * 3
81
  try:
82
  df = pd.read_csv(file_obj.name, low_memory=False)
83
  for col in df.select_dtypes(include=['object']).columns:
@@ -111,7 +111,7 @@ def load_and_process_file(file_obj, state_dict):
111
  gr.update(value=f"{len(metadata['datetime_cols'])}"),
112
  gr.update(choices=metadata['columns']), gr.update(choices=metadata['columns']), gr.update(choices=metadata['columns']))
113
  except Exception as e:
114
- return state_dict, f"❌ **Error:** {e}", *[gr.update()] * 10
115
 
116
  def extract_dataset_metadata(df: pd.DataFrame):
117
  rows, cols = df.shape
@@ -160,11 +160,23 @@ def get_ai_suggestions(state_dict, api_key):
160
  suggestions = json.loads(response.text)
161
 
162
  # Create a button for each suggestion
163
- buttons = [gr.Button(s, variant="secondary") for s in suggestions]
164
- return gr.update(visible=False), gr.Accordion(label="✨ AI Smart Suggestions", open=True, children=buttons)
 
 
 
165
 
166
  except Exception as e:
167
- return f"Could not generate suggestions: {e}", gr.update(visible=False)
 
 
 
 
 
 
 
 
 
168
 
169
  # --- Page 2: Deep Dive Dashboard ---
170
  def add_plot_to_dashboard(state_dict, x_col, y_col, plot_type):
@@ -261,7 +273,7 @@ def respond_to_chat(user_message, history, state_dict, api_key):
261
  if df_result is not None: output_updates[3] = gr.update(visible=True, value=df_result)
262
  if stdout:
263
  # Append stdout to explanation if it exists
264
- new_explanation = (output_updates[0]['value'] if output_updates[0]['value'] else "") + f"\n\n**Console Output:**\n```\n{stdout}\n```"
265
  output_updates[0] = gr.update(visible=True, value=new_explanation)
266
  if error:
267
  error_explanation = f"**Phoenix Co-pilot:** I encountered an error. Here's the details:\n\n`{error}`"
@@ -304,7 +316,8 @@ def create_gradio_interface():
304
  with gr.Column(visible=True) as welcome_page:
305
  gr.Markdown("# Welcome to the AI Data Explorer (Phoenix UI)", elem_id="welcome-header")
306
  gr.Markdown("Please **upload a CSV file** and **enter your Gemini API key** in the sidebar to begin.")
307
- gr.Image(value="https://i.imgur.com/gY5wSjV.png", label="Workflow", show_label=False, show_download_button=False, container=False) # Placeholder image
 
308
 
309
  # Page 1: Data Cockpit (Hidden initially)
310
  with gr.Column(visible=False) as cockpit_page:
@@ -324,7 +337,8 @@ def create_gradio_interface():
324
  time_cols_stat = gr.Textbox("0", show_label=False, elem_classes="stat-card-value")
325
 
326
  suggestion_status = gr.Markdown(visible=True)
327
- suggestion_accordion = gr.Accordion(label="✨ AI Smart Suggestions", open=False, visible=False)
 
328
 
329
  # Page 2: Deep Dive Dashboard Builder (Hidden initially)
330
  with gr.Column(visible=False) as deep_dive_page:
@@ -343,9 +357,8 @@ def create_gradio_interface():
343
  with gr.Column(visible=False) as copilot_page:
344
  gr.Markdown("## πŸ€– AI Co-pilot")
345
  gr.Markdown("Ask complex questions in natural language. The Co-pilot will write and execute code to find the answer.")
346
- chatbot = gr.Chatbot(height=400, label="Conversation with Co-pilot")
347
 
348
- # AI's multi-modal response area
349
  with gr.Accordion("Co-pilot's Response Details", open=True):
350
  copilot_explanation = gr.Markdown(visible=False, elem_classes="explanation-block")
351
  copilot_code = gr.Code(language="python", visible=False, label="Executed Python Code", elem_classes="code-block")
@@ -357,55 +370,49 @@ def create_gradio_interface():
357
  chat_submit_btn = gr.Button("Submit", variant="primary")
358
 
359
  # --- Event Handlers ---
360
- # Page Navigation
361
  pages = [cockpit_page, deep_dive_page, copilot_page]
362
  nav_buttons = [cockpit_btn, deep_dive_btn, copilot_btn]
363
 
364
  for i, btn in enumerate(nav_buttons):
365
- btn.click(lambda i=i: (gr.update(visible=i==0), gr.update(visible=i==1), gr.update(visible=i==2)),
366
- outputs=pages).then(
367
- lambda: [gr.update(elem_classes="selected" if j==i else "") for j in range(len(nav_buttons))],
368
- outputs=nav_buttons)
 
 
 
369
 
370
- # File Upload
371
  file_input.upload(
372
  fn=load_and_process_file,
373
  inputs=[file_input, global_state],
374
  outputs=[global_state, status_output, welcome_page, cockpit_page, deep_dive_page, copilot_page,
375
  rows_stat, cols_stat, quality_stat, time_cols_stat,
376
- x_col_dd, y_col_dd, copilot_input_col_ref_for_dynamic_update] # This last one is a dummy to trigger updates
 
 
377
  ).then(
378
- fn=lambda: (gr.update(elem_classes="selected"), gr.update(elem_classes=""), gr.update(elem_classes="")),
379
- outputs=nav_buttons
380
  )
381
 
382
- # Suggestions Button
383
  suggestion_btn.click(
384
  get_ai_suggestions,
385
  [global_state, api_key_input],
386
- [suggestion_status, suggestion_accordion]
387
- ).then(
388
- fn=lambda: [gr.Button.update(visible=True) for _ in range(5)], # Assumes max 5 suggestions for demo
389
- outputs=[b for b in suggestion_accordion.children] if isinstance(suggestion_accordion, gr.Accordion) and suggestion_accordion.children else []
390
  )
391
- # Handle suggestion button clicks to populate chat
392
- if isinstance(suggestion_accordion, gr.Accordion):
393
- for button in suggestion_accordion.children:
394
- button.click(
395
- fn=lambda q=button.value: (gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), q),
396
- outputs=[cockpit_page, deep_dive_page, copilot_page, chat_input]
397
- ).then(
398
- fn=lambda: (gr.update(elem_classes=""), gr.update(elem_classes=""), gr.update(elem_classes="selected")),
399
- outputs=nav_buttons
400
- )
401
-
402
-
403
- # Dashboard Builder
404
  add_plot_btn.click(add_plot_to_dashboard, [global_state, x_col_dd, y_col_dd, plot_type_dd], [global_state, dashboard_accordion])
405
  clear_plots_btn.click(clear_dashboard, [global_state], [global_state, dashboard_accordion])
406
 
407
- # AI Co-pilot Chat
408
- copilot_input_col_ref_for_dynamic_update = x_col_dd # Dummy placeholder for dynamic updates
409
  chat_submit_btn.click(
410
  respond_to_chat,
411
  [chat_input, chatbot, global_state, api_key_input],
 
77
  def load_and_process_file(file_obj, state_dict):
78
  """Loads a CSV, processes it, and updates the entire UI state."""
79
  if file_obj is None:
80
+ return state_dict, "Please upload a file.", *[gr.update(visible=False)] * 4
81
  try:
82
  df = pd.read_csv(file_obj.name, low_memory=False)
83
  for col in df.select_dtypes(include=['object']).columns:
 
111
  gr.update(value=f"{len(metadata['datetime_cols'])}"),
112
  gr.update(choices=metadata['columns']), gr.update(choices=metadata['columns']), gr.update(choices=metadata['columns']))
113
  except Exception as e:
114
+ return state_dict, f"❌ **Error:** {e}", *[gr.update()] * 11
115
 
116
  def extract_dataset_metadata(df: pd.DataFrame):
117
  rows, cols = df.shape
 
160
  suggestions = json.loads(response.text)
161
 
162
  # Create a button for each suggestion
163
+ buttons = [gr.Button(s, variant="secondary", visible=True) for s in suggestions]
164
+ # Pad with hidden buttons to always have 5 outputs
165
+ buttons += [gr.Button(visible=False)] * (5 - len(buttons))
166
+
167
+ return gr.update(visible=False), *buttons
168
 
169
  except Exception as e:
170
+ return f"Could not generate suggestions: {e}", *[gr.update(visible=False)]*5
171
+
172
+ def handle_suggestion_click(question_text):
173
+ """When a suggestion button is clicked, switch to the co-pilot page and populate the input."""
174
+ return (
175
+ gr.update(visible=False), # Hide cockpit
176
+ gr.update(visible=False), # Hide deep dive
177
+ gr.update(visible=True), # Show co-pilot
178
+ question_text # Populate the chat input
179
+ )
180
 
181
  # --- Page 2: Deep Dive Dashboard ---
182
  def add_plot_to_dashboard(state_dict, x_col, y_col, plot_type):
 
273
  if df_result is not None: output_updates[3] = gr.update(visible=True, value=df_result)
274
  if stdout:
275
  # Append stdout to explanation if it exists
276
+ new_explanation = (output_updates[0]['value'] if output_updates[0]['visible'] else "") + f"\n\n**Console Output:**\n```\n{stdout}\n```"
277
  output_updates[0] = gr.update(visible=True, value=new_explanation)
278
  if error:
279
  error_explanation = f"**Phoenix Co-pilot:** I encountered an error. Here's the details:\n\n`{error}`"
 
316
  with gr.Column(visible=True) as welcome_page:
317
  gr.Markdown("# Welcome to the AI Data Explorer (Phoenix UI)", elem_id="welcome-header")
318
  gr.Markdown("Please **upload a CSV file** and **enter your Gemini API key** in the sidebar to begin.")
319
+ # CORRECTED: Uses a local file, 'workflow.png', which must be in the same directory.
320
+ gr.Image(value="workflow.png", label="Workflow", show_label=False, show_download_button=False, container=False)
321
 
322
  # Page 1: Data Cockpit (Hidden initially)
323
  with gr.Column(visible=False) as cockpit_page:
 
337
  time_cols_stat = gr.Textbox("0", show_label=False, elem_classes="stat-card-value")
338
 
339
  suggestion_status = gr.Markdown(visible=True)
340
+ with gr.Accordion(label="✨ AI Smart Suggestions", open=True):
341
+ suggestion_buttons = [gr.Button(visible=False) for _ in range(5)]
342
 
343
  # Page 2: Deep Dive Dashboard Builder (Hidden initially)
344
  with gr.Column(visible=False) as deep_dive_page:
 
357
  with gr.Column(visible=False) as copilot_page:
358
  gr.Markdown("## πŸ€– AI Co-pilot")
359
  gr.Markdown("Ask complex questions in natural language. The Co-pilot will write and execute code to find the answer.")
360
+ chatbot = gr.Chatbot(height=400, label="Conversation with Co-pilot", show_copy_button=True)
361
 
 
362
  with gr.Accordion("Co-pilot's Response Details", open=True):
363
  copilot_explanation = gr.Markdown(visible=False, elem_classes="explanation-block")
364
  copilot_code = gr.Code(language="python", visible=False, label="Executed Python Code", elem_classes="code-block")
 
370
  chat_submit_btn = gr.Button("Submit", variant="primary")
371
 
372
  # --- Event Handlers ---
 
373
  pages = [cockpit_page, deep_dive_page, copilot_page]
374
  nav_buttons = [cockpit_btn, deep_dive_btn, copilot_btn]
375
 
376
  for i, btn in enumerate(nav_buttons):
377
+ btn.click(
378
+ lambda i=i: (gr.update(visible=i==0), gr.update(visible=i==1), gr.update(visible=i==2)),
379
+ outputs=pages
380
+ ).then(
381
+ lambda i=i: [gr.update(elem_classes="selected" if j==i else "") for j in range(len(nav_buttons))],
382
+ outputs=nav_buttons
383
+ )
384
 
 
385
  file_input.upload(
386
  fn=load_and_process_file,
387
  inputs=[file_input, global_state],
388
  outputs=[global_state, status_output, welcome_page, cockpit_page, deep_dive_page, copilot_page,
389
  rows_stat, cols_stat, quality_stat, time_cols_stat,
390
+ x_col_dd, y_col_dd, plot_type_dd]
391
+ ).then(
392
+ lambda: (gr.update(visible=True), gr.update(visible=False), gr.update(visible=False)), outputs=pages
393
  ).then(
394
+ lambda: (gr.update(elem_classes="selected"), gr.update(elem_classes=""), gr.update(elem_classes="")), outputs=nav_buttons
 
395
  )
396
 
 
397
  suggestion_btn.click(
398
  get_ai_suggestions,
399
  [global_state, api_key_input],
400
+ [suggestion_status, *suggestion_buttons]
 
 
 
401
  )
402
+
403
+ for btn in suggestion_buttons:
404
+ btn.click(
405
+ handle_suggestion_click,
406
+ inputs=[btn],
407
+ outputs=[cockpit_page, deep_dive_page, copilot_page, chat_input]
408
+ ).then(
409
+ lambda: (gr.update(elem_classes=""), gr.update(elem_classes=""), gr.update(elem_classes="selected")),
410
+ outputs=nav_buttons
411
+ )
412
+
 
 
413
  add_plot_btn.click(add_plot_to_dashboard, [global_state, x_col_dd, y_col_dd, plot_type_dd], [global_state, dashboard_accordion])
414
  clear_plots_btn.click(clear_dashboard, [global_state], [global_state, dashboard_accordion])
415
 
 
 
416
  chat_submit_btn.click(
417
  respond_to_chat,
418
  [chat_input, chatbot, global_state, api_key_input],