import gradio as gr import os import json from data_service import DataAssessmentService from sheets_integration import SheetsLogger from datetime import datetime # Initialize services service = DataAssessmentService(api_key=os.environ.get("OPENAI_API_KEY")) sheets_logger = SheetsLogger() # Department mapping from abbreviations to full names DEPARTMENTS = { "Executive Management": "บริหาร ผอ รอง ผู้ช่วย", "Education Support": "สนับสนุนการศึกษา", "Medicine": "MED", "Cardiology": "Cardio", "Gastroenterology": "GI", "Medical Oncology": "Onco MED", "Hematology": "Hematology", "Operating Room": "OR", "Surgery": "Sx", "Orthopedics": "Ortho", "Obstetrics and Gynecology": "OBgyne", "Ophthalmology": "Oph", "Ear, Nose, and Throat": "ENT", "Anesthesiology": "Anes", "Emergency Medicine & EMS": "ER and EMS", "Pediatrics": "PED", "Family Medicine & Preventive Medicine": "GP Fammed preventive med", "Psychiatry": "Psych", "Physical Medicine & Rehabilitation": "PM&R Physiotherapy", "Pathology": "Patho", "Radiology": "Xray", "Radiation Oncology": "Onco radiology", "Cyclotron": "Cyclotron", "Inpatient Department": "IPD", "Outpatient Department": "OPD", "Pharmacy": "Pharmacy", "Dentistry": "dentistry", "Nutrition": "Nutrition", "Medical Records": "เวชระเบียน", "Finance": "การเงิน", "Other": "Other" } # Frequency options FREQUENCIES = ["One-time request", "Weekly", "Monthly"] # Urgency options URGENCY = ["Within a week", "Within a month", "Within a year"] # Example requests EXAMPLE_REQUESTS = """ ### Example 1: Clinical Data Request I need OPD patient statistics for the Cardiology department from January to June 2024, including daily patient volume, types of cardiac conditions (ICD-10 codes), average waiting times, and number of follow-up vs. new cases. This data will be used for department capacity planning and resource allocation. ### Example 2: Quality Improvement Request Requesting waiting time analysis for all OPD clinics for Q1 2024, including: - Registration to first nurse contact time - Nurse station to doctor examination time - Doctor examination duration - Time at pharmacy - Total visit duration Break down by day of week and time slots (morning/afternoon). This data will help identify service bottlenecks. ### Example 3: Department Performance Analysis Need Emergency Department performance data for March 2024: - Daily patient volume by triage level - Door-to-doctor times - Length of stay in ED - Admission rates - Transfer rates to other departments Purpose: Monthly performance review and staff allocation planning. """ def format_user_summary(analysis_result): """Format analysis result into user-friendly summary""" available = analysis_result.get("data_availability", {}).get("available_reports", []) data_lake = analysis_result.get("data_lake_requirements", {}).get("reports_needed", []) unavailable = analysis_result.get("unavailable_data", []) interpretation = analysis_result.get("request_analysis", {}).get("interpretation", "") summary = [ "### Summary of Your Request", f"**What you need**: {interpretation}\n", "\n**Data Availability Status:**\n" ] if available: summary.append("✅ **Available in Web Data System:**") for report in available: summary.append(f"- {report['name']}") summary.append(f"\nEstimated processing time: 3 working days\n") if data_lake: summary.append("🔄 **Requires Additional Database Query:**") for report in data_lake: summary.append(f"- {report['report_type']}") summary.append(f"\nEstimated processing time: 2 weeks\n") if unavailable: summary.append("❌ **Data Not Currently Available:**") for item in unavailable: summary.append(f"- {item['report_type']}") summary.append("\nRecommendation: Schedule a meeting to discuss alternative data sources or solutions\n") return "\n".join(summary) def process_request(name, employee_id, email, department, other_dept, request_details, frequency, urgency): """Process the data request and return both user and technical responses""" # Debug prints print(f"Received inputs:") print(f"Name: {name}") print(f"Employee ID: {employee_id}") print(f"Email: {email}") print(f"Department: {department}") print(f"Other Dept: {other_dept}") print(f"Request Details: {request_details}") print(f"Frequency: {frequency}") print(f"Urgency: {urgency}") # Validate inputs if not all([name, employee_id, email, request_details, department, frequency, urgency]): print("Validation failed - missing required fields") return "Please fill in all required fields.", None # Combine department info final_department = other_dept if department == "Other" else department print(f"Final department: {final_department}") try: # Process the request through GPT print("Calling GPT service...") result = service.assess_request(request_details) print(f"GPT response: {result}") # Create user-friendly summary user_summary = format_user_summary(result) print(f"Generated summary: {user_summary}") # Prepare data for logging sheet_data = { "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "name": name, "employee_id": employee_id, "email": email, "department": final_department, "request_details": request_details, "frequency": frequency, "urgency": urgency, "user_summary": user_summary, "system_analysis": json.dumps(result, ensure_ascii=False) } # Log to Google Sheets print("Logging to sheets...") success = sheets_logger.log_request(sheet_data) print(f"Sheet logging result: {success}") return user_summary, result except Exception as e: error_message = f"Error processing request: {str(e)}" print(f"Error occurred: {error_message}") print(f"Full exception: {traceback.format_exc()}") return error_message, None # Create Gradio interface with gr.Blocks() as demo: gr.Markdown("# Hospital Data Request System") gr.Markdown("Please fill in the following information to request data access.") # Debug output for monitoring debug_output = gr.Markdown(visible=False) with gr.Row(): with gr.Column(): name = gr.Textbox( label="Full Name*", placeholder="Enter your full name", value="" # Ensure empty initial value ) employee_id = gr.Textbox( label="Employee ID*", placeholder="Enter your employee ID", value="" ) email = gr.Textbox( label="Email*", placeholder="Enter your email for contact", value="" ) with gr.Row(): with gr.Column(): department = gr.Dropdown( choices=list(DEPARTMENTS.keys()), label="Department*", info="Select your department", value=list(DEPARTMENTS.keys())[0] # Set default value ) other_dept = gr.Textbox( label="Other Department", placeholder="Specify your department if not in the list", visible=False, value="" ) # Handle department change def update_other_dept_visibility(dept): return gr.update(visible=(dept == "Other")) department.change( fn=update_other_dept_visibility, inputs=department, outputs=other_dept ) # Example requests section with gr.Accordion("📝 Click here to see example requests", open=False): gr.Markdown(EXAMPLE_REQUESTS) with gr.Row(): request_details = gr.Textbox( label="Request Details*", placeholder="Please describe in detail what data you need, including time period, specific parameters, etc.", lines=5, value="" ) with gr.Row(): with gr.Column(): frequency = gr.Dropdown( choices=FREQUENCIES, label="Request Frequency*", value=FREQUENCIES[0] # Set default value ) urgency = gr.Dropdown( choices=URGENCY, label="Urgency Level*", value=URGENCY[0] # Set default value ) # Submit button and processing submit_btn = gr.Button("Submit Request", variant="primary") # Output sections with gr.Row(): user_output = gr.Markdown( label="Request Summary", value="" ) with gr.Accordion("Technical Analysis (For Data Team)", open=False): tech_output = gr.JSON() def process_request(name, employee_id, email, department, other_dept, request_details, frequency, urgency): print(f"Processing request with inputs:") print(f"Name: {name}") print(f"Employee ID: {employee_id}") print(f"Email: {email}") print(f"Department: {department}") print(f"Other Dept: {other_dept}") print(f"Request Details: {request_details}") print(f"Frequency: {frequency}") print(f"Urgency: {urgency}") # Validate inputs if not all([name, employee_id, email, request_details, department, frequency, urgency]): print("Validation failed - missing required fields") return "Please fill in all required fields.", None # Combine department info final_department = other_dept if department == "Other" else department try: # Process the request through GPT print("Calling GPT service...") result = service.assess_request(request_details) print(f"GPT response received: {result}") # Create user-friendly summary user_summary = format_user_summary(result) # Prepare data for logging sheet_data = { "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "name": name, "employee_id": employee_id, "email": email, "department": final_department, "request_details": request_details, "frequency": frequency, "urgency": urgency, "user_summary": user_summary, "system_analysis": json.dumps(result, ensure_ascii=False) } # Log to Google Sheets print("Logging to sheets...") sheets_logger.log_request(sheet_data) return user_summary, result except Exception as e: error_msg = f"Error processing request: {str(e)}" print(error_msg) return error_msg, None # Connect the submit button to the process function submit_btn.click( fn=process_request, inputs=[ name, employee_id, email, department, other_dept, request_details, frequency, urgency ], outputs=[user_output, tech_output] ) gr.Markdown(""" ### Notes: - Fields marked with * are required - Please provide detailed information about the data you need - Include specific time periods and parameters - Clearly state the purpose of your request - All communications will be sent to the provided email """) if __name__ == "__main__": demo.launch()