Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>NeuroScope AI β Documentation</title> | |
| <style> | |
| :root{--bg:#080808;--surface:#111;--surface2:#1a1a1a;--border:#2a2a2a;--border2:#333; | |
| --red:#dc2626;--red2:#ef4444;--red3:#fca5a5;--red-dim:rgba(220,38,38,0.1); | |
| --teal:#14b8a6;--teal-dim:rgba(20,184,166,0.1);--gold:#d97706; | |
| --text:#f5f5f5;--muted:#525252;--subtle:#a3a3a3;--mono:'Fira Code',monospace;} | |
| *{margin:0;padding:0;box-sizing:border-box;} | |
| html{scroll-behavior:smooth;} | |
| body{font-family:'Inter',-apple-system,sans-serif;background:var(--bg);color:var(--text);line-height:1.6;} | |
| /* Top nav */ | |
| .topnav{position:fixed;top:0;left:0;right:0;z-index:200;display:flex;align-items:center; | |
| height:52px;padding:0 2rem;background:rgba(8,8,8,0.95);backdrop-filter:blur(12px); | |
| border-bottom:1px solid var(--border);} | |
| .logo{display:flex;align-items:center;gap:0.6rem;font-size:0.95rem;font-weight:800; | |
| color:var(--text);text-decoration:none;margin-right:2.5rem;} | |
| .logo-box{width:26px;height:26px;background:var(--red);border-radius:6px;display:flex; | |
| align-items:center;justify-content:center;font-size:0.8rem; | |
| box-shadow:0 0 10px rgba(220,38,38,0.4);} | |
| .logo span{color:var(--red2);} | |
| .logo-docs{font-size:0.82rem;font-weight:500;color:var(--muted);margin-left:0.3rem;} | |
| .topnav-links{display:flex;gap:0.1rem;list-style:none;flex:1;} | |
| .topnav-links a{display:block;padding:0.28rem 0.7rem;font-size:0.78rem;color:var(--muted); | |
| text-decoration:none;border-radius:5px;transition:all .12s;} | |
| .topnav-links a:hover{color:var(--text);background:var(--surface);} | |
| .topnav-links a.active{color:var(--text);} | |
| .back-btn{margin-left:auto;background:var(--red);color:#fff;border:none;padding:0.28rem 0.8rem; | |
| border-radius:5px;font-size:0.75rem;font-weight:700;cursor:pointer;text-decoration:none;} | |
| /* Hero */ | |
| .hero{padding:90px 2rem 50px;text-align:center;position:relative;overflow:hidden;} | |
| .hero::before{content:'';position:absolute;top:0;left:50%;transform:translateX(-50%); | |
| width:600px;height:280px;background:radial-gradient(ellipse at center top, | |
| rgba(220,38,38,0.1) 0%,transparent 70%);pointer-events:none;} | |
| .hero-eyebrow{display:inline-block;font-size:0.62rem;font-weight:800;letter-spacing:2px; | |
| text-transform:uppercase;color:var(--red2);border:1px solid rgba(220,38,38,0.25); | |
| background:var(--red-dim);padding:0.28rem 0.85rem;border-radius:20px;margin-bottom:1.25rem;} | |
| .hero h1{font-size:clamp(2rem,5vw,3.2rem);font-weight:900;letter-spacing:-1.5px;line-height:1.1;margin-bottom:1rem;} | |
| .hero h1 em{font-style:normal;color:var(--red);} | |
| .hero-desc{font-size:0.95rem;color:var(--subtle);max-width:500px;margin:0 auto 2.5rem;line-height:1.75;} | |
| .hero-ctas{display:flex;gap:0.75rem;justify-content:center;flex-wrap:wrap;margin-bottom:3rem;} | |
| .btn-primary{background:var(--red);color:#fff;border:none;padding:0.65rem 1.5rem;border-radius:7px; | |
| font-size:0.85rem;font-weight:700;cursor:pointer;transition:background .15s;text-decoration:none;} | |
| .btn-primary:hover{background:var(--red2);} | |
| .btn-secondary{background:transparent;color:var(--subtle);border:1px solid var(--border2); | |
| padding:0.65rem 1.5rem;border-radius:7px;font-size:0.85rem;font-weight:600; | |
| cursor:pointer;transition:all .15s;text-decoration:none;} | |
| .btn-secondary:hover{border-color:var(--red);color:var(--text);} | |
| /* Stats */ | |
| .stats-bar{border-top:1px solid var(--border);border-bottom:1px solid var(--border); | |
| display:flex;justify-content:center;background:var(--surface);} | |
| .stat-item{padding:1.1rem 2.5rem;text-align:center;border-right:1px solid var(--border);} | |
| .stat-item:last-child{border-right:none;} | |
| .stat-num{font-size:1.35rem;font-weight:900;color:var(--red2);display:block;font-family:var(--mono);} | |
| .stat-lbl{font-size:0.6rem;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:1px;} | |
| /* Layout */ | |
| .page{display:grid;grid-template-columns:230px 1fr;max-width:1160px;margin:0 auto;padding:0 1rem;} | |
| .sidebar{position:sticky;top:52px;height:calc(100vh - 52px);overflow-y:auto; | |
| padding:1.75rem 0;border-right:1px solid var(--border);} | |
| .sidebar::-webkit-scrollbar{width:3px;} | |
| .sidebar::-webkit-scrollbar-thumb{background:var(--border2);border-radius:2px;} | |
| .sb-group{margin-bottom:1.5rem;} | |
| .sb-group-title{font-size:0.6rem;font-weight:800;color:var(--muted);text-transform:uppercase; | |
| letter-spacing:1.2px;padding:0 1.1rem;margin-bottom:0.3rem;} | |
| .sidebar a{display:flex;align-items:center;gap:0.4rem;padding:0.35rem 1.1rem;font-size:0.78rem; | |
| color:var(--muted);text-decoration:none;transition:all .12s;border-left:2px solid transparent;} | |
| .sidebar a:hover{color:var(--subtle);} | |
| .sidebar a.active{color:var(--text);border-left-color:var(--red);background:var(--red-dim);} | |
| /* Content */ | |
| .content{padding:2.5rem 2.5rem 5rem;min-width:0;} | |
| .doc-section{margin-bottom:3.5rem;scroll-margin-top:65px;} | |
| .section-eyebrow{font-size:0.58rem;font-weight:800;letter-spacing:1.5px;text-transform:uppercase; | |
| color:var(--red2);margin-bottom:0.4rem;} | |
| .doc-section h2{font-size:1.6rem;font-weight:900;letter-spacing:-0.6px;margin-bottom:0.65rem;line-height:1.2;} | |
| .doc-section>p{color:var(--subtle);font-size:0.875rem;margin-bottom:1.25rem;max-width:640px;line-height:1.75;} | |
| .doc-section h3{font-size:0.95rem;font-weight:700;margin:1.75rem 0 0.55rem;} | |
| .doc-section p{color:var(--subtle);font-size:0.85rem;line-height:1.75;margin-bottom:0.85rem;} | |
| /* Cards */ | |
| .card-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:0.8rem;margin:1.25rem 0;} | |
| .card-grid-2{grid-template-columns:repeat(2,1fr);} | |
| .doc-card{background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:1rem;transition:border-color .15s;} | |
| .doc-card:hover{border-color:var(--border2);} | |
| .doc-card.red{border-left:3px solid var(--red);} | |
| .doc-card.teal{border-left:3px solid var(--teal);} | |
| .doc-card.gold{border-left:3px solid var(--gold);} | |
| .card-icon{font-size:1.2rem;margin-bottom:0.5rem;} | |
| .card-title{font-size:0.82rem;font-weight:700;margin-bottom:0.25rem;} | |
| .card-body{font-size:0.73rem;color:var(--muted);line-height:1.55;} | |
| /* Table */ | |
| .doc-table{width:100%;border-collapse:collapse;font-size:0.8rem;margin:1rem 0;} | |
| .doc-table th{background:var(--surface2);color:var(--muted);font-size:0.62rem;font-weight:700; | |
| text-transform:uppercase;letter-spacing:0.7px;padding:0.6rem 0.9rem;text-align:left; | |
| border-bottom:1px solid var(--border);} | |
| .doc-table td{padding:0.65rem 0.9rem;border-bottom:1px solid var(--border);color:var(--subtle);} | |
| .doc-table td:first-child{color:var(--text);font-weight:600;font-family:var(--mono);font-size:0.76rem;} | |
| .doc-table tr:last-child td{border-bottom:none;} | |
| .doc-table tr:hover td{background:var(--surface);} | |
| .auc{color:var(--red2);font-weight:700;font-family:var(--mono);} | |
| /* Code */ | |
| .code-wrap{background:#0a0a0a;border:1px solid var(--border);border-radius:8px;overflow:hidden;margin:1rem 0;} | |
| .code-hdr{display:flex;align-items:center;justify-content:space-between;padding:0.4rem 0.85rem; | |
| background:var(--surface);border-bottom:1px solid var(--border);} | |
| .code-lang{font-size:0.6rem;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:0.5px;} | |
| .copy-btn{font-size:0.62rem;color:var(--muted);background:none;border:none;cursor:pointer;transition:color .15s;} | |
| .copy-btn:hover{color:var(--text);} | |
| pre{padding:0.9rem;font-family:var(--mono);font-size:0.76rem;line-height:1.7;color:#cdd6f4;overflow-x:auto;} | |
| .kw{color:#cba6f7;}.str{color:#a6e3a1;}.num{color:#fab387;}.cm{color:#45475a;}.key{color:#89b4fa;} | |
| /* Tags */ | |
| .tag{display:inline-block;font-size:0.63rem;font-weight:700;padding:0.1rem 0.45rem; | |
| border-radius:4px;font-family:var(--mono);margin:0 0.1rem;} | |
| .tag-red{background:var(--red-dim);color:var(--red2);} | |
| .tag-teal{background:var(--teal-dim);color:var(--teal);} | |
| .tag-muted{background:var(--surface2);color:var(--muted);} | |
| .tag-get{background:rgba(22,163,74,0.12);color:#4ade80;} | |
| .tag-post{background:rgba(217,119,6,0.12);color:#fbbf24;} | |
| /* Callout */ | |
| .callout{display:flex;gap:0.6rem;padding:0.85rem 1rem;border-radius:7px; | |
| margin:1rem 0;font-size:0.8rem;line-height:1.6;border-left:3px solid;} | |
| .callout-warn{background:rgba(217,119,6,0.08);border-color:var(--gold);color:#fcd34d;} | |
| .callout-info{background:var(--teal-dim);border-color:var(--teal);color:#94ecdf;} | |
| .callout-danger{background:var(--red-dim);border-color:var(--red);color:var(--red3);} | |
| /* Pipeline */ | |
| .pipeline{display:flex;align-items:center;overflow-x:auto;padding:1rem 0;gap:0;margin:1rem 0;} | |
| .pipe-step{flex-shrink:0;text-align:center;} | |
| .pipe-box{background:var(--surface);border:1px solid var(--border2);border-radius:7px; | |
| padding:0.6rem 0.85rem;font-size:0.72rem;font-weight:600;color:var(--subtle);white-space:nowrap;} | |
| .pipe-box.hl{border-color:var(--red);color:var(--red2);background:var(--red-dim);} | |
| .pipe-num{font-size:0.55rem;color:var(--muted);margin-bottom:0.25rem;font-family:var(--mono);} | |
| .pipe-arrow{color:var(--border2);font-size:0.85rem;padding:0 0.3rem;flex-shrink:0;} | |
| /* Step list */ | |
| .step-list{margin:1rem 0;} | |
| .step-item{display:flex;gap:0.85rem;margin-bottom:1.1rem;} | |
| .step-num-circle{width:24px;height:24px;background:var(--red);color:#fff;border-radius:50%; | |
| display:flex;align-items:center;justify-content:center;font-size:0.68rem; | |
| font-weight:800;flex-shrink:0;margin-top:0.1rem;} | |
| .step-body h4{font-size:0.85rem;font-weight:700;margin-bottom:0.2rem;} | |
| .step-body p{font-size:0.78rem;color:var(--muted);margin:0;} | |
| @media(max-width:800px){.page{grid-template-columns:1fr;}.sidebar{display:none;} | |
| .card-grid{grid-template-columns:1fr;}.stat-item{padding:0.85rem 1rem;}} | |
| </style> | |
| </head> | |
| <body> | |
| <nav class="topnav"> | |
| <a class="logo" href="/ui"> | |
| <div class="logo-box">π§ </div> | |
| NEURO<span>SCOPE</span> AI<span class="logo-docs"> Docs</span> | |
| </a> | |
| <ul class="topnav-links"> | |
| <li><a href="#overview" class="active">Overview</a></li> | |
| <li><a href="#architecture">Architecture</a></li> | |
| <li><a href="#models">Models</a></li> | |
| <li><a href="#api">API Reference</a></li> | |
| <li><a href="#quickstart">Quickstart</a></li> | |
| </ul> | |
| <a class="back-btn" href="/ui">β Back to App</a> | |
| </nav> | |
| <!-- Hero --> | |
| <section class="hero"> | |
| <div class="hero-eyebrow">NCI Ireland Β· Multi-Cancer AI Β· v2.4.2</div> | |
| <h1>NeuroScope AI<br><em>Documentation</em></h1> | |
| <p class="hero-desc">Multi-cancer clinical decision support platform β 6 pipelines, 7 ONNX models, Microsoft SSO, and FHIR R4 export.</p> | |
| <div class="hero-ctas"> | |
| <a class="btn-primary" href="#quickstart">Get Started</a> | |
| <a class="btn-secondary" href="#api">API Reference</a> | |
| <a class="btn-secondary" href="/register">Register Institution</a> | |
| </div> | |
| </section> | |
| <!-- Stats --> | |
| <div class="stats-bar"> | |
| <div class="stat-item"><span class="stat-num">7/7</span><span class="stat-lbl">Models Loaded</span></div> | |
| <div class="stat-item"><span class="stat-num">6</span><span class="stat-lbl">Cancer Pipelines</span></div> | |
| <div class="stat-item"><span class="stat-num">30+</span><span class="stat-lbl">API Endpoints</span></div> | |
| <div class="stat-item"><span class="stat-num">0.988</span><span class="stat-lbl">Best AUC</span></div> | |
| <div class="stat-item"><span class="stat-num">FHIR R4</span><span class="stat-lbl">Export Format</span></div> | |
| </div> | |
| <div class="page"> | |
| <!-- Sidebar --> | |
| <aside class="sidebar"> | |
| <div class="sb-group"> | |
| <div class="sb-group-title">Introduction</div> | |
| <a href="#overview" class="active">Overview</a> | |
| <a href="#quickstart">Quickstart</a> | |
| </div> | |
| <div class="sb-group"> | |
| <div class="sb-group-title">Platform</div> | |
| <a href="#architecture">Architecture</a> | |
| <a href="#models">Models & Performance</a> | |
| <a href="#auth">Authentication</a> | |
| <a href="#roles">Roles & Access</a> | |
| </div> | |
| <div class="sb-group"> | |
| <div class="sb-group-title">API Reference</div> | |
| <a href="#api">Core Endpoints</a> | |
| <a href="#scan-api">Scan Analysis</a> | |
| <a href="#hospital-api">Hospital Management</a> | |
| <a href="#admin-api">Admin Endpoints</a> | |
| <a href="#fhir-api">FHIR Export</a> | |
| </div> | |
| <div class="sb-group"> | |
| <div class="sb-group-title">Reference</div> | |
| <a href="#cancer-pipelines">Cancer Pipelines</a> | |
| <a href="#legal">Legal & Compliance</a> | |
| </div> | |
| </aside> | |
| <!-- Content --> | |
| <main class="content"> | |
| <!-- Overview --> | |
| <section class="doc-section" id="overview"> | |
| <div class="section-eyebrow">Introduction</div> | |
| <h2>What is NeuroScope AI?</h2> | |
| <p>NeuroScope AI is a multi-cancer clinical decision support platform built for NHS and international hospitals. It combines 7 validated ONNX model pipelines with Microsoft Entra ID SSO, federated learning, and full FHIR R4 export β all in a single FastAPI deployment on HuggingFace Spaces.</p> | |
| <div class="card-grid"> | |
| <div class="doc-card red"><div class="card-icon">π§ </div><div class="card-title">6 Cancer Pipelines</div><div class="card-body">Brain, Lung, Breast, Liver, Skin, Spine β each with dedicated ONNX models.</div></div> | |
| <div class="doc-card teal"><div class="card-icon">π</div><div class="card-title">Microsoft Entra ID SSO</div><div class="card-body">Role-based access: superadmin, admin, clinician, viewer. OAuth2 token flow.</div></div> | |
| <div class="doc-card gold"><div class="card-icon">π</div><div class="card-title">FHIR R4 + ICD-10</div><div class="card-body">Every scan exports a FHIR DiagnosticReport with ICD-10 codes and NCCN treatment recs.</div></div> | |
| <div class="doc-card"><div class="card-icon">πΊοΈ</div><div class="card-title">Grad-CAM++ + TIxAI</div><div class="card-body">Per-scan explainability heatmaps with trustworthiness index scoring.</div></div> | |
| <div class="doc-card"><div class="card-icon">π</div><div class="card-title">Federated Learning</div><div class="card-body">DP-SGD with Opacus. Patient data never leaves the institution.</div></div> | |
| <div class="doc-card"><div class="card-icon">π₯</div><div class="card-title">Hospital Workflow</div><div class="card-body">Registration, approval, multi-hospital management, audit logging.</div></div> | |
| </div> | |
| <div class="callout callout-danger">β NeuroScope AI is a clinical decision support tool, not a medical device. All AI outputs must be reviewed by a qualified clinician before clinical action.</div> | |
| </section> | |
| <!-- Quickstart --> | |
| <section class="doc-section" id="quickstart"> | |
| <div class="section-eyebrow">Getting Started</div> | |
| <h2>Quickstart</h2> | |
| <p>Get access to NeuroScope AI in three steps.</p> | |
| <div class="step-list"> | |
| <div class="step-item"> | |
| <div class="step-num-circle">1</div> | |
| <div class="step-body"> | |
| <h4>Register your institution</h4> | |
| <p>Complete the hospital registration form at <a href="/register" style="color:var(--red2)">/register</a>. Your application is reviewed within 2 business days.</p> | |
| </div> | |
| </div> | |
| <div class="step-item"> | |
| <div class="step-num-circle">2</div> | |
| <div class="step-body"> | |
| <h4>Sign in with Microsoft SSO</h4> | |
| <p>Once approved, sign in at <a href="/ui" style="color:var(--red2)">/ui</a> using your institutional Microsoft account.</p> | |
| </div> | |
| </div> | |
| <div class="step-item"> | |
| <div class="step-num-circle">3</div> | |
| <div class="step-body"> | |
| <h4>Upload a scan and analyze</h4> | |
| <div class="code-wrap"> | |
| <div class="code-hdr"><span class="code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">Copy</button></div> | |
| <pre><span class="kw">import</span> requests | |
| res = requests.post( | |
| <span class="str">"https://tejansree-neuroscope-ai.hf.space/scan"</span>, | |
| headers={<span class="str">"Authorization"</span>: <span class="str">"Bearer YOUR_TOKEN"</span>}, | |
| files={<span class="str">"file"</span>: open(<span class="str">"brain_mri.jpg"</span>, <span class="str">"rb"</span>)}, | |
| data={<span class="str">"cancer_type"</span>: <span class="str">"brain"</span>, <span class="str">"patient_id"</span>: <span class="str">"PT-001"</span>} | |
| ) | |
| print(res.json()[<span class="str">"verdict"</span>]) <span class="cm"># CANCER_DETECTED / NORMAL / REVIEW</span></pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Architecture --> | |
| <section class="doc-section" id="architecture"> | |
| <div class="section-eyebrow">Platform</div> | |
| <h2>Architecture</h2> | |
| <p>NeuroScope AI is a single FastAPI service on HuggingFace Spaces, serving 7 ONNX models with Microsoft Entra ID SSO and Supabase (primary) + JSON file fallback data layer.</p> | |
| <div class="pipeline"> | |
| <div class="pipe-step"><div class="pipe-num">01</div><div class="pipe-box hl">Upload Scan</div></div> | |
| <div class="pipe-arrow">β</div> | |
| <div class="pipe-step"><div class="pipe-num">02</div><div class="pipe-box">Auth Check</div></div> | |
| <div class="pipe-arrow">β</div> | |
| <div class="pipe-step"><div class="pipe-num">03</div><div class="pipe-box hl">ONNX Inference</div></div> | |
| <div class="pipe-arrow">β</div> | |
| <div class="pipe-step"><div class="pipe-num">04</div><div class="pipe-box">Grad-CAM++</div></div> | |
| <div class="pipe-arrow">β</div> | |
| <div class="pipe-step"><div class="pipe-num">05</div><div class="pipe-box hl">FHIR Report</div></div> | |
| <div class="pipe-arrow">β</div> | |
| <div class="pipe-step"><div class="pipe-num">06</div><div class="pipe-box">Audit Log</div></div> | |
| </div> | |
| <h3>Tech Stack</h3> | |
| <table class="doc-table"> | |
| <tr><th>Layer</th><th>Technology</th><th>Purpose</th></tr> | |
| <tr><td>API</td><td>FastAPI + Uvicorn</td><td>30+ REST endpoints</td></tr> | |
| <tr><td>Auth</td><td>Microsoft Entra ID</td><td>SSO, RBAC, token validation</td></tr> | |
| <tr><td>Models</td><td>ONNX Runtime (INT8)</td><td>7 quantised cancer detection models</td></tr> | |
| <tr><td>Database</td><td>Supabase + JSON fallback</td><td>Scan results, hospitals, audit logs</td></tr> | |
| <tr><td>Hosting</td><td>HuggingFace Spaces</td><td>Production deployment</td></tr> | |
| <tr><td>Privacy</td><td>Opacus DP-SGD</td><td>Federated learning with Ξ΅<10</td></tr> | |
| </table> | |
| </section> | |
| <!-- Models --> | |
| <section class="doc-section" id="models"> | |
| <div class="section-eyebrow">Platform</div> | |
| <h2>Models & Performance</h2> | |
| <p>Seven ONNX INT8 quantised models loaded at startup. All trained on publicly available datasets and validated on held-out test sets.</p> | |
| <table class="doc-table"> | |
| <tr><th>Model Key</th><th>Cancer Type</th><th>Architecture</th><th>Modality</th><th>Performance</th></tr> | |
| <tr><td>brain_cls</td><td>Brain</td><td>EfficientNet-B4</td><td>MRI</td><td class="auc">AUC 0.9882</td></tr> | |
| <tr><td>brain_seg</td><td>Brain Segmentation</td><td>SegResNet</td><td>MRI</td><td class="auc">Dice 0.8351</td></tr> | |
| <tr><td>lung_det</td><td>Lung Nodule</td><td>ResNet3D</td><td>CT</td><td class="auc">AUC 0.9816</td></tr> | |
| <tr><td>breast_det</td><td>Breast</td><td>EfficientNet-B5</td><td>Ultrasound</td><td class="auc">AUC 0.8693</td></tr> | |
| <tr><td>liver_seg</td><td>Liver</td><td>ResUNet</td><td>CT</td><td class="auc">Dice 0.5773 β </td></tr> | |
| <tr><td>skin_cls</td><td>Skin</td><td>EfficientNet-B4</td><td>Dermoscopy</td><td class="auc">MelAUC 0.8995</td></tr> | |
| <tr><td>spine_cls</td><td>Spine</td><td>HybridSpineNet</td><td>MRI</td><td class="auc">MeanAUC 0.7112</td></tr> | |
| </table> | |
| <div class="callout callout-warn">β Liver segmentation (Dice 0.5773) is research preview only β binary tumor segmentation due to dataset limitations. Not for clinical use.</div> | |
| </section> | |
| <!-- Auth --> | |
| <section class="doc-section" id="auth"> | |
| <div class="section-eyebrow">Platform</div> | |
| <h2>Authentication</h2> | |
| <p>NeuroScope AI uses Microsoft Entra ID (formerly Azure AD) for SSO. All API endpoints (except /health, /register, /tos, /dpa, /docs) require a valid Bearer token.</p> | |
| <div class="code-wrap"> | |
| <div class="code-hdr"><span class="code-lang">http</span><button class="copy-btn" onclick="copyCode(this)">Copy</button></div> | |
| <pre>Authorization: Bearer <microsoft_access_token></pre> | |
| </div> | |
| <p>Tokens are obtained via the Microsoft OAuth2 flow. The UI handles this automatically via the Sign in with Microsoft button.</p> | |
| </section> | |
| <!-- Roles --> | |
| <section class="doc-section" id="roles"> | |
| <div class="section-eyebrow">Platform</div> | |
| <h2>Roles & Access Control</h2> | |
| <table class="doc-table"> | |
| <tr><th>Role</th><th>Access Level</th><th>Permissions</th></tr> | |
| <tr><td>superadmin</td><td>Global</td><td>All endpoints, all hospitals, system config</td></tr> | |
| <tr><td>admin</td><td>Hospital</td><td>Approve users, view all hospital scans, manage settings</td></tr> | |
| <tr><td>clinician</td><td>Hospital</td><td>Upload scans, view results, export FHIR, provide feedback</td></tr> | |
| <tr><td>viewer</td><td>Hospital</td><td>View scan results only β read-only access</td></tr> | |
| </table> | |
| </section> | |
| <!-- API Reference --> | |
| <section class="doc-section" id="api"> | |
| <div class="section-eyebrow">API Reference</div> | |
| <h2>Core Endpoints</h2> | |
| <p>Base URL: <code style="color:var(--red2);font-family:var(--mono)">https://tejansree-neuroscope-ai.hf.space</code></p> | |
| <table class="doc-table"> | |
| <tr><th>Method</th><th>Endpoint</th><th>Auth</th><th>Description</th></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/health</td><td>None</td><td>API status, model count, version</td></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/models</td><td>None</td><td>List all loaded models and status</td></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/ui</td><td>None</td><td>Main dashboard HTML</td></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/register</td><td>None</td><td>Hospital registration form</td></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/tos</td><td>None</td><td>Terms of Service</td></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/dpa</td><td>None</td><td>Data Processing Agreement</td></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/docs</td><td>None</td><td>This documentation page</td></tr> | |
| </table> | |
| </section> | |
| <section class="doc-section" id="scan-api"> | |
| <h2>Scan Analysis</h2> | |
| <table class="doc-table"> | |
| <tr><th>Method</th><th>Endpoint</th><th>Description</th></tr> | |
| <tr><td><span class="tag tag-post">POST</span></td><td>/scan</td><td>Upload and analyze a single medical scan</td></tr> | |
| <tr><td><span class="tag tag-post">POST</span></td><td>/scan/batch</td><td>Batch analyze multiple scans</td></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/scan/{scan_id}</td><td>Retrieve a previous scan result</td></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/scan/{scan_id}/fhir</td><td>FHIR R4 DiagnosticReport export</td></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/patient/{id}/history</td><td>All scans for a patient</td></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/scan/{id}/feedback</td><td>Get clinician feedback on a scan</td></tr> | |
| <tr><td><span class="tag tag-post">POST</span></td><td>/scan/{id}/feedback</td><td>Submit clinician feedback</td></tr> | |
| </table> | |
| <h3>POST /scan β Example</h3> | |
| <div class="code-wrap"> | |
| <div class="code-hdr"><span class="code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">Copy</button></div> | |
| <pre>res = requests.post( | |
| <span class="str">"https://tejansree-neuroscope-ai.hf.space/scan"</span>, | |
| headers={<span class="str">"Authorization"</span>: <span class="str">"Bearer TOKEN"</span>}, | |
| files={<span class="str">"file"</span>: open(<span class="str">"scan.jpg"</span>, <span class="str">"rb"</span>)}, | |
| data={ | |
| <span class="str">"cancer_type"</span>: <span class="str">"brain"</span>, <span class="cm"># brain|lung|breast|liver|skin|spine</span> | |
| <span class="str">"patient_id"</span>: <span class="str">"PT-2024-001"</span>, | |
| <span class="str">"patient_age"</span>: <span class="str">"52"</span>, | |
| <span class="str">"patient_sex"</span>: <span class="str">"female"</span>, | |
| } | |
| ) | |
| data = res.json() | |
| print(data[<span class="str">"verdict"</span>]) <span class="cm"># CANCER_DETECTED / NORMAL / REVIEW_REQUIRED</span> | |
| print(data[<span class="str">"confidence"</span>]) <span class="cm"># 0.934</span> | |
| print(data[<span class="str">"icd10"</span>]) <span class="cm"># C71.9</span></pre> | |
| </div> | |
| </section> | |
| <section class="doc-section" id="hospital-api"> | |
| <h2>Hospital Management</h2> | |
| <table class="doc-table"> | |
| <tr><th>Method</th><th>Endpoint</th><th>Role</th><th>Description</th></tr> | |
| <tr><td><span class="tag tag-post">POST</span></td><td>/hospital/register</td><td>Public</td><td>Submit hospital registration</td></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/hospital/approval</td><td>Any</td><td>Check registration status</td></tr> | |
| <tr><td><span class="tag tag-post">POST</span></td><td>/hospital/approve</td><td>Superadmin</td><td>Approve a pending hospital</td></tr> | |
| <tr><td><span class="tag tag-post">POST</span></td><td>/hospital/reject</td><td>Superadmin</td><td>Reject a pending hospital</td></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/hospital/list</td><td>Superadmin</td><td>List all hospitals</td></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/hospital/stats</td><td>Admin+</td><td>Hospital usage statistics</td></tr> | |
| </table> | |
| </section> | |
| <section class="doc-section" id="admin-api"> | |
| <h2>Admin Endpoints</h2> | |
| <table class="doc-table"> | |
| <tr><th>Method</th><th>Endpoint</th><th>Description</th></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/auth/audit</td><td>Audit log (last N entries)</td></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/auth/users</td><td>List users for current hospital</td></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/admin/stats</td><td>Platform-wide statistics</td></tr> | |
| <tr><td><span class="tag tag-post">POST</span></td><td>/federated/submit</td><td>Submit federated learning update</td></tr> | |
| <tr><td><span class="tag tag-get">GET</span></td><td>/federated/status</td><td>Federated learning round status</td></tr> | |
| </table> | |
| </section> | |
| <section class="doc-section" id="fhir-api"> | |
| <h2>FHIR Export</h2> | |
| <p>Every scan can be exported as a FHIR R4 DiagnosticReport with ICD-10 coding and NCCN treatment recommendations.</p> | |
| <div class="code-wrap"> | |
| <div class="code-hdr"><span class="code-lang">json</span><button class="copy-btn" onclick="copyCode(this)">Copy</button></div> | |
| <pre>{ | |
| <span class="key">"resourceType"</span>: <span class="str">"DiagnosticReport"</span>, | |
| <span class="key">"status"</span>: <span class="str">"final"</span>, | |
| <span class="key">"code"</span>: { <span class="key">"text"</span>: <span class="str">"NeuroScope AI Analysis β Brain MRI"</span> }, | |
| <span class="key">"conclusion"</span>: <span class="str">"CANCER_DETECTED: Glioblastoma (93.4%)"</span>, | |
| <span class="key">"conclusionCode"</span>: [{ | |
| <span class="key">"coding"</span>: [{ <span class="key">"system"</span>: <span class="str">"http://hl7.org/fhir/sid/icd-10"</span>, <span class="key">"code"</span>: <span class="str">"C71.9"</span> }] | |
| }] | |
| }</pre> | |
| </div> | |
| </section> | |
| <!-- Cancer Pipelines --> | |
| <section class="doc-section" id="cancer-pipelines"> | |
| <div class="section-eyebrow">Reference</div> | |
| <h2>Cancer Pipelines</h2> | |
| <table class="doc-table"> | |
| <tr><th>Pipeline</th><th>cancer_type value</th><th>Input</th><th>ICD-10</th><th>Status</th></tr> | |
| <tr><td>Brain</td><td><span class="tag tag-red">brain</span></td><td>MRI (JPEG/NIfTI)</td><td>C71.x</td><td><span class="tag tag-teal">Production</span></td></tr> | |
| <tr><td>Lung</td><td><span class="tag tag-red">lung</span></td><td>CT scan (JPEG)</td><td>C34.x</td><td><span class="tag tag-teal">Production</span></td></tr> | |
| <tr><td>Breast</td><td><span class="tag tag-red">breast</span></td><td>Ultrasound (JPEG)</td><td>C50.x</td><td><span class="tag tag-teal">Production</span></td></tr> | |
| <tr><td>Liver</td><td><span class="tag tag-red">liver</span></td><td>CT scan (JPEG)</td><td>C22.x</td><td><span class="tag tag-muted">Research Preview</span></td></tr> | |
| <tr><td>Skin</td><td><span class="tag tag-red">skin</span></td><td>Dermoscopy (JPEG)</td><td>C43.x</td><td><span class="tag tag-teal">Production</span></td></tr> | |
| <tr><td>Spine</td><td><span class="tag tag-red">spine</span></td><td>MRI (JPEG)</td><td>C41.2</td><td><span class="tag tag-teal">Production</span></td></tr> | |
| </table> | |
| </section> | |
| <!-- Legal --> | |
| <section class="doc-section" id="legal"> | |
| <div class="section-eyebrow">Reference</div> | |
| <h2>Legal & Compliance</h2> | |
| <div class="card-grid card-grid-2"> | |
| <div class="doc-card teal"> | |
| <div class="card-icon">π</div> | |
| <div class="card-title">Terms of Service</div> | |
| <div class="card-body">Usage terms, medical disclaimer, eligibility requirements, and limitation of liability. <a href="/tos" style="color:var(--teal)">Read TOS β</a></div> | |
| </div> | |
| <div class="doc-card"> | |
| <div class="card-icon">π</div> | |
| <div class="card-title">Data Processing Agreement</div> | |
| <div class="card-body">GDPR Article 28 compliant DPA governing patient data processing. <a href="/dpa" style="color:var(--red2)">Read DPA β</a></div> | |
| </div> | |
| </div> | |
| <div class="callout callout-info"> | |
| π‘ NeuroScope AI has not received FDA clearance, CE marking, or MHRA registration as a medical device. It is a clinical decision support tool for use by qualified clinicians only. | |
| </div> | |
| </section> | |
| </main> | |
| </div> | |
| <script> | |
| function copyCode(btn) { | |
| const pre = btn.closest('.code-wrap').querySelector('pre'); | |
| navigator.clipboard.writeText(pre.textContent); | |
| btn.textContent = 'Copied!'; | |
| setTimeout(() => btn.textContent = 'Copy', 1500); | |
| } | |
| // Scroll spy | |
| const sections = document.querySelectorAll('.doc-section'); | |
| const links = document.querySelectorAll('.sidebar a'); | |
| const navLinks = document.querySelectorAll('.topnav-links a'); | |
| const content = document.querySelector('.content'); | |
| const obs = new IntersectionObserver(entries => { | |
| entries.forEach(e => { | |
| if(e.isIntersecting) { | |
| const id = e.target.id; | |
| links.forEach(a => a.classList.toggle('active', a.getAttribute('href')==='#'+id)); | |
| navLinks.forEach(a => a.classList.toggle('active', a.getAttribute('href')==='#'+id)); | |
| } | |
| }); | |
| }, {rootMargin:'-52px 0px -60% 0px'}); | |
| sections.forEach(s => obs.observe(s)); | |
| links.forEach(a => a.addEventListener('click', e => { | |
| e.preventDefault(); | |
| document.querySelector(a.getAttribute('href'))?.scrollIntoView({behavior:'smooth'}); | |
| })); | |
| </script> | |
| </body> | |
| </html> | |