import os import json import gradio as gr import pandas as pd from python_request import process_wod_document from dummy import output_test # --- Authentication Function --- def authenticate_user(username, password): """ Simple authentication function. In production, you should use more secure methods like hashed passwords. """ return username == "demo" and password == os.environ["PASSWORD"] # --- Core Application Logic --- def analyze_wod(file_obj, wod_type): """ This function analyzes a Work Order Document using the remote API. Args: file_obj: The uploaded file object from Gradio. wod_type: The selected type of Work Order Document. Returns: A pandas DataFrame with the analysis results. """ # Check if user has selected a valid WOD type if wod_type == "-- WOD type --" or wod_type is None: # Show warning dialog and return empty DataFrame gr.Warning("Please select a WOD type first!") return "", pd.DataFrame() # Check if file is uploaded if file_obj is None: gr.Warning("Please upload a PDF file first!") return "", pd.DataFrame() print(f"Analyzing '{file_obj.name}' (Type: {wod_type})...") try: # In modern Gradio versions, file_obj is already a path string # We can use it directly or get the path from it if hasattr(file_obj, 'name') and os.path.isfile(file_obj.name): # file_obj has a .name attribute pointing to the temporary file temp_file_path = file_obj.name cleanup_needed = False else: # Fallback: assume file_obj is a path string temp_file_path = str(file_obj) cleanup_needed = False # Process the document using the API api_response = process_wod_document(temp_file_path, wod_type) # api_response = json.loads(output_test) # Clean up temporary file if we created one if cleanup_needed: os.unlink(temp_file_path) # Check if API call was successful if api_response.get("status") != "success": error_msg = api_response.get("message", "Unknown error occurred") gr.Error(f"API Error: {error_msg}") return "", pd.DataFrame() # Parse the API response results = api_response.get("results", {}) summary = results.get("summary", {}) # Convert API response to DataFrame format requirements = [] reasons = [] statuses = [] for requirement_name, details in summary.items(): requirements.append(requirement_name) reasons.append(details.get("reasoning", "")) # Convert true/false to PASS/FAIL status_bool = details.get("status", "false") if isinstance(status_bool, str): status = "PASS" if status_bool.lower() == "true" else "FAIL" else: status = "PASS" if status_bool else "FAIL" statuses.append(status) # Create DataFrame df = pd.DataFrame({ "Requirement": requirements, "Reason": reasons, "Status": statuses }) # Get prediction for display prediction = results.get("prediction", "Unknown") gr.Info(f"Analysis completed! Overall prediction: {prediction}") # Format prediction as centered H1 for display prediction_display = f"

{prediction}

" if prediction != "Unknown" else "" return prediction_display, df except Exception as e: error_msg = f"Error processing document: {str(e)}" print(error_msg) gr.Error(error_msg) return "", pd.DataFrame() # --- Gradio User Interface Definition --- # Using gr.Blocks() for a custom layout that matches the elegant design. with gr.Blocks( #theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"), theme=gr.themes.Default(primary_hue="blue", secondary_hue="sky"), css=".gradio-container {max-width: 960px !important; margin: auto !important;}" ) as demo: # Main Title and Description gr.Markdown( """ # WOD Analyzer Upload a Work Order Document to automatically check for requirements. """ ) # Input Section with gr.Row(): # File Upload Component file_input = gr.File(label="Upload WOD PDF") # Dropdown for WOD Type type_input = gr.Dropdown( ["-- WOD type --", "REPLACEMENT", "THERMAL", "VISIT", "PREVENTIVE_MAINTENANCE", "INSTALLATION", "WITHDRAWAL"], label="Type", value="-- WOD type --", info="Select the type of work order." ) # Action Button analyze_btn = gr.Button("Analyze Document", variant="primary") # Results Section gr.Markdown("---") gr.Markdown("## Results") # Prediction display (centered H1) prediction_output = gr.Markdown(value="", visible=True) # DataFrame to display the output, with styling for the 'Status' column results_output = gr.DataFrame( headers=["Requirement", "Reason", "Status"], datatype=["str", "str", "str"], interactive=False, max_height=1250, column_widths=[30, 60, 10], wrap=True ) # Define the interaction: clicking the button calls the function analyze_btn.click( fn=analyze_wod, inputs=[file_input, type_input], outputs=[prediction_output, results_output] ) # --- Launch the Application with Authentication --- if __name__ == "__main__": # The launch() command creates a web server with authentication enabled # Users must provide the correct username and password to access the app # demo.launch(debug=True) demo.launch( auth=authenticate_user, # Enable authentication auth_message="Please enter your credentials to access the WOD Analyzer", share=True, ssr_mode=False, )