mgbam commited on
Commit
f311ea6
Β·
verified Β·
1 Parent(s): 0a8cbc3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +94 -43
app.py CHANGED
@@ -2,28 +2,28 @@
2
 
3
  # -*- coding: utf-8 -*-
4
  #
5
- # PROJECT: CognitiveEDA v5.3 - The QuantumLeap Intelligence Platform
6
  #
7
- # DESCRIPTION: Main application entry point. This definitive version correctly
8
- # orchestrates UI layout, callback registration, and server launch.
 
 
9
  #
10
  # SETUP: $ pip install -r requirements.txt
11
  #
12
  # AUTHOR: An MCP & PhD Expert in Data & AI Solutions
13
- # VERSION: 5.3 (Definitive Launch Edition)
14
- # LAST-UPDATE: 2023-10-30 (Ensured main execution block and all callbacks are wired)
15
 
16
  import warnings
17
  import logging
18
  import gradio as gr
19
 
20
- # Import the UI layout and the callback LOGIC functions
21
- from ui.layout import create_main_layout
22
  from ui import callbacks
23
  from core.config import settings
24
 
25
  # --- Configuration & Setup ---
26
- # This setup MUST be in the global scope to be configured before any functions run.
27
  logging.basicConfig(
28
  level=logging.INFO,
29
  format='%(asctime)s - [%(levelname)s] - (%(filename)s:%(lineno)d) - %(message)s'
@@ -36,32 +36,100 @@ def main():
36
  Primary function to build, wire up, and launch the Gradio application.
37
  """
38
  logging.info(f"Starting {settings.APP_TITLE}")
39
-
40
- # The 'with' block creates the Gradio context. All UI and event listeners
41
- # MUST be defined within this block.
42
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="indigo"), title=settings.APP_TITLE) as demo:
43
 
44
- # 1. Build the UI from the layout module.
45
- # This returns a dictionary of all named components.
46
- components = create_main_layout()
 
 
 
 
 
 
 
 
 
 
 
 
 
47
 
48
- # 2. Register all event handlers (callbacks) within the same context.
49
- # This is the correct, robust pattern for a modular Gradio app.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
  # --- Primary Analysis Chain ---
52
- # Event 1: User clicks "Generate". This triggers the fast, initial analysis.
53
  analysis_complete_event = components["analyze_button"].click(
54
  fn=callbacks.run_initial_analysis,
55
  inputs=[components["upload_button"]],
56
  outputs=[components["state_analyzer"]]
57
  )
58
-
59
- # Event 2: Chained to the success of Event 1. This triggers the slower,
60
- # asynchronous report and visual generation.
61
  analysis_complete_event.then(
62
  fn=callbacks.generate_reports_and_visuals,
63
  inputs=[components["state_analyzer"]],
64
- outputs=components # Maps the returned dict to the components dict
65
  )
66
 
67
  # --- Interactive Explorer Callbacks ---
@@ -70,43 +138,26 @@ def main():
70
  inputs=[components["state_analyzer"], components["dd_hist_col"]],
71
  outputs=[components["plot_histogram"]]
72
  )
73
-
74
- # For the scatter plot, we need to listen to changes on all three dropdowns.
75
  scatter_inputs = [
76
- components["state_analyzer"],
77
- components["dd_scatter_x"],
78
- components["dd_scatter_y"],
79
- components["dd_scatter_color"]
80
  ]
81
  for dropdown in [components["dd_scatter_x"], components["dd_scatter_y"], components["dd_scatter_color"]]:
82
  dropdown.change(
83
- fn=callbacks.create_scatterplot,
84
- inputs=scatter_inputs,
85
- outputs=[components["plot_scatter"]]
86
  )
87
 
88
  # --- Specialized Module Callbacks ---
89
  components["num_clusters"].change(
90
  fn=callbacks.update_clustering,
91
  inputs=[components["state_analyzer"], components["num_clusters"]],
92
- outputs=[
93
- components["plot_cluster"],
94
- components["plot_elbow"],
95
- components["md_cluster_summary"]
96
- ]
97
  )
98
 
99
- # 3. Launch the application server. This line is outside the 'with' block
100
- # but is called on the 'demo' object that was defined by it. The server
101
- # will now run indefinitely, listening for requests.
102
  demo.launch(debug=False, server_name="0.0.0.0")
103
 
104
 
105
  # --- Application Entry Point ---
106
- # This is the most critical part for a runnable script. The `if __name__ == "__main__":`
107
- # check ensures that the `main()` function is called only when the script is
108
- # executed directly (not when it's imported by another script). Without this
109
- # block, the application will define the 'main' function but never run it,
110
- # leading to the "application not initialized" error.
111
  if __name__ == "__main__":
112
  main()
 
2
 
3
  # -*- coding: utf-8 -*-
4
  #
5
+ # PROJECT: CognitiveEDA v5.4 - The QuantumLeap Intelligence Platform
6
  #
7
+ # DESCRIPTION: Main application entry point. This definitive version combines UI
8
+ # layout and callback registration within a single, robust script
9
+ # to align with Gradio's context-based API design, resolving all
10
+ # previous startup errors.
11
  #
12
  # SETUP: $ pip install -r requirements.txt
13
  #
14
  # AUTHOR: An MCP & PhD Expert in Data & AI Solutions
15
+ # VERSION: 5.4 (Definitive Context-Aware Edition)
16
+ # LAST-UPDATE: 2023-10-30 (Final architectural correction)
17
 
18
  import warnings
19
  import logging
20
  import gradio as gr
21
 
22
+ # The callback LOGIC is still neatly separated
 
23
  from ui import callbacks
24
  from core.config import settings
25
 
26
  # --- Configuration & Setup ---
 
27
  logging.basicConfig(
28
  level=logging.INFO,
29
  format='%(asctime)s - [%(levelname)s] - (%(filename)s:%(lineno)d) - %(message)s'
 
36
  Primary function to build, wire up, and launch the Gradio application.
37
  """
38
  logging.info(f"Starting {settings.APP_TITLE}")
39
+
40
+ # The 'with' block creates the Gradio context. All UI and events will be defined here.
 
41
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="indigo"), title=settings.APP_TITLE) as demo:
42
 
