wod-analyzer / app.py
datasaur-dev's picture
Update app.py
984add3 verified
raw
history blame
5.81 kB
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
})
# Show success message with prediction
prediction = results.get("prediction", "Unknown")
gr.Info(f"Analysis completed! Overall prediction: {prediction}")
return 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")
# 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=[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,
)