Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,56 +1,52 @@
|
|
1 |
import gradio as gr
|
2 |
import os
|
3 |
import json
|
|
|
4 |
from data_service import DataAssessmentService
|
5 |
from sheets_integration import SheetsLogger
|
6 |
from datetime import datetime
|
7 |
|
8 |
-
# Initialize services
|
9 |
-
|
10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
|
12 |
-
#
|
13 |
DEPARTMENTS = {
|
14 |
-
"Executive Management": "
|
15 |
-
"Education Support": "
|
16 |
-
"Medicine": "
|
17 |
-
"Cardiology": "
|
18 |
-
"Gastroenterology": "
|
19 |
-
"Medical Oncology": "
|
20 |
"Hematology": "Hematology",
|
21 |
-
"Operating Room": "
|
22 |
-
"Surgery": "
|
23 |
-
"Orthopedics": "
|
24 |
-
"Obstetrics and Gynecology": "
|
25 |
-
"Ophthalmology": "
|
26 |
"Ear, Nose, and Throat": "ENT",
|
27 |
-
"Anesthesiology": "
|
28 |
-
"Emergency Medicine & EMS": "
|
29 |
-
"Pediatrics": "
|
30 |
-
"Family Medicine & Preventive Medicine": "
|
31 |
-
"Psychiatry": "
|
32 |
-
"Physical Medicine & Rehabilitation": "PM&R
|
33 |
-
"Pathology": "
|
34 |
-
"Radiology": "
|
35 |
-
"Radiation Oncology": "Onco radiology",
|
36 |
-
"Cyclotron": "Cyclotron",
|
37 |
-
"Inpatient Department": "IPD",
|
38 |
-
"Outpatient Department": "OPD",
|
39 |
-
"Pharmacy": "Pharmacy",
|
40 |
-
"Dentistry": "dentistry",
|
41 |
-
"Nutrition": "Nutrition",
|
42 |
-
"Medical Records": "เวชระเบียน",
|
43 |
-
"Finance": "การเงิน",
|
44 |
"Other": "Other"
|
45 |
}
|
46 |
|
47 |
-
# Frequency options
|
48 |
FREQUENCIES = ["One-time request", "Weekly", "Monthly"]
|
49 |
-
|
50 |
-
# Urgency options
|
51 |
URGENCY = ["Within a week", "Within a month", "Within a year"]
|
52 |
|
53 |
-
# Example requests
|
54 |
EXAMPLE_REQUESTS = """
|
55 |
### Example 1: Clinical Data Request
|
56 |
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.
|
@@ -74,44 +70,9 @@ Need Emergency Department performance data for March 2024:
|
|
74 |
Purpose: Monthly performance review and staff allocation planning.
|
75 |
"""
|
76 |
|
77 |
-
def format_user_summary(analysis_result):
|
78 |
-
"""Format analysis result into user-friendly summary"""
|
79 |
-
available = analysis_result.get("data_availability", {}).get("available_reports", [])
|
80 |
-
data_lake = analysis_result.get("data_lake_requirements", {}).get("reports_needed", [])
|
81 |
-
unavailable = analysis_result.get("unavailable_data", [])
|
82 |
-
|
83 |
-
interpretation = analysis_result.get("request_analysis", {}).get("interpretation", "")
|
84 |
-
|
85 |
-
summary = [
|
86 |
-
"### Summary of Your Request",
|
87 |
-
f"**What you need**: {interpretation}\n",
|
88 |
-
"\n**Data Availability Status:**\n"
|
89 |
-
]
|
90 |
-
|
91 |
-
if available:
|
92 |
-
summary.append("✅ **Available in Web Data System:**")
|
93 |
-
for report in available:
|
94 |
-
summary.append(f"- {report['name']}")
|
95 |
-
summary.append(f"\nEstimated processing time: 3 working days\n")
|
96 |
-
|
97 |
-
if data_lake:
|
98 |
-
summary.append("🔄 **Requires Additional Database Query:**")
|
99 |
-
for report in data_lake:
|
100 |
-
summary.append(f"- {report['report_type']}")
|
101 |
-
summary.append(f"\nEstimated processing time: 2 weeks\n")
|
102 |
-
|
103 |
-
if unavailable:
|
104 |
-
summary.append("❌ **Data Not Currently Available:**")
|
105 |
-
for item in unavailable:
|
106 |
-
summary.append(f"- {item['report_type']}")
|
107 |
-
summary.append("\nRecommendation: Schedule a meeting to discuss alternative data sources or solutions\n")
|
108 |
-
|
109 |
-
return "\n".join(summary)
|
110 |
-
|
111 |
def process_request(name, employee_id, email, department, other_dept, request_details, frequency, urgency):
|
112 |
"""Process the data request and return both user and technical responses"""
|
113 |
-
|
114 |
-
print(f"Received inputs:")
|
115 |
print(f"Name: {name}")
|
116 |
print(f"Employee ID: {employee_id}")
|
117 |
print(f"Email: {email}")
|
@@ -126,27 +87,58 @@ def process_request(name, employee_id, email, department, other_dept, request_de
|
|
126 |
print("Validation failed - missing required fields")
|
127 |
return "Please fill in all required fields.", None
|
128 |
|
129 |
-
# Combine department info
|
130 |
-
final_department = other_dept if department == "Other" else department
|
131 |
-
print(f"Final department: {final_department}")
|
132 |
-
|
133 |
try:
|
134 |
# Process the request through GPT
|
135 |
print("Calling GPT service...")
|
136 |
result = service.assess_request(request_details)
|
137 |
-
print(f"GPT response: {result}")
|
|
|
|
|
|
|
138 |
|
139 |
# Create user-friendly summary
|
140 |
-
user_summary =
|
141 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
|
143 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
sheet_data = {
|
145 |
-
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
146 |
"name": name,
|
147 |
"employee_id": employee_id,
|
148 |
"email": email,
|
149 |
-
"department":
|
150 |
"request_details": request_details,
|
151 |
"frequency": frequency,
|
152 |
"urgency": urgency,
|
@@ -154,33 +146,28 @@ def process_request(name, employee_id, email, department, other_dept, request_de
|
|
154 |
"system_analysis": json.dumps(result, ensure_ascii=False)
|
155 |
}
|
156 |
|
157 |
-
|
158 |
-
print("
|
159 |
-
success = sheets_logger.log_request(sheet_data)
|
160 |
-
print(f"Sheet logging result: {success}")
|
161 |
|
162 |
return user_summary, result
|
163 |
|
164 |
except Exception as e:
|
165 |
-
|
166 |
-
print(
|
167 |
-
print(
|
168 |
-
return
|
169 |
|
170 |
# Create Gradio interface
|
171 |
with gr.Blocks() as demo:
|
172 |
gr.Markdown("# Hospital Data Request System")
|
173 |
gr.Markdown("Please fill in the following information to request data access.")
|
174 |
|
175 |
-
# Debug output for monitoring
|
176 |
-
debug_output = gr.Markdown(visible=False)
|
177 |
-
|
178 |
with gr.Row():
|
179 |
with gr.Column():
|
180 |
name = gr.Textbox(
|
181 |
label="Full Name*",
|
182 |
placeholder="Enter your full name",
|
183 |
-
value=""
|
184 |
)
|
185 |
employee_id = gr.Textbox(
|
186 |
label="Employee ID*",
|
@@ -199,7 +186,7 @@ with gr.Blocks() as demo:
|
|
199 |
choices=list(DEPARTMENTS.keys()),
|
200 |
label="Department*",
|
201 |
info="Select your department",
|
202 |
-
value=list(DEPARTMENTS.keys())[0]
|
203 |
)
|
204 |
other_dept = gr.Textbox(
|
205 |
label="Other Department",
|
@@ -209,11 +196,8 @@ with gr.Blocks() as demo:
|
|
209 |
)
|
210 |
|
211 |
# Handle department change
|
212 |
-
def update_other_dept_visibility(dept):
|
213 |
-
return gr.update(visible=(dept == "Other"))
|
214 |
-
|
215 |
department.change(
|
216 |
-
fn=
|
217 |
inputs=department,
|
218 |
outputs=other_dept
|
219 |
)
|
@@ -235,80 +219,24 @@ with gr.Blocks() as demo:
|
|
235 |
frequency = gr.Dropdown(
|
236 |
choices=FREQUENCIES,
|
237 |
label="Request Frequency*",
|
238 |
-
value=FREQUENCIES[0]
|
239 |
)
|
240 |
urgency = gr.Dropdown(
|
241 |
choices=URGENCY,
|
242 |
label="Urgency Level*",
|
243 |
-
value=URGENCY[0]
|
244 |
)
|
245 |
|
246 |
-
# Submit button
|
247 |
-
submit_btn = gr.Button("Submit Request"
|
248 |
|
249 |
# Output sections
|
250 |
with gr.Row():
|
251 |
-
user_output = gr.Markdown(
|
252 |
-
label="Request Summary",
|
253 |
-
value=""
|
254 |
-
)
|
255 |
|
256 |
with gr.Accordion("Technical Analysis (For Data Team)", open=False):
|
257 |
tech_output = gr.JSON()
|
258 |
|
259 |
-
def process_request(name, employee_id, email, department, other_dept, request_details, frequency, urgency):
|
260 |
-
print(f"Processing request with inputs:")
|
261 |
-
print(f"Name: {name}")
|
262 |
-
print(f"Employee ID: {employee_id}")
|
263 |
-
print(f"Email: {email}")
|
264 |
-
print(f"Department: {department}")
|
265 |
-
print(f"Other Dept: {other_dept}")
|
266 |
-
print(f"Request Details: {request_details}")
|
267 |
-
print(f"Frequency: {frequency}")
|
268 |
-
print(f"Urgency: {urgency}")
|
269 |
-
|
270 |
-
# Validate inputs
|
271 |
-
if not all([name, employee_id, email, request_details, department, frequency, urgency]):
|
272 |
-
print("Validation failed - missing required fields")
|
273 |
-
return "Please fill in all required fields.", None
|
274 |
-
|
275 |
-
# Combine department info
|
276 |
-
final_department = other_dept if department == "Other" else department
|
277 |
-
|
278 |
-
try:
|
279 |
-
# Process the request through GPT
|
280 |
-
print("Calling GPT service...")
|
281 |
-
result = service.assess_request(request_details)
|
282 |
-
print(f"GPT response received: {result}")
|
283 |
-
|
284 |
-
# Create user-friendly summary
|
285 |
-
user_summary = format_user_summary(result)
|
286 |
-
|
287 |
-
# Prepare data for logging
|
288 |
-
sheet_data = {
|
289 |
-
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
290 |
-
"name": name,
|
291 |
-
"employee_id": employee_id,
|
292 |
-
"email": email,
|
293 |
-
"department": final_department,
|
294 |
-
"request_details": request_details,
|
295 |
-
"frequency": frequency,
|
296 |
-
"urgency": urgency,
|
297 |
-
"user_summary": user_summary,
|
298 |
-
"system_analysis": json.dumps(result, ensure_ascii=False)
|
299 |
-
}
|
300 |
-
|
301 |
-
# Log to Google Sheets
|
302 |
-
print("Logging to sheets...")
|
303 |
-
sheets_logger.log_request(sheet_data)
|
304 |
-
|
305 |
-
return user_summary, result
|
306 |
-
|
307 |
-
except Exception as e:
|
308 |
-
error_msg = f"Error processing request: {str(e)}"
|
309 |
-
print(error_msg)
|
310 |
-
return error_msg, None
|
311 |
-
|
312 |
# Connect the submit button to the process function
|
313 |
submit_btn.click(
|
314 |
fn=process_request,
|
|
|
1 |
import gradio as gr
|
2 |
import os
|
3 |
import json
|
4 |
+
import traceback
|
5 |
from data_service import DataAssessmentService
|
6 |
from sheets_integration import SheetsLogger
|
7 |
from datetime import datetime
|
8 |
|
9 |
+
# Initialize services with error handling
|
10 |
+
try:
|
11 |
+
print("Initializing services...")
|
12 |
+
service = DataAssessmentService(api_key=os.environ.get("OPENAI_API_KEY"))
|
13 |
+
sheets_logger = SheetsLogger()
|
14 |
+
print("Services initialized successfully")
|
15 |
+
except Exception as e:
|
16 |
+
print(f"Error initializing services: {str(e)}")
|
17 |
+
print(traceback.format_exc())
|
18 |
+
raise
|
19 |
|
20 |
+
# Constants
|
21 |
DEPARTMENTS = {
|
22 |
+
"Executive Management": "Executive Administration",
|
23 |
+
"Education Support": "Education Support",
|
24 |
+
"Medicine": "Medicine",
|
25 |
+
"Cardiology": "Cardiology",
|
26 |
+
"Gastroenterology": "Gastroenterology",
|
27 |
+
"Medical Oncology": "Medical Oncology",
|
28 |
"Hematology": "Hematology",
|
29 |
+
"Operating Room": "Operating Room",
|
30 |
+
"Surgery": "Surgery",
|
31 |
+
"Orthopedics": "Orthopedics",
|
32 |
+
"Obstetrics and Gynecology": "Obstetrics and Gynecology",
|
33 |
+
"Ophthalmology": "Ophthalmology",
|
34 |
"Ear, Nose, and Throat": "ENT",
|
35 |
+
"Anesthesiology": "Anesthesiology",
|
36 |
+
"Emergency Medicine & EMS": "Emergency Medicine",
|
37 |
+
"Pediatrics": "Pediatrics",
|
38 |
+
"Family Medicine & Preventive Medicine": "Family Medicine",
|
39 |
+
"Psychiatry": "Psychiatry",
|
40 |
+
"Physical Medicine & Rehabilitation": "PM&R",
|
41 |
+
"Pathology": "Pathology",
|
42 |
+
"Radiology": "Radiology",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
"Other": "Other"
|
44 |
}
|
45 |
|
|
|
46 |
FREQUENCIES = ["One-time request", "Weekly", "Monthly"]
|
|
|
|
|
47 |
URGENCY = ["Within a week", "Within a month", "Within a year"]
|
48 |
|
49 |
+
# Example requests for reference
|
50 |
EXAMPLE_REQUESTS = """
|
51 |
### Example 1: Clinical Data Request
|
52 |
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.
|
|
|
70 |
Purpose: Monthly performance review and staff allocation planning.
|
71 |
"""
|
72 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
def process_request(name, employee_id, email, department, other_dept, request_details, frequency, urgency):
|
74 |
"""Process the data request and return both user and technical responses"""
|
75 |
+
print("\nProcessing new request:")
|
|
|
76 |
print(f"Name: {name}")
|
77 |
print(f"Employee ID: {employee_id}")
|
78 |
print(f"Email: {email}")
|
|
|
87 |
print("Validation failed - missing required fields")
|
88 |
return "Please fill in all required fields.", None
|
89 |
|
|
|
|
|
|
|
|
|
90 |
try:
|
91 |
# Process the request through GPT
|
92 |
print("Calling GPT service...")
|
93 |
result = service.assess_request(request_details)
|
94 |
+
print(f"GPT service response received: {result}")
|
95 |
+
|
96 |
+
if "error" in result:
|
97 |
+
return f"Error analyzing request: {result['error']}", None
|
98 |
|
99 |
# Create user-friendly summary
|
100 |
+
user_summary = f"""
|
101 |
+
### Data Request Summary
|
102 |
+
**From:** {name} ({department})
|
103 |
+
**Request Type:** {frequency} | Urgency: {urgency}
|
104 |
+
|
105 |
+
**Analysis:**
|
106 |
+
{result.get('request_analysis', {}).get('interpretation', 'No interpretation available')}
|
107 |
+
|
108 |
+
**Data Availability:**
|
109 |
+
"""
|
110 |
|
111 |
+
# Add available reports
|
112 |
+
available = result.get('data_availability', {}).get('available_reports', [])
|
113 |
+
if available:
|
114 |
+
user_summary += "\n✅ **Available in Web Data:**\n"
|
115 |
+
for report in available:
|
116 |
+
user_summary += f"- {report['name']}\n"
|
117 |
+
user_summary += "\nEstimated processing time: 3 working days\n"
|
118 |
+
|
119 |
+
# Add data lake requirements
|
120 |
+
data_lake = result.get('data_lake_requirements', {}).get('reports_needed', [])
|
121 |
+
if data_lake:
|
122 |
+
user_summary += "\n🔄 **Requires Additional Database Query:**\n"
|
123 |
+
for report in data_lake:
|
124 |
+
user_summary += f"- {report['report_type']}\n"
|
125 |
+
user_summary += "\nEstimated processing time: 2 weeks\n"
|
126 |
+
|
127 |
+
# Add unavailable data
|
128 |
+
unavailable = result.get('unavailable_data', [])
|
129 |
+
if unavailable:
|
130 |
+
user_summary += "\n❌ **Data Not Currently Available:**\n"
|
131 |
+
for item in unavailable:
|
132 |
+
user_summary += f"- {item['report_type']}\n"
|
133 |
+
user_summary += "\nRecommendation: Schedule a meeting to discuss alternatives\n"
|
134 |
+
|
135 |
+
# Log to sheets
|
136 |
+
print("Logging to Google Sheets...")
|
137 |
sheet_data = {
|
|
|
138 |
"name": name,
|
139 |
"employee_id": employee_id,
|
140 |
"email": email,
|
141 |
+
"department": other_dept if department == "Other" else department,
|
142 |
"request_details": request_details,
|
143 |
"frequency": frequency,
|
144 |
"urgency": urgency,
|
|
|
146 |
"system_analysis": json.dumps(result, ensure_ascii=False)
|
147 |
}
|
148 |
|
149 |
+
sheets_logger.log_request(sheet_data)
|
150 |
+
print("Request logged successfully")
|
|
|
|
|
151 |
|
152 |
return user_summary, result
|
153 |
|
154 |
except Exception as e:
|
155 |
+
error_msg = f"Error processing request: {str(e)}"
|
156 |
+
print(error_msg)
|
157 |
+
print(traceback.format_exc())
|
158 |
+
return error_msg, None
|
159 |
|
160 |
# Create Gradio interface
|
161 |
with gr.Blocks() as demo:
|
162 |
gr.Markdown("# Hospital Data Request System")
|
163 |
gr.Markdown("Please fill in the following information to request data access.")
|
164 |
|
|
|
|
|
|
|
165 |
with gr.Row():
|
166 |
with gr.Column():
|
167 |
name = gr.Textbox(
|
168 |
label="Full Name*",
|
169 |
placeholder="Enter your full name",
|
170 |
+
value=""
|
171 |
)
|
172 |
employee_id = gr.Textbox(
|
173 |
label="Employee ID*",
|
|
|
186 |
choices=list(DEPARTMENTS.keys()),
|
187 |
label="Department*",
|
188 |
info="Select your department",
|
189 |
+
value=list(DEPARTMENTS.keys())[0]
|
190 |
)
|
191 |
other_dept = gr.Textbox(
|
192 |
label="Other Department",
|
|
|
196 |
)
|
197 |
|
198 |
# Handle department change
|
|
|
|
|
|
|
199 |
department.change(
|
200 |
+
fn=lambda x: gr.update(visible=(x == "Other")),
|
201 |
inputs=department,
|
202 |
outputs=other_dept
|
203 |
)
|
|
|
219 |
frequency = gr.Dropdown(
|
220 |
choices=FREQUENCIES,
|
221 |
label="Request Frequency*",
|
222 |
+
value=FREQUENCIES[0]
|
223 |
)
|
224 |
urgency = gr.Dropdown(
|
225 |
choices=URGENCY,
|
226 |
label="Urgency Level*",
|
227 |
+
value=URGENCY[0]
|
228 |
)
|
229 |
|
230 |
+
# Submit button
|
231 |
+
submit_btn = gr.Button("Submit Request")
|
232 |
|
233 |
# Output sections
|
234 |
with gr.Row():
|
235 |
+
user_output = gr.Markdown(label="Request Summary")
|
|
|
|
|
|
|
236 |
|
237 |
with gr.Accordion("Technical Analysis (For Data Team)", open=False):
|
238 |
tech_output = gr.JSON()
|
239 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
# Connect the submit button to the process function
|
241 |
submit_btn.click(
|
242 |
fn=process_request,
|