File size: 3,044 Bytes
d9ea3f9
 
60da408
c9ba3ae
d9ea3f9
c9ba3ae
51dfd28
 
 
0d6622c
 
c9ba3ae
d9ea3f9
51dfd28
 
60da408
 
 
51dfd28
60da408
51dfd28
d9ea3f9
51dfd28
 
0d6622c
6eb2933
d9ea3f9
 
 
 
c9ba3ae
60da408
0d6622c
d9ea3f9
 
51dfd28
d9ea3f9
 
 
51dfd28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0d6622c
c9ba3ae
d9ea3f9
 
f9d0aef
60da408
 
d9ea3f9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# app.py

# -*- coding: utf-8 -*-
#
# PROJECT:      CognitiveEDA v5.0 - The QuantumLeap Intelligence Platform
#
# DESCRIPTION:  Main application entry point. This script now correctly
#               orchestrates UI layout and callback registration within the
#               same Gradio Blocks context.
#
# SETUP:        $ pip install -r requirements.txt
#
# AUTHOR:       An MCP & PhD Expert in Data & AI Solutions
# VERSION:      5.1 (Context-Aware Edition: Architectural Fix)
# LAST-UPDATE:  2023-10-30 (Corrected Gradio context handling)

import warnings
import logging
import gradio as gr

# Import the UI layout and the callback LOGIC functions
from ui.layout import create_main_layout
from ui import callbacks
from core.config import settings

# --- Configuration & Setup ---
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - [%(levelname)s] - (%(filename)s:%(lineno)d) - %(message)s'
)
warnings.filterwarnings('ignore', category=FutureWarning)


def main():
    """
    Primary function to build, wire up, and launch the Gradio application.
    """
    logging.info(f"Starting {settings.APP_TITLE}")
    
    # Create the top-level Blocks context. All UI and events will be defined here.
    with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="indigo"), title=settings.APP_TITLE) as demo:
        # 1. Build the UI from the layout module.
        # This function now only creates the components and returns them.
        components = create_main_layout()

        # 2. Register all event handlers (callbacks) within the same context.
        # This is the correct pattern. We attach listeners to the components
        # that were just created.

        # We chain the events for a better user experience.
        # First click -> generates the analyzer.
        # Then, the change in the analyzer state -> generates the visuals.
        analysis_complete_event = components["analyze_button"].click(
            fn=callbacks.run_full_analysis,
            inputs=[components["upload_button"]],
            outputs=[components["state_analyzer"]]
        )

        # The .then() event is triggered only after the .click() event successfully completes.
        analysis_complete_event.then(
            fn=callbacks.generate_reports_and_visuals,
            inputs=[components["state_analyzer"]],
            # The outputs dictionary keys must match the component dictionary keys
            outputs=list(components.values())
        )

        # Register other interactive callbacks
        components["num_clusters"].change(
            fn=callbacks.update_clustering,
            inputs=[components["state_analyzer"], components["num_clusters"]],
            outputs=[components["plot_cluster"], components["plot_elbow"], components["md_cluster_summary"]]
        )
        
        # (Add other .change() or .click() listeners for scatter plots, histograms, etc. here)


    # 3. Launch the application
    demo.launch(debug=True, server_name="0.0.0.0")


if __name__ == "__main__":
    main()