ProfessionalMario commited on
Commit
83db025
·
verified ·
1 Parent(s): f780933

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +28 -114
app.py CHANGED
@@ -1,162 +1,76 @@
1
  import os
2
  import io
3
- import sys
4
  import gradio as gr
5
  from pathlib import Path
6
  from rich.console import Console
7
 
8
- # Import your custom modules
9
  from cli_app.command_handler import handle_command
10
  import cli_app.command_handler as handler
11
- from utils.logger import logger
12
  from vector_store.instruction_embedder import embed_analyze_instructions
13
 
14
- # Global console for local CLI use
15
- console = Console()
16
-
17
  def terminal_logic(command):
18
- """
19
- Captures Rich console output and detects if an image was generated.
20
- Returns: (text_output, image_path)
21
- """
22
  output_buffer = io.StringIO()
23
- temp_console = Console(
24
- file=output_buffer,
25
- force_terminal=True,
26
- width=100,
27
- color_system=None,
28
- legacy_windows=False
29
- )
30
 
31
  old_console = getattr(handler, 'console', None)
32
  handler.console = temp_console
33
 
34
  try:
35
- if command.lower() == "exit":
36
- return "Session ended. Refresh to restart.", None
37
-
38
- # Execute logic
39
  result = handle_command(command)
40
  captured = output_buffer.getvalue()
 
41
 
42
- # --- PLOT DETECTION LOGIC ---
43
- # Look for a path in the result or captured text (e.g., "output/plot.png")
44
- # Adjust the 'output' string to match where your tool saves PNGs
45
  image_path = None
46
- if ".png" in captured or (result and ".png" in result):
47
- # Simple heuristic: find a word ending in .png
48
- words = (captured + (result or "")).split()
49
- for word in words:
50
- if word.endswith(".png") and os.path.exists(word):
51
- image_path = word
52
  break
53
-
54
- full_text = f"{captured}\n{result if result else ''}".strip()
55
- return full_text or "Command executed.", image_path
56
-
57
  except Exception as e:
58
- logger.error(f"Space Terminal Error: {e}")
59
  return f"Error: {str(e)}", None
60
  finally:
61
- if old_console:
62
- handler.console = old_console
63
 
64
  def run_space_interface():
65
- # 1. Initialize Vector Store instructions
66
  embed_analyze_instructions()
67
-
68
- # 2. AUTO-HYDRATE DATA (Detects Parquet and Pickles)
69
- # Looking in data/datasets/ because that's where your sync folder puts them
70
  data_dir = Path("data/datasets")
71
- found_data = False
72
-
73
  if data_dir.exists():
74
  for file in os.listdir(data_dir):
75
  if file.endswith((".parquet", ".pkl")) and "embeddings" not in file:
76
- try:
77
- # Simulates 'load data/datasets/filename'
78
- handler.handle_command(f"load {data_dir / file}")
79
- found_data = True
80
- except:
81
- pass
82
 
83
- # 3. Generate Help Table for Welcome Screen
84
- help_buffer = io.StringIO()
85
- help_console = Console(file=help_buffer, force_terminal=True, width=100, color_system=None)
86
-
87
- old_console = getattr(handler, 'console', None)
88
- handler.console = help_console
89
- handler.handle_command("help")
90
- welcome_table = help_buffer.getvalue()
91
- handler.console = old_console
92
-
93
- status_msg = "✅ Datasets Ready" if found_data else "⚠️ No Datasets Found. Use 'load <path>'"
94
- welcome_text = f"WELCOME TO EDA EXPLORER\n{status_msg}\n{'='*25}\n{welcome_table}"
95
-
96
- # 4. Build the Modern Terminal UI
97
- with gr.Blocks(title="EDA Explorer Terminal", theme="monochrome") as demo:
98
  gr.Markdown("# 📊 EDA Explorer Terminal")
99
 
100
  with gr.Row():
101
- with gr.Column(scale=3):
102
- output_box = gr.Code(
103
- value=welcome_text,
104
- label="Console Output",
105
- language="markdown",
106
- lines=25
107
- )
108
- with gr.Column(scale=2):
109
- plot_output = gr.Image(
110
- label="Visual Analysis",
111
- type="filepath",
112
- interactive=False
113
- )
114
 
115
- input_box = gr.Textbox(
116
- label="Command Line",
117
- placeholder="e.g., analyze titanic or histogram Age in titanic",
118
- autofocus=True
119
- )
120
 
