Spaces:
Sleeping
Sleeping
Nikhil Pravin Pise commited on
Commit Β·
f55411e
1
Parent(s): 3b8e1fe
Fix: Improve UI formatting and handle missing biomarker data gracefully
Browse files- Better biomarker name extraction with fallback options
- Skip unknown/generic biomarker names
- Add default recommendations when none provided
- Improve grid layout for biomarker cards
- Better handling of missing/sparse data
- More robust type checking for recommendations
- Improved visual consistency and spacing
- huggingface/app.py +52 -34
huggingface/app.py
CHANGED
|
@@ -421,17 +421,22 @@ def format_summary(response: dict, elapsed: float) -> str:
|
|
| 421 |
|
| 422 |
# Biomarker Flags - as a visual grid
|
| 423 |
flags = response.get("biomarker_flags", [])
|
| 424 |
-
if flags:
|
| 425 |
flag_cards = ""
|
| 426 |
for flag in flags[:8]:
|
| 427 |
if isinstance(flag, dict):
|
| 428 |
-
name = flag.get("biomarker", "
|
| 429 |
-
|
| 430 |
-
|
|
|
|
|
|
|
|
|
|
| 431 |
|
| 432 |
status_styles = {
|
| 433 |
"critical": ("π΄", "#dc2626", "#fef2f2"),
|
|
|
|
| 434 |
"abnormal": ("π‘", "#ca8a04", "#fefce8"),
|
|
|
|
| 435 |
"normal": ("π’", "#16a34a", "#f0fdf4")
|
| 436 |
}
|
| 437 |
s_emoji, s_color, s_bg = status_styles.get(status, status_styles["normal"])
|
|
@@ -439,16 +444,17 @@ def format_summary(response: dict, elapsed: float) -> str:
|
|
| 439 |
flag_cards += f"""
|
| 440 |
<div style="background: {s_bg}; border: 1px solid {s_color}33; border-radius: 8px; padding: 12px; text-align: center;">
|
| 441 |
<div style="font-size: 1.2em;">{s_emoji}</div>
|
| 442 |
-
<div style="font-weight: 600; color: #1e3a5f; margin: 4px 0;">{name}</div>
|
| 443 |
-
<div style="font-size:
|
| 444 |
-
<div style="font-size: 0.
|
| 445 |
</div>
|
| 446 |
"""
|
| 447 |
|
| 448 |
-
|
|
|
|
| 449 |
<div style="margin-bottom: 16px;">
|
| 450 |
<h4 style="margin: 0 0 12px 0; color: #1e3a5f;">π Biomarker Analysis</h4>
|
| 451 |
-
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(
|
| 452 |
{flag_cards}
|
| 453 |
</div>
|
| 454 |
</div>
|
|
@@ -456,46 +462,58 @@ def format_summary(response: dict, elapsed: float) -> str:
|
|
| 456 |
|
| 457 |
# Recommendations - organized sections
|
| 458 |
recs = response.get("recommendations", {})
|
| 459 |
-
|
| 460 |
-
|
| 461 |
-
|
| 462 |
-
|
| 463 |
-
|
| 464 |
-
|
| 465 |
-
rec_sections += f"""
|
| 466 |
<div style="margin-bottom: 12px;">
|
| 467 |
<h5 style="margin: 0 0 8px 0; color: #dc2626;">π¨ Immediate Actions</h5>
|
| 468 |
<ul style="margin: 0; padding-left: 20px; color: #475569;">{items}</ul>
|
| 469 |
</div>
|
| 470 |
-
|
| 471 |
-
|
| 472 |
-
|
| 473 |
-
|
| 474 |
-
|
| 475 |
-
|
| 476 |
<div style="margin-bottom: 12px;">
|
| 477 |
<h5 style="margin: 0 0 8px 0; color: #16a34a;">πΏ Lifestyle Modifications</h5>
|
| 478 |
<ul style="margin: 0; padding-left: 20px; color: #475569;">{items}</ul>
|
| 479 |
</div>
|
| 480 |
-
|
| 481 |
-
|
| 482 |
-
|
| 483 |
-
|
| 484 |
-
|
| 485 |
-
|
| 486 |
<div>
|
| 487 |
<h5 style="margin: 0 0 8px 0; color: #2563eb;">π
Follow-up</h5>
|
| 488 |
<ul style="margin: 0; padding-left: 20px; color: #475569;">{items}</ul>
|
| 489 |
</div>
|
| 490 |
-
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 494 |
<div style="background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%); border-radius: 12px; padding: 16px; margin-bottom: 16px;">
|
| 495 |
-
<h4 style="margin: 0 0 16px 0; color: #1e3a5f;">π‘ Recommendations</h4>
|
| 496 |
{rec_sections}
|
| 497 |
</div>
|
| 498 |
-
|
| 499 |
|
| 500 |
# Disease Explanation
|
| 501 |
explanation = response.get("disease_explanation", {})
|
|
|
|
| 421 |
|
| 422 |
# Biomarker Flags - as a visual grid
|
| 423 |
flags = response.get("biomarker_flags", [])
|
| 424 |
+
if flags and len(flags) > 0:
|
| 425 |
flag_cards = ""
|
| 426 |
for flag in flags[:8]:
|
| 427 |
if isinstance(flag, dict):
|
| 428 |
+
name = flag.get("biomarker", flag.get("name", "Biomarker"))
|
| 429 |
+
# Skip if name is still unknown or generic
|
| 430 |
+
if not name or name.lower() in ["unknown", "biomarker", ""]:
|
| 431 |
+
continue
|
| 432 |
+
status = flag.get("status", "normal").lower()
|
| 433 |
+
value = flag.get("value", flag.get("result", "N/A"))
|
| 434 |
|
| 435 |
status_styles = {
|
| 436 |
"critical": ("π΄", "#dc2626", "#fef2f2"),
|
| 437 |
+
"high": ("π΄", "#dc2626", "#fef2f2"),
|
| 438 |
"abnormal": ("π‘", "#ca8a04", "#fefce8"),
|
| 439 |
+
"low": ("π‘", "#ca8a04", "#fefce8"),
|
| 440 |
"normal": ("π’", "#16a34a", "#f0fdf4")
|
| 441 |
}
|
| 442 |
s_emoji, s_color, s_bg = status_styles.get(status, status_styles["normal"])
|
|
|
|
| 444 |
flag_cards += f"""
|
| 445 |
<div style="background: {s_bg}; border: 1px solid {s_color}33; border-radius: 8px; padding: 12px; text-align: center;">
|
| 446 |
<div style="font-size: 1.2em;">{s_emoji}</div>
|
| 447 |
+
<div style="font-weight: 600; color: #1e3a5f; margin: 4px 0; font-size: 0.9em;">{name}</div>
|
| 448 |
+
<div style="font-size: 1em; color: {s_color}; font-weight: 600;">{value}</div>
|
| 449 |
+
<div style="font-size: 0.75em; color: #64748b; text-transform: capitalize;">{status}</div>
|
| 450 |
</div>
|
| 451 |
"""
|
| 452 |
|
| 453 |
+
if flag_cards: # Only show section if we have cards
|
| 454 |
+
parts.append(f"""
|
| 455 |
<div style="margin-bottom: 16px;">
|
| 456 |
<h4 style="margin: 0 0 12px 0; color: #1e3a5f;">π Biomarker Analysis</h4>
|
| 457 |
+
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 12px;">
|
| 458 |
{flag_cards}
|
| 459 |
</div>
|
| 460 |
</div>
|
|
|
|
| 462 |
|
| 463 |
# Recommendations - organized sections
|
| 464 |
recs = response.get("recommendations", {})
|
| 465 |
+
rec_sections = ""
|
| 466 |
+
|
| 467 |
+
immediate = recs.get("immediate_actions", []) if isinstance(recs, dict) else []
|
| 468 |
+
if immediate and len(immediate) > 0:
|
| 469 |
+
items = "".join([f'<li style="margin-bottom: 6px;">{str(a).strip()}</li>' for a in immediate[:3]])
|
| 470 |
+
rec_sections += f"""
|
|
|
|
| 471 |
<div style="margin-bottom: 12px;">
|
| 472 |
<h5 style="margin: 0 0 8px 0; color: #dc2626;">π¨ Immediate Actions</h5>
|
| 473 |
<ul style="margin: 0; padding-left: 20px; color: #475569;">{items}</ul>
|
| 474 |
</div>
|
| 475 |
+
"""
|
| 476 |
+
|
| 477 |
+
lifestyle = recs.get("lifestyle_modifications", []) if isinstance(recs, dict) else []
|
| 478 |
+
if lifestyle and len(lifestyle) > 0:
|
| 479 |
+
items = "".join([f'<li style="margin-bottom: 6px;">{str(m).strip()}</li>' for m in lifestyle[:3]])
|
| 480 |
+
rec_sections += f"""
|
| 481 |
<div style="margin-bottom: 12px;">
|
| 482 |
<h5 style="margin: 0 0 8px 0; color: #16a34a;">πΏ Lifestyle Modifications</h5>
|
| 483 |
<ul style="margin: 0; padding-left: 20px; color: #475569;">{items}</ul>
|
| 484 |
</div>
|
| 485 |
+
"""
|
| 486 |
+
|
| 487 |
+
followup = recs.get("follow_up", []) if isinstance(recs, dict) else []
|
| 488 |
+
if followup and len(followup) > 0:
|
| 489 |
+
items = "".join([f'<li style="margin-bottom: 6px;">{str(f).strip()}</li>' for f in followup[:3]])
|
| 490 |
+
rec_sections += f"""
|
| 491 |
<div>
|
| 492 |
<h5 style="margin: 0 0 8px 0; color: #2563eb;">π
Follow-up</h5>
|
| 493 |
<ul style="margin: 0; padding-left: 20px; color: #475569;">{items}</ul>
|
| 494 |
</div>
|
| 495 |
+
"""
|
| 496 |
+
|
| 497 |
+
# Add default recommendations if none provided
|
| 498 |
+
if not rec_sections:
|
| 499 |
+
rec_sections = f"""
|
| 500 |
+
<div style="margin-bottom: 12px;">
|
| 501 |
+
<h5 style="margin: 0 0 8px 0; color: #2563eb;">π General Recommendations</h5>
|
| 502 |
+
<ul style="margin: 0; padding-left: 20px; color: #475569;">
|
| 503 |
+
<li style="margin-bottom: 6px;">Schedule an appointment with your healthcare provider for comprehensive evaluation</li>
|
| 504 |
+
<li style="margin-bottom: 6px;">Maintain a regular log of your biomarker measurements</li>
|
| 505 |
+
<li style="margin-bottom: 6px;">Follow up with laboratory testing as recommended by your physician</li>
|
| 506 |
+
</ul>
|
| 507 |
+
</div>
|
| 508 |
+
"""
|
| 509 |
+
|
| 510 |
+
if rec_sections:
|
| 511 |
+
parts.append(f"""
|
| 512 |
<div style="background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%); border-radius: 12px; padding: 16px; margin-bottom: 16px;">
|
| 513 |
+
<h4 style="margin: 0 0 16px 0; color: #1e3a5f;">π‘ Clinical Recommendations</h4>
|
| 514 |
{rec_sections}
|
| 515 |
</div>
|
| 516 |
+
""")
|
| 517 |
|
| 518 |
# Disease Explanation
|
| 519 |
explanation = response.get("disease_explanation", {})
|