Spaces:
Running
Running
File size: 5,017 Bytes
79b0bef | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | """
dashboard/app.py
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Streamlit application entry point.
Run locally:
streamlit run dashboard/app.py
Deploy to Streamlit Cloud:
1. Push this repo to GitHub
2. Go to share.streamlit.io β New app
3. Set main file path: dashboard/app.py
4. Add secrets (see VSCODE_GUIDE.md for full instructions):
API_BASE_URL = "https://your-api-host.com"
DATABASE_URL = "postgresql://..."
Navigation
ββββββββββ
π¬ Demo β paste clinical text, get real-time analysis
π Explorer β entity frequency charts and co-occurrence graph
π§ Metrics β classifier performance and training history
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
"""
from __future__ import annotations
import sys
from pathlib import Path
# Streamlit runs this script directly (`streamlit run dashboard/app.py`),
# which puts this file's own directory (dashboard/) on sys.path -- not the
# project root. That makes `dashboard` itself unimportable as a package
# from within its own folder. Insert the project root (this file's parent)
# so absolute imports like `from dashboard.api_client import ...` resolve,
# same pattern the notebooks use (`sys.path.insert(0, '..')`).
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
import streamlit as st
from dashboard.api_client import check_health
from dashboard.views import demo, explorer, model_metrics
# ββ Page config βββββββββββββββββββββββββββββββββββββββββββββββββββ
# Must be the first Streamlit call in the script.
st.set_page_config(
page_title = "Clinical NLP Pipeline",
page_icon = "π¬",
layout = "wide",
initial_sidebar_state = "expanded",
)
# ββ Custom CSS ββββββββββββββββββββββββββββββββββββββββββββββββββββ
# Minimal styling β keeps the app looking clean without overriding
# Streamlit's built-in theme.
st.markdown("""
<style>
/* Tighten the sidebar width slightly */
[data-testid="stSidebar"] { min-width: 220px; max-width: 280px; }
/* Subtle card background for metric containers */
[data-testid="metric-container"] {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
padding: 12px 16px;
}
/* Reduce top padding on the main content area */
.block-container { padding-top: 1.5rem; }
</style>
""", unsafe_allow_html=True)
# ββ Sidebar navigation ββββββββββββββββββββββββββββββββββββββββββββ
with st.sidebar:
st.markdown("## π¬ Clinical NLP")
st.markdown("---")
page = st.radio(
label = "Navigation",
options = ["Demo", "Explorer", "Metrics"],
format_func = lambda p: {
"Demo": "π¬ Live Demo",
"Explorer": "π Explorer",
"Metrics": "π§ Model Metrics",
}[p],
label_visibility = "collapsed",
)
st.markdown("---")
# API health indicator
health = check_health()
status = health.get("status", "unknown")
db_status = health.get("database", "unknown")
colour = "#2ecc71" if status == "ok" else "#e74c3c"
st.markdown(
f"<div style='font-size:0.8rem; color:#666'>"
f"API "
f"<span style='color:{colour}; font-weight:600'>"
f"{'β online' if status == 'ok' else 'β offline'}</span>"
f"</div>",
unsafe_allow_html=True,
)
if db_status not in ("unknown", "unreachable"):
db_colour = "#2ecc71" if db_status == "connected" else "#e74c3c"
st.markdown(
f"<div style='font-size:0.8rem; color:#666'>"
f"DB "
f"<span style='color:{db_colour}; font-weight:600'>"
f"{'β connected' if db_status == 'connected' else 'β unreachable'}</span>"
f"</div>",
unsafe_allow_html=True,
)
st.markdown("---")
st.markdown(
"<div style='font-size:0.75rem; color:#aaa'>"
"Clinical NLP Pipeline Β· v1.0<br>"
"Built with spaCy Β· Bio_ClinicalBERT<br>"
"FastAPI Β· Streamlit"
"</div>",
unsafe_allow_html=True,
)
# ββ Page routing ββββββββββββββββββββββββββββββββββββββββββββββββββ
if page == "Demo":
demo.render()
elif page == "Explorer":
explorer.render()
elif page == "Metrics":
model_metrics.render()
|