121
  gr.Examples(
122
- examples=[
123
- ["list"],
124
- ["analyze titanic"],
125
- ["histogram Age in titanic"],
126
- ["info Customer_Churn"]
127
- ],
128
- inputs=input_box,
129
- label="Quick Actions"
130
  )
131
 
132
- # Submit triggers the logic and updates BOTH the text and the image
133
  input_box.submit(
134
  fn=terminal_logic,
135
  inputs=input_box,
136
- outputs=[output_box, plot_output]
 
137
  )
138
 
139
- demo.launch(server_name="0.0.0.0", server_port=7860)
140
-
141
- def run_cli():
142
- """Standard local terminal loop."""
143
- embed_analyze_instructions()
144
- console.print("\n[bold cyan]EDA Explorer CLI[/bold cyan]")
145
- while True:
146
- try:
147
- cmd = console.input("[bold yellow]> [/bold yellow]")
148
- if cmd.lower() == "exit": break
149
- result = handle_command(cmd)
150
- if result: console.print(result)
151
- except (KeyboardInterrupt, EOFError): break
152
- except Exception as e: console.print(f"[red]Error:[/red] {e}")
153
 
154
  if __name__ == "__main__":
155
- if "SPACE_ID" in os.environ:
156
- run_space_interface()
157
- else:
158
- run_cli()
159
-
160
-
161
-
162
-
 
1
  import os
2
  import io
 
3
  import gradio as gr
4
  from pathlib import Path
5
  from rich.console import Console
6
 
7
+ # Import your modules
8
  from cli_app.command_handler import handle_command
9
  import cli_app.command_handler as handler
 
10
  from vector_store.instruction_embedder import embed_analyze_instructions
11
 
 
 
 
12
  def terminal_logic(command):
13
+ if not command: return "", None
 
 
 
14
  output_buffer = io.StringIO()
15
+ temp_console = Console(file=output_buffer, force_terminal=True, width=100, color_system=None)
 
 
 
 
 
 
16
 
17
  old_console = getattr(handler, 'console', None)
18
  handler.console = temp_console
19
 
20
  try:
 
 
 
 
21
  result = handle_command(command)
22
  captured = output_buffer.getvalue()
23
+ combined = f"{captured}\n{str(result) if result else ''}".strip()
24
 
 
 
 
25
  image_path = None
26
+ if ".png" in combined:
27
+ for word in combined.split():
28
+ clean = word.strip(".,![]'\"")
29
+ if clean.endswith(".png") and os.path.exists(clean):
30
+ image_path = clean
 
31
  break
32
+ return f"```\n{combined}\n
33
+ ```", image_path
 
 
34
  except Exception as e:
 
35
  return f"Error: {str(e)}", None
36
  finally:
37
+ handler.console = old_console
 
38
 
39
  def run_space_interface():
 
40
  embed_analyze_instructions()
41
+
42
+ # Auto-hydrate
 
43
  data_dir = Path("data/datasets")
 
 
44
  if data_dir.exists():
45
  for file in os.listdir(data_dir):
46
  if file.endswith((".parquet", ".pkl")) and "embeddings" not in file:
47
+ try: handler.handle_command(f"load {data_dir / file}")
48
+ except: continue
 
 
 
 
49
 
50
+ with gr.Blocks(theme="monochrome", analytics_enabled=False) as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  gr.Markdown("# 📊 EDA Explorer Terminal")
52
 
53
  with gr.Row():
54
+ # Markdown is significantly safer than gr.Code for preventing schema crashes
55
+ output_box = gr.Markdown(value="```\nTerminal Ready\n```")
56
+ plot_output = gr.Image(label="Visual Analysis", type="filepath")
 
 
 
 
 
 
 
 
 
 
57
 
58
+ input_box = gr.Textbox(label="Command Line")
 
 
 
 
59
 
60
  gr.Examples(
61
+ examples=[["list"], ["NL: show top 10 rows in titanic"], ["NL: average Age in titanic"]],
62
+ inputs=input_box
 
 
 
 
 
 
63
  )
64
 
65
+ # api_name=False is the crucial fix for the "bool is not iterable" crawler error
66
  input_box.submit(
67
  fn=terminal_logic,
68
  inputs=input_box,
69
+ outputs=[output_box, plot_output],
70
+ api_name=False
71
  )
72
 
73
+ demo.launch(server_name="0.0.0.0", server_port=7860, show_api=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
  if __name__ == "__main__":
76
+ run_space_interface()