Spaces:
Sleeping
Sleeping
File size: 8,530 Bytes
d7c0aa2 2101408 d7c0aa2 c953011 d7c0aa2 c953011 d7c0aa2 c953011 d7c0aa2 c953011 d7c0aa2 c953011 d7c0aa2 c953011 d7c0aa2 c953011 d7c0aa2 c953011 7d58419 c953011 2101408 d7c0aa2 c953011 2101408 08eb6be c953011 d7c0aa2 c953011 d7c0aa2 c953011 d7c0aa2 518996e c953011 d7c0aa2 c953011 d7c0aa2 c953011 d7c0aa2 c953011 d7c0aa2 c953011 d7c0aa2 2101408 c953011 2101408 d7c0aa2 c953011 7d58419 c953011 d7c0aa2 c953011 7d58419 d7c0aa2 2101408 518996e 2101408 c953011 d7c0aa2 2101408 c953011 2101408 c953011 2101408 d7c0aa2 c953011 d7c0aa2 08eb6be d7c0aa2 518996e c953011 2101408 c953011 2101408 c953011 2101408 c953011 2101408 7d58419 c953011 2101408 d7c0aa2 7d58419 d7c0aa2 08eb6be 2101408 08eb6be c953011 d7c0aa2 c953011 d7c0aa2 08eb6be d7c0aa2 c953011 d7c0aa2 518996e d7c0aa2 f2fd281 d7c0aa2 |
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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
import gradio as gr
import requests
import json
import os
# ==================== API Functions ====================
def analyze_provider_notes(provider_notes, api_url, progress=gr.Progress()):
"""Send provider notes to backend API for analysis"""
if not provider_notes or not provider_notes.strip():
return generate_empty_response()
progress(0, desc="Starting analysis...")
try:
payload = {"provider_notes": provider_notes}
progress(0.3, desc="Sending request to API...")
response = requests.post(
f"{api_url}/api/v1/analyze",
json=payload,
headers={"Content-Type": "application/json"},
timeout=60
)
progress(0.6, desc="Processing response...")
response.raise_for_status()
result = response.json()
progress(0.9, desc="Formatting results...")
formatted_response = format_complete_response(result)
progress(1.0, desc="Complete!")
return formatted_response
except requests.exceptions.Timeout:
return "β **Request Timeout**\n\nThe API is taking too long to respond. Please try again."
except requests.exceptions.HTTPError as e:
return f"β **HTTP Error {e.response.status_code}**\n\n{e.response.text}"
except requests.exceptions.RequestException as e:
return f"β **Request Error**\n\n{str(e)}"
except Exception as e:
return f"β **Unexpected Error**\n\n{str(e)}"
def generate_empty_response():
"""Generate empty response message"""
return """
### π¬ Welcome to Medical Coding (ICD-10) Assistant
Please enter provider notes in the text box below and click **Send** to analyze.
**Tips:**
- Provide detailed clinical documentation
- Include symptoms, diagnoses, and procedures
- Be specific about treatments and prescriptions
**How to use:**
1. Select an example from the sidebar, or
2. Upload documents via the Upload button
3. Type your own clinical notes below
4. Click the **Send** button
5. Review the ICD-10 and CPT codes generated
"""
def format_complete_response(result):
"""Format complete analysis response"""
output = "---\n\n"
if result.get("overall_summary"):
output += f"### π Overall Summary\n\n{result['overall_summary']}\n\n---\n\n"
output += "### π₯ ICD-10 Diagnostic Codes\n\n"
icd_codes = result.get("icd_codes", [])
if icd_codes:
for idx, icd in enumerate(icd_codes, 1):
output += f"**{idx}. {icd.get('code', 'N/A')}** - {icd.get('description', 'N/A')}\n\n"
output += f"*Explanation:* {icd.get('explanation', 'N/A')}\n\n"
else:
output += "*No ICD-10 codes identified*\n\n"
output += "---\n\n"
output += "### πΌ CPT Procedure Codes\n\n"
cpt_codes = result.get("cpt_codes", [])
if cpt_codes:
for idx, cpt in enumerate(cpt_codes, 1):
output += f"**{idx}. {cpt.get('code', 'N/A')}** - {cpt.get('description', 'N/A')}\n\n"
output += f"*Explanation:* {cpt.get('explanation', 'N/A')}\n\n"
else:
output += "*No CPT codes identified*\n\n"
return output
# ==================== Example Notes ====================
EXAMPLES = {
"Acute Bronchitis": """Patient presents with acute bronchitis. Cough for 5 days, productive with yellow sputum. Lung exam reveals diffuse wheezing. Prescribed azithromycin 500mg.""",
"Type 2 Diabetes": """Patient with type 2 diabetes mellitus, uncontrolled. HbA1c 9.2%. Discussed diet and medication compliance. Adjusted insulin dosing. Referred to diabetes educator.""",
"Hypertension Follow-up": """Follow-up visit for hypertension. Blood pressure 145/92. Patient reports good medication compliance. Continue current antihypertensive regimen. Return in 3 months.""",
}
def load_example(example_name):
"""Load example provider notes"""
return EXAMPLES.get(example_name, "")
# ==================== Load External CSS ====================
def load_css():
"""Load external CSS file"""
css_path = os.path.join(os.path.dirname(__file__), "assets", "styles.css")
try:
with open(css_path, "r", encoding="utf-8") as f:
return f.read()
except FileNotFoundError:
print("Warning: styles.css not found")
return ""
# ==================== Gradio Interface ====================
with gr.Blocks(css=load_css(), theme=gr.themes.Soft(), title="Medical Coding (ICD-10) Assistant") as demo:
api_url_state = gr.State(value="https://Distopia22-icd-cpt-coding-api.hf.space")
# Header
gr.HTML("""
<div class="header-container">
<h1>π₯ Medical Coding (ICD-10) Assistant</h1>
<p>AI-Powered Medical Coding Analysis using Groq LLaMA 3.3 70B</p>
</div>
""")
with gr.Row(elem_classes="main-container"):
# Left Sidebar
with gr.Column(scale=1, min_width=280, elem_classes="sidebar"):
gr.HTML('<div class="sidebar-title">π Example Cases</div>')
example_buttons = {}
for example_name in EXAMPLES.keys():
btn = gr.Button(
f"π {example_name}",
elem_classes="example-btn"
)
example_buttons[example_name] = btn
gr.Markdown("---")
# Upload Document Section - Redirects to API Docs
gr.HTML('<div class="sidebar-title">π€ Upload Document</div>')
gr.HTML("""
<a href="https://distopia22-icd-cpt-coding-api-backend.hf.space/docs" target="_blank" style="text-decoration: none;">
<button class="upload-redirect-button">
π Upload via API Docs
</button>
</a>
<div style="background: rgba(255,255,255,0.1); padding: 10px; border-radius: 8px; margin-top: 10px;">
<p style="color: #e0f7f4; font-size: 0.8rem; margin: 5px 0; text-align: center;">
π Only .txt format allowed
</p>
<p style="color: #ffffff; font-size: 0.75rem; margin: 5px 0; text-align: center; opacity: 0.7;">
Click button to upload files
</p>
</div>
""")
# Right Chat Area
with gr.Column(scale=3, elem_classes="chat-container"):
output_area = gr.Markdown(
value=generate_empty_response(),
elem_classes="output-area",
label=""
)
with gr.Group(elem_classes="input-container"):
with gr.Row():
provider_notes_input = gr.Textbox(
label="",
placeholder="Enter clinical provider notes here...",
lines=3,
max_lines=5,
show_label=False,
elem_classes="prompt-input"
)
with gr.Row():
send_btn = gr.Button("π Send", elem_classes="send-button", size="sm")
clear_btn = gr.Button("ποΈ Clear", elem_classes="clear-button", size="sm")
# Footer
gr.HTML("""
<div class="footer">
<p>Powered by <strong>Groq LLaMA 3.3 70B</strong> | <strong>FastAPI</strong> | <strong>Gradio</strong></p>
<p>Β© 2025 Medical Coding Assistant - Secure & HIPAA Compliant</p>
</div>
""")
# ==================== Event Handlers ====================
# Example button clicks
for example_name, btn in example_buttons.items():
btn.click(
fn=lambda name=example_name: load_example(name),
outputs=[provider_notes_input]
)
# Send button - Analyze notes
send_btn.click(
fn=analyze_provider_notes,
inputs=[provider_notes_input, api_url_state],
outputs=[output_area]
)
# Clear button
clear_btn.click(
fn=lambda: ("", generate_empty_response()),
outputs=[provider_notes_input, output_area]
)
# Launch
if __name__ == "__main__":
demo.launch(
server_name="0.0.0.0",
server_port=7860,
show_error=True
) |