# interface/app.py import gradio as gr from typing import List, Dict from .handlers import process_inputs from .display import format_results from .utils import validate_inputs from config.settings import config from .handlers import ProcessingHandler from .utils import InputValidator def create_interface(): """Create the Gradio interface""" handler = ProcessingHandler() # Create interface components with gr.Blocks(title="Image Inspection analysis") as app: gr.Markdown("# Image Inspection analysis System") with gr.Row(): # Input components with gr.Column(): query = gr.Textbox( label="What would you like to analyze?", placeholder="e.g., Check safety issues in pump systems", lines=3 ) constraints = gr.Textbox( label="Any specific constraints? (optional)", placeholder="e.g., Exclude routine maintenance issues", lines=2 ) top_k = gr.Slider( minimum=1, maximum=10, value=5, step=1, label="Number of top results to show" ) report_format = gr.Radio( choices=["summary", "detailed"], value="summary", label="Report Format" ) images = gr.File( file_count="multiple", label="Upload Images", file_types=["image"] ) submit_btn = gr.Button("Analyze", variant="primary") # Right column - Outputs with gr.Column(): with gr.Tab("Results"): analysis_status = gr.Markdown("Ready for analysis...") results_box = gr.Markdown( visible=False, label="Analysis Results" ) selected_images = gr.Gallery( label="Selected Relevant Images", visible=False, columns=2, height=400 ) confidence_scores = gr.Json( label="Confidence Scores", visible=False ) with gr.Tab("Processing Details"): processing_status = gr.JSON( label="Processing Steps", visible=False ) with gr.Tab("Errors"): error_box = gr.Markdown( visible=False ) # Second: Helper functions for UI updates def update_ui_on_error(error_msg): return { results_box: gr.update(visible=True, value=error_msg), selected_images: gr.update(visible=False), confidence_scores: gr.update(visible=False), processing_status: gr.update(visible=True, value={'status': 'error'}) } def update_ui_on_success(results): return { results_box: gr.update(visible=True, value=results['content']), selected_images: gr.update(visible=True, value=results['images']), confidence_scores: gr.update(visible=True, value=results['scores']), processing_status: gr.update(visible=True, value={'status': 'success'}) } def validate_and_process(query, constraints, images, top_k, report_format): # Validate inputs is_valid, error_message = InputValidator.validate_inputs( query, constraints, images ) if not is_valid: return update_ui_on_error(error_message) # If valid, proceed with processing return handler.process_inputs( query, constraints, images, top_k, report_format ) # Single submit button with combined functionality #submit_btn = gr.Button("Analyze", variant="primary") # # Connect submit button to both clear and process # submit_btn.click( # fn=lambda: [ # gr.Markdown.update(visible=True, value="Validating inputs......"), # gr.Markdown.update(visible=False), # gr.Gallery.update(visible=False), # gr.Json.update(visible=False), # gr.JSON.update(visible=False) # ], # inputs=None, # outputs=[analysis_status, results_box, selected_images, # confidence_scores, processing_status] # ).then( # Chain the processing after clearing # fn=validate_and_process, # inputs=[query, constraints, images, top_k, report_format], # outputs=[results_box, selected_images, confidence_scores, processing_status], # #show_progress=True # ).then( # # Third: Update UI based on results # fn=lambda results: update_ui_on_success(results) if results['status'] == 'success' # else update_ui_on_error(results['error']), # inputs=[processing_status], # outputs=[results_box, selected_images, confidence_scores, processing_status] # ) progress_message = gr.Markdown("Ready to analyze...") # Update the click handler submit_btn.click( # First update UI to show processing state fn=lambda: ( gr.update(visible=True, value="⏳ Processing your request..."), # progress message gr.update(visible=False), # results gr.update(visible=False), # images gr.update(visible=False), # scores gr.update(visible=True, value={"status": "started", "step": "initializing"}) # status ), inputs=None, outputs=[ progress_message, results_box, selected_images, confidence_scores, processing_status ] ).then( # Process inputs fn=handler.process_inputs, inputs=[ query, constraints, images, top_k, report_format ], outputs=[ results_box, selected_images, confidence_scores, processing_status ], show_progress="full" # Show gradio's built-in progress ).then( # Update UI after processing fn=lambda: gr.update(visible=True, value="✅ Analysis complete!"), inputs=None, outputs=progress_message ) # Add error handling feedback progress_message.change( fn=lambda x: gr.update(visible=True) if "Error" in str(x) else gr.update(visible=False), inputs=[progress_message], outputs=[progress_message] ) # submit_btn.click( # # First clear/reset outputs # fn=lambda: ( # "Processing...", # for results_box # None, # for selected_images # None, # for confidence_scores # {"status": "processing"} # for processing_status # ), # inputs=None, # outputs=[ # results_box, # selected_images, # confidence_scores, # processing_status # ] # ).then( # Then process inputs # fn=handler.process_inputs, # inputs=[ # query, # constraints, # images, # top_k, # report_format # ], # outputs=[ # results_box, # selected_images, # confidence_scores, # processing_status # ] # ) return app # Launch the interface if __name__ == "__main__": interface = create_interface() interface.launch()