Distopia22's picture
Feature: Replace API config with upload redirect button
08eb6be
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
)