# 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()