updated the code script ✅✅
Browse files- mediSync/app.py +158 -26
mediSync/app.py
CHANGED
|
@@ -396,6 +396,27 @@ import matplotlib.pyplot as plt
|
|
| 396 |
from PIL import Image
|
| 397 |
import json
|
| 398 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 399 |
# Add parent directory to path
|
| 400 |
parent_dir = os.path.dirname(os.path.abspath(__file__))
|
| 401 |
sys.path.append(parent_dir)
|
|
@@ -747,16 +768,39 @@ def complete_appointment(appointment_id):
|
|
| 747 |
dict: Response from the API
|
| 748 |
"""
|
| 749 |
try:
|
| 750 |
-
#
|
| 751 |
-
|
|
|
|
| 752 |
payload = {"appointment_id": appointment_id}
|
| 753 |
|
| 754 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 755 |
|
| 756 |
-
|
| 757 |
-
|
| 758 |
-
|
| 759 |
-
|
|
|
|
| 760 |
|
| 761 |
except Exception as e:
|
| 762 |
logger.error(f"Error completing appointment: {e}")
|
|
@@ -813,13 +857,28 @@ def create_interface():
|
|
| 813 |
4. Click "End Consultation" when finished to complete your appointment
|
| 814 |
""")
|
| 815 |
|
| 816 |
-
# Add appointment ID input
|
| 817 |
with gr.Row():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 818 |
appointment_id_input = gr.Textbox(
|
| 819 |
label="Appointment ID",
|
| 820 |
placeholder="Enter your appointment ID here...",
|
| 821 |
info="This will be automatically populated if you came from the doctors page",
|
| 822 |
-
value=
|
| 823 |
)
|
| 824 |
|
| 825 |
with gr.Tab("Multimodal Analysis"):
|
|
@@ -958,15 +1017,22 @@ def create_interface():
|
|
| 958 |
result = complete_appointment(appointment_id.strip())
|
| 959 |
|
| 960 |
if result["status"] == "success":
|
|
|
|
|
|
|
|
|
|
| 961 |
# Create success message with redirect button
|
| 962 |
html_response = f"""
|
| 963 |
<div style='color: green; padding: 15px; background-color: #e6ffe6; border-radius: 5px; margin: 10px 0;'>
|
| 964 |
<h3>✅ Consultation Completed Successfully!</h3>
|
| 965 |
<p>{result['message']}</p>
|
| 966 |
<p>Your appointment has been marked as completed.</p>
|
| 967 |
-
<button onclick="window.open('
|
| 968 |
style="background-color: #007bff; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; margin-top: 10px;">
|
| 969 |
-
Return to Doctors Page
|
|
|
|
|
|
|
|
|
|
|
|
|
| 970 |
</button>
|
| 971 |
</div>
|
| 972 |
"""
|
|
@@ -1014,29 +1080,97 @@ def create_interface():
|
|
| 1014 |
// Function to populate appointment ID from URL
|
| 1015 |
function populateAppointmentId() {
|
| 1016 |
var appointmentId = getUrlParameter('appointment_id');
|
|
|
|
|
|
|
| 1017 |
if (appointmentId) {
|
| 1018 |
-
//
|
| 1019 |
-
var
|
| 1020 |
-
|
| 1021 |
-
|
| 1022 |
-
|
| 1023 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1024 |
}
|
| 1025 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1026 |
}
|
| 1027 |
}
|
| 1028 |
|
| 1029 |
// Run when page loads
|
| 1030 |
document.addEventListener('DOMContentLoaded', function() {
|
| 1031 |
-
|
|
|
|
| 1032 |
});
|
| 1033 |
|
| 1034 |
-
// Also run
|
| 1035 |
-
|
| 1036 |
-
|
| 1037 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1038 |
});
|
| 1039 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1040 |
</script>
|
| 1041 |
""")
|
| 1042 |
|
|
@@ -1045,6 +1179,4 @@ def create_interface():
|
|
| 1045 |
|
| 1046 |
|
| 1047 |
if __name__ == "__main__":
|
| 1048 |
-
create_interface()
|
| 1049 |
-
|
| 1050 |
-
# Example Script
|
|
|
|
| 396 |
from PIL import Image
|
| 397 |
import json
|
| 398 |
|
| 399 |
+
# Import configuration
|
| 400 |
+
try:
|
| 401 |
+
from .config import get_flask_urls, get_doctors_page_urls, TIMEOUT_SETTINGS
|
| 402 |
+
except ImportError:
|
| 403 |
+
# Fallback configuration if config file is not available
|
| 404 |
+
def get_flask_urls():
|
| 405 |
+
return [
|
| 406 |
+
"http://127.0.0.1:600/complete_appointment",
|
| 407 |
+
"http://localhost:600/complete_appointment",
|
| 408 |
+
"https://your-flask-app-domain.com/complete_appointment",
|
| 409 |
+
"http://your-flask-app-ip:600/complete_appointment"
|
| 410 |
+
]
|
| 411 |
+
|
| 412 |
+
def get_doctors_page_urls():
|
| 413 |
+
return {
|
| 414 |
+
"local": "http://127.0.0.1:600/doctors",
|
| 415 |
+
"production": "https://your-flask-app-domain.com/doctors"
|
| 416 |
+
}
|
| 417 |
+
|
| 418 |
+
TIMEOUT_SETTINGS = {"connection_timeout": 5, "request_timeout": 10}
|
| 419 |
+
|
| 420 |
# Add parent directory to path
|
| 421 |
parent_dir = os.path.dirname(os.path.abspath(__file__))
|
| 422 |
sys.path.append(parent_dir)
|
|
|
|
| 768 |
dict: Response from the API
|
| 769 |
"""
|
| 770 |
try:
|
| 771 |
+
# Get Flask URLs from configuration
|
| 772 |
+
flask_urls = get_flask_urls()
|
| 773 |
+
|
| 774 |
payload = {"appointment_id": appointment_id}
|
| 775 |
|
| 776 |
+
for flask_api_url in flask_urls:
|
| 777 |
+
try:
|
| 778 |
+
logger.info(f"Trying to connect to: {flask_api_url}")
|
| 779 |
+
response = requests.post(flask_api_url, json=payload, timeout=TIMEOUT_SETTINGS["connection_timeout"])
|
| 780 |
+
|
| 781 |
+
if response.status_code == 200:
|
| 782 |
+
return {"status": "success", "message": "Appointment completed successfully"}
|
| 783 |
+
elif response.status_code == 404:
|
| 784 |
+
return {"status": "error", "message": "Appointment not found"}
|
| 785 |
+
else:
|
| 786 |
+
logger.warning(f"Unexpected response from {flask_api_url}: {response.status_code}")
|
| 787 |
+
continue
|
| 788 |
+
|
| 789 |
+
except requests.exceptions.ConnectionError:
|
| 790 |
+
logger.warning(f"Connection failed to {flask_api_url}")
|
| 791 |
+
continue
|
| 792 |
+
except requests.exceptions.Timeout:
|
| 793 |
+
logger.warning(f"Timeout connecting to {flask_api_url}")
|
| 794 |
+
continue
|
| 795 |
+
except Exception as e:
|
| 796 |
+
logger.warning(f"Error with {flask_api_url}: {e}")
|
| 797 |
+
continue
|
| 798 |
|
| 799 |
+
# If all URLs fail, return a helpful error message
|
| 800 |
+
return {
|
| 801 |
+
"status": "error",
|
| 802 |
+
"message": "Cannot connect to Flask app. Please ensure the Flask app is running and accessible."
|
| 803 |
+
}
|
| 804 |
|
| 805 |
except Exception as e:
|
| 806 |
logger.error(f"Error completing appointment: {e}")
|
|
|
|
| 857 |
4. Click "End Consultation" when finished to complete your appointment
|
| 858 |
""")
|
| 859 |
|
| 860 |
+
# Add appointment ID input with Python-based population
|
| 861 |
with gr.Row():
|
| 862 |
+
# Get appointment ID from URL parameters if available
|
| 863 |
+
import urllib.parse
|
| 864 |
+
try:
|
| 865 |
+
# This will be set by JavaScript, but we can also try to get it server-side
|
| 866 |
+
url_params = {}
|
| 867 |
+
if hasattr(gr, 'get_current_url'):
|
| 868 |
+
current_url = gr.get_current_url()
|
| 869 |
+
if current_url:
|
| 870 |
+
parsed = urllib.parse.urlparse(current_url)
|
| 871 |
+
url_params = urllib.parse.parse_qs(parsed.query)
|
| 872 |
+
|
| 873 |
+
default_appointment_id = url_params.get('appointment_id', [''])[0]
|
| 874 |
+
except:
|
| 875 |
+
default_appointment_id = ""
|
| 876 |
+
|
| 877 |
appointment_id_input = gr.Textbox(
|
| 878 |
label="Appointment ID",
|
| 879 |
placeholder="Enter your appointment ID here...",
|
| 880 |
info="This will be automatically populated if you came from the doctors page",
|
| 881 |
+
value=default_appointment_id
|
| 882 |
)
|
| 883 |
|
| 884 |
with gr.Tab("Multimodal Analysis"):
|
|
|
|
| 1017 |
result = complete_appointment(appointment_id.strip())
|
| 1018 |
|
| 1019 |
if result["status"] == "success":
|
| 1020 |
+
# Get doctors page URLs from configuration
|
| 1021 |
+
doctors_urls = get_doctors_page_urls()
|
| 1022 |
+
|
| 1023 |
# Create success message with redirect button
|
| 1024 |
html_response = f"""
|
| 1025 |
<div style='color: green; padding: 15px; background-color: #e6ffe6; border-radius: 5px; margin: 10px 0;'>
|
| 1026 |
<h3>✅ Consultation Completed Successfully!</h3>
|
| 1027 |
<p>{result['message']}</p>
|
| 1028 |
<p>Your appointment has been marked as completed.</p>
|
| 1029 |
+
<button onclick="window.open('{doctors_urls['local']}', '_blank')"
|
| 1030 |
style="background-color: #007bff; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; margin-top: 10px;">
|
| 1031 |
+
Return to Doctors Page (Local)
|
| 1032 |
+
</button>
|
| 1033 |
+
<button onclick="window.open('{doctors_urls['production']}', '_blank')"
|
| 1034 |
+
style="background-color: #28a745; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; margin-top: 10px; margin-left: 10px;">
|
| 1035 |
+
Return to Doctors Page (Production)
|
| 1036 |
</button>
|
| 1037 |
</div>
|
| 1038 |
"""
|
|
|
|
| 1080 |
// Function to populate appointment ID from URL
|
| 1081 |
function populateAppointmentId() {
|
| 1082 |
var appointmentId = getUrlParameter('appointment_id');
|
| 1083 |
+
console.log('Found appointment ID:', appointmentId);
|
| 1084 |
+
|
| 1085 |
if (appointmentId) {
|
| 1086 |
+
// Try multiple selectors to find the appointment ID input
|
| 1087 |
+
var selectors = [
|
| 1088 |
+
'input[placeholder*="appointment ID"]',
|
| 1089 |
+
'input[placeholder*="appointment_id"]',
|
| 1090 |
+
'input[placeholder*="Appointment ID"]',
|
| 1091 |
+
'textarea[placeholder*="appointment ID"]',
|
| 1092 |
+
'textarea[placeholder*="appointment_id"]',
|
| 1093 |
+
'textarea[placeholder*="Appointment ID"]'
|
| 1094 |
+
];
|
| 1095 |
+
|
| 1096 |
+
for (var selector of selectors) {
|
| 1097 |
+
var elements = document.querySelectorAll(selector);
|
| 1098 |
+
for (var element of elements) {
|
| 1099 |
+
console.log('Found element:', element);
|
| 1100 |
+
element.value = appointmentId;
|
| 1101 |
+
// Trigger change event
|
| 1102 |
+
var event = new Event('input', { bubbles: true });
|
| 1103 |
+
element.dispatchEvent(event);
|
| 1104 |
+
console.log('Set appointment ID to:', appointmentId);
|
| 1105 |
+
return true;
|
| 1106 |
+
}
|
| 1107 |
+
}
|
| 1108 |
+
|
| 1109 |
+
// If not found by placeholder, try by label
|
| 1110 |
+
var labels = document.querySelectorAll('label');
|
| 1111 |
+
for (var label of labels) {
|
| 1112 |
+
if (label.textContent && label.textContent.toLowerCase().includes('appointment id')) {
|
| 1113 |
+
var input = label.nextElementSibling;
|
| 1114 |
+
if (input && (input.tagName === 'INPUT' || input.tagName === 'TEXTAREA')) {
|
| 1115 |
+
input.value = appointmentId;
|
| 1116 |
+
var event = new Event('input', { bubbles: true });
|
| 1117 |
+
input.dispatchEvent(event);
|
| 1118 |
+
console.log('Set appointment ID by label to:', appointmentId);
|
| 1119 |
+
return true;
|
| 1120 |
+
}
|
| 1121 |
}
|
| 1122 |
}
|
| 1123 |
+
|
| 1124 |
+
console.log('Could not find appointment ID input field');
|
| 1125 |
+
} else {
|
| 1126 |
+
console.log('No appointment ID found in URL');
|
| 1127 |
+
}
|
| 1128 |
+
return false;
|
| 1129 |
+
}
|
| 1130 |
+
|
| 1131 |
+
// Function to wait for Gradio to be ready
|
| 1132 |
+
function waitForGradio() {
|
| 1133 |
+
if (typeof gradio !== 'undefined' && gradio) {
|
| 1134 |
+
console.log('Gradio detected, waiting for load...');
|
| 1135 |
+
setTimeout(function() {
|
| 1136 |
+
populateAppointmentId();
|
| 1137 |
+
// Also try again after a longer delay
|
| 1138 |
+
setTimeout(populateAppointmentId, 2000);
|
| 1139 |
+
}, 1000);
|
| 1140 |
+
} else {
|
| 1141 |
+
console.log('Gradio not detected, trying direct population...');
|
| 1142 |
+
populateAppointmentId();
|
| 1143 |
+
// Try again after a delay
|
| 1144 |
+
setTimeout(populateAppointmentId, 1000);
|
| 1145 |
}
|
| 1146 |
}
|
| 1147 |
|
| 1148 |
// Run when page loads
|
| 1149 |
document.addEventListener('DOMContentLoaded', function() {
|
| 1150 |
+
console.log('DOM loaded, attempting to populate appointment ID...');
|
| 1151 |
+
waitForGradio();
|
| 1152 |
});
|
| 1153 |
|
| 1154 |
+
// Also run when window loads
|
| 1155 |
+
window.addEventListener('load', function() {
|
| 1156 |
+
console.log('Window loaded, attempting to populate appointment ID...');
|
| 1157 |
+
setTimeout(waitForGradio, 500);
|
| 1158 |
+
});
|
| 1159 |
+
|
| 1160 |
+
// Monitor for dynamic content changes
|
| 1161 |
+
var observer = new MutationObserver(function(mutations) {
|
| 1162 |
+
mutations.forEach(function(mutation) {
|
| 1163 |
+
if (mutation.type === 'childList') {
|
| 1164 |
+
setTimeout(populateAppointmentId, 100);
|
| 1165 |
+
}
|
| 1166 |
});
|
| 1167 |
+
});
|
| 1168 |
+
|
| 1169 |
+
// Start observing
|
| 1170 |
+
observer.observe(document.body, {
|
| 1171 |
+
childList: true,
|
| 1172 |
+
subtree: true
|
| 1173 |
+
});
|
| 1174 |
</script>
|
| 1175 |
""")
|
| 1176 |
|
|
|
|
| 1179 |
|
| 1180 |
|
| 1181 |
if __name__ == "__main__":
|
| 1182 |
+
create_interface()
|
|
|
|
|
|