updated UI code ✅✅
Browse files- mediSync/app.py +41 -52
mediSync/app.py
CHANGED
@@ -29,6 +29,15 @@ from utils.visualization import (
|
|
29 |
plot_multimodal_results,
|
30 |
plot_report_entities,
|
31 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
|
33 |
# Set up logging
|
34 |
logging.basicConfig(
|
@@ -41,7 +50,6 @@ logger = logging.getLogger(__name__)
|
|
41 |
# Create temporary directory for sample data if it doesn't exist
|
42 |
os.makedirs(os.path.join(parent_dir, "data", "sample"), exist_ok=True)
|
43 |
|
44 |
-
|
45 |
# Import configuration for end consultation logic
|
46 |
try:
|
47 |
from .config import get_flask_urls, get_doctors_page_urls, TIMEOUT_SETTINGS
|
@@ -153,8 +161,7 @@ class MediSyncApp:
|
|
153 |
html_result = f"""
|
154 |
<div class="medisync-card medisync-card-bg medisync-force-text">
|
155 |
<h2 class="medisync-title medisync-blue">
|
156 |
-
<
|
157 |
-
<span style="font-size:1.45em; font-weight:900; letter-spacing:1px; text-shadow:0 2px 8px #00bfae33;">X-ray Analysis Results</span>
|
158 |
</h2>
|
159 |
<p><strong>Primary Finding:</strong> {results.get("primary_finding", "Unknown")}</p>
|
160 |
<p><strong>Confidence:</strong> {results.get("confidence", 0):.1%}</p>
|
@@ -203,8 +210,7 @@ class MediSyncApp:
|
|
203 |
html_result = f"""
|
204 |
<div class="medisync-card medisync-card-bg medisync-force-text">
|
205 |
<h2 class="medisync-title medisync-green">
|
206 |
-
<
|
207 |
-
<span style="font-size:1.45em; font-weight:900; letter-spacing:1px; text-shadow:0 2px 8px #28a74533;">Text Analysis Results</span>
|
208 |
</h2>
|
209 |
<p><strong>Severity Level:</strong> {results.get("severity", {}).get("level", "Unknown")}</p>
|
210 |
<p><strong>Severity Score:</strong> {results.get("severity", {}).get("score", 0)}/4</p>
|
@@ -273,8 +279,7 @@ class MediSyncApp:
|
|
273 |
html_result = f"""
|
274 |
<div class="medisync-card medisync-card-bg medisync-force-text">
|
275 |
<h2 class="medisync-title medisync-purple">
|
276 |
-
<
|
277 |
-
<span style="font-size:1.45em; font-weight:900; letter-spacing:1px; text-shadow:0 2px 8px #6c63ff33;">Multimodal Analysis Results</span>
|
278 |
</h2>
|
279 |
<h3>Overview</h3>
|
280 |
<p><strong>Primary Finding:</strong> {results.get("primary_finding", "Unknown")}</p>
|
@@ -435,9 +440,7 @@ def create_interface():
|
|
435 |
margin-bottom: 0.7em;
|
436 |
letter-spacing: 1px;
|
437 |
text-shadow: 0 2px 8px #00bfae33, 0 1px 0 #fff;
|
438 |
-
display:
|
439 |
-
align-items: center;
|
440 |
-
gap: 10px;
|
441 |
}
|
442 |
.medisync-blue { color: #00bfae; }
|
443 |
.medisync-green { color: #28a745; }
|
@@ -503,23 +506,13 @@ def create_interface():
|
|
503 |
html[data-theme="dark"] .medisync-force-text, html[data-theme="dark"] .medisync-force-text * {
|
504 |
color: #f8fafc !important;
|
505 |
}
|
506 |
-
/* End consultation status output
|
507 |
#end_consultation_status, #end_consultation_status * {
|
508 |
-
color:
|
509 |
background: #fff !important;
|
510 |
-
}
|
511 |
-
html[data-theme="dark"] #end_consultation_status, html[data-theme="dark"] #end_consultation_status * {
|
512 |
-
color: #f8fafc !important;
|
513 |
-
background: #23272f !important;
|
514 |
-
}
|
515 |
-
/* Style for the popup/status after end consultation for visibility */
|
516 |
-
#end_consultation_status, #end_consultation_status * {
|
517 |
font-size: 1.12rem !important;
|
518 |
font-weight: 600 !important;
|
519 |
}
|
520 |
-
html[data-theme="dark"] #end_consultation_status, html[data-theme="dark"] #end_consultation_status * {
|
521 |
-
color: #f8fafc !important;
|
522 |
-
}
|
523 |
/* Style the buttons inside the end consultation status popup */
|
524 |
#end_consultation_status button {
|
525 |
font-size: 1rem !important;
|
@@ -539,22 +532,19 @@ def create_interface():
|
|
539 |
) as interface:
|
540 |
gr.Markdown(
|
541 |
"""
|
542 |
-
<div style="
|
543 |
-
<
|
544 |
-
|
545 |
-
MediSync
|
546 |
-
<img src="https://cdn.jsdelivr.net/gh/saqib-ali-buriro/medivance-assets/ai_heartbeat.png" alt="AI Heartbeat" style="height: 32px; vertical-align: middle; margin-left: 8px;">
|
547 |
</span>
|
548 |
-
<img src="https://cdn.jsdelivr.net/gh/saqib-ali-buriro/medivance-assets/doctor_icon.png" alt="Doctor" style="height: 38px; border-radius: 8px; background: #fff; box-shadow: 0 2px 8px 0 rgba(26,115,232,0.10); margin-left: 8px;">
|
549 |
</div>
|
550 |
-
<div style="font-size: 1.22rem; margin-bottom: 1.2em; font-weight: 600;
|
551 |
-
<span
|
552 |
</div>
|
553 |
<div style="font-size: 1.09rem; margin-bottom: 1.2em;">
|
554 |
-
<span
|
555 |
</div>
|
556 |
<div style="margin-bottom: 1.2em;">
|
557 |
-
<ul style="font-size: 1.04rem;
|
558 |
<li>Upload a chest X-ray image</li>
|
559 |
<li>Enter the corresponding medical report text</li>
|
560 |
<li>Choose the analysis type: <b>Image</b>, <b>Text</b>, or <b>Multimodal</b></li>
|
@@ -661,8 +651,7 @@ def create_interface():
|
|
661 |
"""
|
662 |
<div class="medisync-card medisync-card-bg medisync-force-text">
|
663 |
<h2 class="medisync-title medisync-blue">
|
664 |
-
<
|
665 |
-
<span style="font-size:1.45em; font-weight:900; letter-spacing:1px; text-shadow:0 2px 8px #00bfae33;">About MediSync</span>
|
666 |
</h2>
|
667 |
<p>
|
668 |
<b>MediSync</b> is an AI-powered healthcare solution that uses multi-modal analysis to provide comprehensive insights from medical images and reports.
|
@@ -708,17 +697,17 @@ def create_interface():
|
|
708 |
)
|
709 |
|
710 |
def handle_end_consultation(appointment_id):
|
711 |
-
#
|
712 |
if not appointment_id or appointment_id.strip() == "":
|
713 |
-
return "<div
|
714 |
result = complete_appointment(appointment_id.strip())
|
715 |
if result["status"] == "success":
|
716 |
doctors_urls = get_doctors_page_urls()
|
717 |
html_response = f"""
|
718 |
-
<div
|
719 |
-
<h3 style="color: #
|
720 |
-
<p
|
721 |
-
<p
|
722 |
<button onclick="window.open('{doctors_urls['local']}', '_blank')"
|
723 |
style="background-color: #00bfae; color: white; padding: 8px 18px; border: none; border-radius: 6px; cursor: pointer; margin-top: 10px;">
|
724 |
Return to Doctors Page (Local)
|
@@ -732,15 +721,15 @@ def create_interface():
|
|
732 |
else:
|
733 |
if "Cannot connect to Flask app" in result['message']:
|
734 |
html_response = f"""
|
735 |
-
<div
|
736 |
-
<h3 style="color: #
|
737 |
-
<p
|
738 |
-
<p
|
739 |
-
<p
|
740 |
<ol>
|
741 |
-
<li
|
742 |
-
<li
|
743 |
-
<li
|
744 |
</ol>
|
745 |
<div style="margin-top: 15px;">
|
746 |
<button onclick="window.open('http://127.0.0.1:600/complete_appointment_manual?appointment_id={appointment_id.strip()}', '_blank')"
|
@@ -760,10 +749,10 @@ def create_interface():
|
|
760 |
"""
|
761 |
else:
|
762 |
html_response = f"""
|
763 |
-
<div
|
764 |
-
<h3 style="color: #
|
765 |
-
<p
|
766 |
-
<p
|
767 |
</div>
|
768 |
"""
|
769 |
return html_response
|
|
|
29 |
plot_multimodal_results,
|
30 |
plot_report_entities,
|
31 |
)
|
32 |
+
import logging
|
33 |
+
import os
|
34 |
+
import sys
|
35 |
+
import tempfile
|
36 |
+
from pathlib import Path
|
37 |
+
import requests
|
38 |
+
import gradio as gr
|
39 |
+
import matplotlib.pyplot as plt
|
40 |
+
from PIL import Image
|
41 |
|
42 |
# Set up logging
|
43 |
logging.basicConfig(
|
|
|
50 |
# Create temporary directory for sample data if it doesn't exist
|
51 |
os.makedirs(os.path.join(parent_dir, "data", "sample"), exist_ok=True)
|
52 |
|
|
|
53 |
# Import configuration for end consultation logic
|
54 |
try:
|
55 |
from .config import get_flask_urls, get_doctors_page_urls, TIMEOUT_SETTINGS
|
|
|
161 |
html_result = f"""
|
162 |
<div class="medisync-card medisync-card-bg medisync-force-text">
|
163 |
<h2 class="medisync-title medisync-blue">
|
164 |
+
<b>X-ray Analysis Results</b>
|
|
|
165 |
</h2>
|
166 |
<p><strong>Primary Finding:</strong> {results.get("primary_finding", "Unknown")}</p>
|
167 |
<p><strong>Confidence:</strong> {results.get("confidence", 0):.1%}</p>
|
|
|
210 |
html_result = f"""
|
211 |
<div class="medisync-card medisync-card-bg medisync-force-text">
|
212 |
<h2 class="medisync-title medisync-green">
|
213 |
+
<b>Text Analysis Results</b>
|
|
|
214 |
</h2>
|
215 |
<p><strong>Severity Level:</strong> {results.get("severity", {}).get("level", "Unknown")}</p>
|
216 |
<p><strong>Severity Score:</strong> {results.get("severity", {}).get("score", 0)}/4</p>
|
|
|
279 |
html_result = f"""
|
280 |
<div class="medisync-card medisync-card-bg medisync-force-text">
|
281 |
<h2 class="medisync-title medisync-purple">
|
282 |
+
<b>Multimodal Analysis Results</b>
|
|
|
283 |
</h2>
|
284 |
<h3>Overview</h3>
|
285 |
<p><strong>Primary Finding:</strong> {results.get("primary_finding", "Unknown")}</p>
|
|
|
440 |
margin-bottom: 0.7em;
|
441 |
letter-spacing: 1px;
|
442 |
text-shadow: 0 2px 8px #00bfae33, 0 1px 0 #fff;
|
443 |
+
/* Remove display:flex and gap for simple bold text */
|
|
|
|
|
444 |
}
|
445 |
.medisync-blue { color: #00bfae; }
|
446 |
.medisync-green { color: #28a745; }
|
|
|
506 |
html[data-theme="dark"] .medisync-force-text, html[data-theme="dark"] .medisync-force-text * {
|
507 |
color: #f8fafc !important;
|
508 |
}
|
509 |
+
/* End consultation status output: remove color and theme, keep text black and simple */
|
510 |
#end_consultation_status, #end_consultation_status * {
|
511 |
+
color: #000 !important;
|
512 |
background: #fff !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
513 |
font-size: 1.12rem !important;
|
514 |
font-weight: 600 !important;
|
515 |
}
|
|
|
|
|
|
|
516 |
/* Style the buttons inside the end consultation status popup */
|
517 |
#end_consultation_status button {
|
518 |
font-size: 1rem !important;
|
|
|
532 |
) as interface:
|
533 |
gr.Markdown(
|
534 |
"""
|
535 |
+
<div style="margin-bottom: 0.5em;">
|
536 |
+
<span style="font-size: 2.4rem; font-weight: bold; letter-spacing: 1.5px;">
|
537 |
+
<b>MediSync</b>
|
|
|
|
|
538 |
</span>
|
|
|
539 |
</div>
|
540 |
+
<div style="font-size: 1.22rem; margin-bottom: 1.2em; font-weight: 600;">
|
541 |
+
<span>AI-powered Multi-Modal Medical Analysis System</span>
|
542 |
</div>
|
543 |
<div style="font-size: 1.09rem; margin-bottom: 1.2em;">
|
544 |
+
<span>Seamlessly analyze X-ray images and medical reports for comprehensive healthcare insights.</span>
|
545 |
</div>
|
546 |
<div style="margin-bottom: 1.2em;">
|
547 |
+
<ul style="font-size: 1.04rem;">
|
548 |
<li>Upload a chest X-ray image</li>
|
549 |
<li>Enter the corresponding medical report text</li>
|
550 |
<li>Choose the analysis type: <b>Image</b>, <b>Text</b>, or <b>Multimodal</b></li>
|
|
|
651 |
"""
|
652 |
<div class="medisync-card medisync-card-bg medisync-force-text">
|
653 |
<h2 class="medisync-title medisync-blue">
|
654 |
+
<b>About MediSync</b>
|
|
|
655 |
</h2>
|
656 |
<p>
|
657 |
<b>MediSync</b> is an AI-powered healthcare solution that uses multi-modal analysis to provide comprehensive insights from medical images and reports.
|
|
|
697 |
)
|
698 |
|
699 |
def handle_end_consultation(appointment_id):
|
700 |
+
# Output status: keep text black, simple, no color or theme
|
701 |
if not appointment_id or appointment_id.strip() == "":
|
702 |
+
return "<div style='color: #000; background: #fff; padding: 10px; border-radius: 5px;'>Please enter your appointment ID first.</div>"
|
703 |
result = complete_appointment(appointment_id.strip())
|
704 |
if result["status"] == "success":
|
705 |
doctors_urls = get_doctors_page_urls()
|
706 |
html_response = f"""
|
707 |
+
<div style='color: #000; background: #fff; padding: 15px; border-radius: 5px; margin: 10px 0;'>
|
708 |
+
<h3 style="color: #000;">✅ Consultation Completed Successfully!</h3>
|
709 |
+
<p>✔️ {result['message']}</p>
|
710 |
+
<p>Your appointment has been marked as completed.</p>
|
711 |
<button onclick="window.open('{doctors_urls['local']}', '_blank')"
|
712 |
style="background-color: #00bfae; color: white; padding: 8px 18px; border: none; border-radius: 6px; cursor: pointer; margin-top: 10px;">
|
713 |
Return to Doctors Page (Local)
|
|
|
721 |
else:
|
722 |
if "Cannot connect to Flask app" in result['message']:
|
723 |
html_response = f"""
|
724 |
+
<div style='color: #000; background: #fff; padding: 15px; border-radius: 5px; margin: 10px 0;'>
|
725 |
+
<h3 style="color: #000;">⚠️ Consultation Ready to Complete</h3>
|
726 |
+
<p>Your consultation analysis is complete! However, we cannot automatically mark your appointment as completed because the Flask app is not accessible from this environment.</p>
|
727 |
+
<p><strong>Appointment ID:</strong> {appointment_id.strip()}</p>
|
728 |
+
<p><strong>Next Steps:</strong></p>
|
729 |
<ol>
|
730 |
+
<li>Copy your appointment ID: <code>{appointment_id.strip()}</code></li>
|
731 |
+
<li>Return to your Flask app (doctors page)</li>
|
732 |
+
<li>Manually complete the appointment using the appointment ID</li>
|
733 |
</ol>
|
734 |
<div style="margin-top: 15px;">
|
735 |
<button onclick="window.open('http://127.0.0.1:600/complete_appointment_manual?appointment_id={appointment_id.strip()}', '_blank')"
|
|
|
749 |
"""
|
750 |
else:
|
751 |
html_response = f"""
|
752 |
+
<div style='color: #000; background: #fff; padding: 15px; border-radius: 5px; margin: 10px 0;'>
|
753 |
+
<h3 style="color: #000;">❌ Error Completing Consultation</h3>
|
754 |
+
<p>{result['message']}</p>
|
755 |
+
<p>Please try again or contact support if the problem persists.</p>
|
756 |
</div>
|
757 |
"""
|
758 |
return html_response
|