Spaces:
Sleeping
Sleeping
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, | |
) |