43
+ # ======================================================================
44
+ # 1. DEFINE THE UI LAYOUT DIRECTLY WITHIN THE MAIN SCRIPT
45
+ # This is the most robust pattern and resolves all context-related errors.
46
+ # ======================================================================
47
+
48
+ # State object to hold the DataAnalyzer instance
49
+ state_analyzer = gr.State()
50
+
51
+ # --- Header ---
52
+ gr.Markdown(f"<h1>{settings.APP_TITLE}</h1>")
53
+ gr.Markdown("A world-class data discovery platform that provides a complete suite of EDA tools and intelligently unlocks specialized analysis modules.")
54
+
55
+ # --- Input Row ---
56
+ with gr.Row():
57
+ upload_button = gr.File(label="1. Upload Data File (CSV, Excel)", file_types=[".csv", ".xlsx"], scale=3)
58
+ analyze_button = gr.Button("✨ Generate Intelligence Report", variant="primary", scale=1)
59
 
60
+ # --- Main Tabs ---
61
+ with gr.Tabs():
62
+ with gr.Tab("πŸ€– AI-Powered Strategy Report", id="tab_ai"):
63
+ ai_report_output = gr.Markdown("### Your AI-generated report will appear here after analysis...")
64
+
65
+ with gr.Tab("πŸ“‹ Data Profile", id="tab_profile"):
66
+ with gr.Accordion("Missing Values Report", open=False):
67
+ profile_missing_df = gr.DataFrame()
68
+ with gr.Accordion("Numeric Features Summary", open=True):
69
+ profile_numeric_df = gr.DataFrame()
70
+ with gr.Accordion("Categorical Features Summary", open=True):
71
+ profile_categorical_df = gr.DataFrame()
72
+
73
+ with gr.Tab("πŸ“Š Overview Visuals", id="tab_overview"):
74
+ with gr.Row():
75
+ plot_types = gr.Plot()
76
+ plot_missing = gr.Plot()
77
+ plot_correlation = gr.Plot()
78
+
79
+ with gr.Tab("🎨 Interactive Explorer", id="tab_explorer"):
80
+ gr.Markdown("### Univariate Analysis")
81
+ with gr.Row():
82
+ dd_hist_col = gr.Dropdown(label="Select Column for Histogram", interactive=True)
83
+ plot_histogram = gr.Plot()
84
+ gr.Markdown("### Bivariate Analysis")
85
+ with gr.Row():
86
+ with gr.Column(scale=1):
87
+ dd_scatter_x = gr.Dropdown(label="X-Axis (Numeric)", interactive=True)
88
+ dd_scatter_y = gr.Dropdown(label="Y-Axis (Numeric)", interactive=True)
89
+ dd_scatter_color = gr.Dropdown(label="Color By (Optional)", interactive=True)
90
+ with gr.Column(scale=2):
91
+ plot_scatter = gr.Plot()
92
+
93
+ with gr.Tab("🧩 Clustering (K-Means)", id="tab_cluster", visible=False) as tab_cluster:
94
+ with gr.Row():
95
+ with gr.Column(scale=1):
96
+ num_clusters = gr.Slider(minimum=2, maximum=10, value=3, step=1, label="Number of Clusters (K)", interactive=True)
97
+ md_cluster_summary = gr.Markdown()
98
+ with gr.Column(scale=2):
99
+ plot_cluster = gr.Plot()
100
+ plot_elbow = gr.Plot()
101
+
102
+ tab_timeseries = gr.Tab("βŒ› Time-Series Analysis", id="tab_timeseries", visible=False)
103
+ tab_text = gr.Tab("πŸ“ Text Analysis", id="tab_text", visible=False)
104
+
105
+ # --- Collect all components into a dictionary for easy access ---
106
+ components = {
107
+ "state_analyzer": state_analyzer, "upload_button": upload_button, "analyze_button": analyze_button,
108
+ "ai_report_output": ai_report_output, "profile_missing_df": profile_missing_df,
109
+ "profile_numeric_df": profile_numeric_df, "profile_categorical_df": profile_categorical_df,
110
+ "plot_types": plot_types, "plot_missing": plot_missing, "plot_correlation": plot_correlation,
111
+ "dd_hist_col": dd_hist_col, "plot_histogram": plot_histogram, "dd_scatter_x": dd_scatter_x,
112
+ "dd_scatter_y": dd_scatter_y, "dd_scatter_color": dd_scatter_color, "plot_scatter": plot_scatter,
113
+ "tab_timeseries": tab_timeseries, "tab_text": tab_text, "tab_cluster": tab_cluster,
114
+ "num_clusters": num_clusters, "md_cluster_summary": md_cluster_summary,
115
+ "plot_cluster": plot_cluster, "plot_elbow": plot_elbow,
116
+ }
117
+
118
+ # ======================================================================
119
+ # 2. REGISTER EVENT HANDLERS
120
+ # Now that components is a guaranteed dictionary, this will work.
121
+ # ======================================================================
122
 
