mgbam commited on
Commit
0a8cbc3
·
verified ·
1 Parent(s): 7d40c30

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +95 -98
app.py CHANGED
@@ -1,115 +1,112 @@
1
- # ui/layout.py
2
 
3
  # -*- coding: utf-8 -*-
4
  #
5
- # PROJECT: CognitiveEDA v5.0 - The QuantumLeap Intelligence Platform
6
  #
7
- # DESCRIPTION: This module defines the entire Gradio UI structure. It is now
8
- # corrected to return only the dictionary of components.
 
 
 
 
 
 
9
 
 
 
10
  import gradio as gr
 
 
 
 
11
  from core.config import settings
12
 
13
- def create_main_layout() -> dict:
14
- """
15
- Defines the Gradio UI structure and returns a dictionary of its components.
 
 
 
 
16
 
17
- This function is designed to be called within a `gr.Blocks` context.
18
 
19
- Returns:
20
- A dictionary mapping component names to their Gradio component objects.
 
21
  """
22
- # State object to hold the DataAnalyzer instance
23
- state_analyzer = gr.State()
 
 
 
 
 
 
 
24
 
25
- # --- Header ---
26
- gr.Markdown(f"<h1>{settings.APP_TITLE}</h1>")
27
- gr.Markdown("A world-class data discovery platform that provides a complete suite of EDA tools and intelligently unlocks specialized analysis modules.")
28
 
29
- # --- Input Row ---
30
- with gr.Row():
31
- upload_button = gr.File(label="1. Upload Data File (CSV, Excel)", file_types=[".csv", ".xlsx"], scale=3)
32
- analyze_button = gr.Button("✨ Generate Intelligence Report", variant="primary", scale=1)
 
 
 
33
 
34
- # --- Main Tabs ---
35
- with gr.Tabs():
36
- with gr.Tab("🤖 AI-Powered Strategy Report", id="tab_ai"):
37
- ai_report_output = gr.Markdown("### Your AI-generated report will appear here after analysis...")
38
-
39
- with gr.Tab("📋 Data Profile", id="tab_profile"):
40
- with gr.Accordion("Missing Values Report", open=False):
41
- profile_missing_df = gr.DataFrame()
42
- with gr.Accordion("Numeric Features Summary", open=True):
43
- profile_numeric_df = gr.DataFrame()
44
- with gr.Accordion("Categorical Features Summary", open=True):
45
- profile_categorical_df = gr.DataFrame()
46
 
47
- with gr.Tab("📊 Overview Visuals", id="tab_overview"):
48
- with gr.Row():
49
- plot_types = gr.Plot()
50
- plot_missing = gr.Plot()
51
- plot_correlation = gr.Plot()
52
-
53
- with gr.Tab("🎨 Interactive Explorer", id="tab_explorer"):
54
- gr.Markdown("### Univariate Analysis")
55
- with gr.Row():
56
- dd_hist_col = gr.Dropdown(label="Select Column for Histogram", interactive=True)
57
- plot_histogram = gr.Plot()
58
- gr.Markdown("### Bivariate Analysis")
59
- with gr.Row():
60
- with gr.Column(scale=1):
61
- dd_scatter_x = gr.Dropdown(label="X-Axis (Numeric)", interactive=True)
62
- dd_scatter_y = gr.Dropdown(label="Y-Axis (Numeric)", interactive=True)
63
- dd_scatter_color = gr.Dropdown(label="Color By (Optional)", interactive=True)
64
- with gr.Column(scale=2):
65
- plot_scatter = gr.Plot()
66
-
67
- with gr.Tab("🧩 Clustering (K-Means)", id="tab_cluster", visible=False) as tab_cluster:
68
- with gr.Row():
69
- with gr.Column(scale=1):
70
- num_clusters = gr.Slider(minimum=2, maximum=10, value=3, step=1, label="Number of Clusters (K)", interactive=True)
71
- md_cluster_summary = gr.Markdown()
72
- with gr.Column(scale=2):
73
- plot_cluster = gr.Plot()
74
- plot_elbow = gr.Plot()
75
-
76
- # Add other tabs as needed (Time-Series, Text)
77
- tab_timeseries = gr.Tab("⌛ Time-Series Analysis", id="tab_timeseries", visible=False)
78
- tab_text = gr.Tab("📝 Text Analysis", id="tab_text", visible=False)
 
 
 
 
79
 
80
- # Collect all components into a dictionary for easy access
81
- components = {
82
- # State
83
- "state_analyzer": state_analyzer,
84
- # Inputs
85
- "upload_button": upload_button,
86
- "analyze_button": analyze_button,
87
- # AI Tab
88
- "ai_report_output": ai_report_output,
89
- # Profile Tab
90
- "profile_missing_df": profile_missing_df,
91
- "profile_numeric_df": profile_numeric_df,
92
- "profile_categorical_df": profile_categorical_df,
93
- # Overview Tab
94
- "plot_types": plot_types,
95
- "plot_missing": plot_missing,
96
- "plot_correlation": plot_correlation,
97
- # Explorer Tab
98
- "dd_hist_col": dd_hist_col,
99
- "plot_histogram": plot_histogram,
100
- "dd_scatter_x": dd_scatter_x,
101
- "dd_scatter_y": dd_scatter_y,
102
- "dd_scatter_color": dd_scatter_color,
103
- "plot_scatter": plot_scatter,
104
- # Conditional Tabs
105
- "tab_timeseries": tab_timeseries,
106
- "tab_text": tab_text,
107
- "tab_cluster": tab_cluster,
108
- # Clustering Tab Components
109
- "num_clusters": num_clusters,
110
- "md_cluster_summary": md_cluster_summary,
111
- "plot_cluster": plot_cluster,
112
- "plot_elbow": plot_elbow,
113
- }
114
 
115
- return components
 
 
 
 
 
 
 
 
1
+ # app.py
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'
30
+ )
31
+ warnings.filterwarnings('ignore', category=FutureWarning)
32
 
 
33
 
34
+ def main():
35
+ """
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 ---
68
+ components["dd_hist_col"].change(
69
+ fn=callbacks.create_histogram,
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()