123
  # --- Primary Analysis Chain ---
 
124
  analysis_complete_event = components["analyze_button"].click(
125
  fn=callbacks.run_initial_analysis,
126
  inputs=[components["upload_button"]],
127
  outputs=[components["state_analyzer"]]
128
  )
 
 
 
129
  analysis_complete_event.then(
130
  fn=callbacks.generate_reports_and_visuals,
131
  inputs=[components["state_analyzer"]],
132
+ outputs=components
133
  )
134
 
135
  # --- Interactive Explorer Callbacks ---
 
138
  inputs=[components["state_analyzer"], components["dd_hist_col"]],
139
  outputs=[components["plot_histogram"]]
140
  )
 
 
141
  scatter_inputs = [
142
+ components["state_analyzer"], components["dd_scatter_x"],
143
+ components["dd_scatter_y"], components["dd_scatter_color"]
 
 
144
  ]
145
  for dropdown in [components["dd_scatter_x"], components["dd_scatter_y"], components["dd_scatter_color"]]:
146
  dropdown.change(
147
+ fn=callbacks.create_scatterplot, inputs=scatter_inputs, outputs=[components["plot_scatter"]]
 
 
148
  )
149
 
150
  # --- Specialized Module Callbacks ---
151
  components["num_clusters"].change(
152
  fn=callbacks.update_clustering,
153
  inputs=[components["state_analyzer"], components["num_clusters"]],
154
+ outputs=[components["plot_cluster"], components["plot_elbow"], components["md_cluster_summary"]]
 
 
 
 
155
  )
156
 
157
+ # 3. Launch the application server
 
 
158
  demo.launch(debug=False, server_name="0.0.0.0")
159
 
160
 
161
  # --- Application Entry Point ---
 
 
 
 
 
162
  if __name__ == "__main__":
163
  main()