Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import requests | |
| import json | |
| # ==================== API Functions ==================== | |
| def check_api_health(api_url): | |
| """Check if the backend API is healthy""" | |
| try: | |
| response = requests.get(f"{api_url}/api/v1/health", timeout=10) | |
| response.raise_for_status() | |
| health_data = response.json() | |
| return f"β API Status: {health_data.get('status', 'Unknown')}\n\nService: {health_data.get('service', 'N/A')}" | |
| except requests.exceptions.Timeout: | |
| return "β API Health Check Failed: Request timed out" | |
| except requests.exceptions.RequestException as e: | |
| return f"β API Health Check Failed: {str(e)}" | |
| except Exception as e: | |
| return f"β Unexpected Error: {str(e)}" | |
| def analyze_provider_notes(api_url, provider_notes, progress=gr.Progress()): | |
| """Send provider notes to backend API for analysis""" | |
| if not provider_notes or not provider_notes.strip(): | |
| return "β οΈ Please enter provider notes before analyzing.", "", "" | |
| 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...") | |
| # Format ICD codes | |
| icd_output = format_icd_codes(result.get("icd_codes", [])) | |
| # Format CPT codes | |
| cpt_output = format_cpt_codes(result.get("cpt_codes", [])) | |
| # Overall summary | |
| summary = result.get("overall_summary", "No summary available") | |
| summary_output = f"### π Overall Summary\n\n{summary}\n\n---\n" | |
| progress(1.0, desc="Complete!") | |
| return summary_output, icd_output, cpt_output | |
| except requests.exceptions.Timeout: | |
| return "β Request timed out. The API is taking too long to respond.", "", "" | |
| 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: {str(e)}", "", "" | |
| except Exception as e: | |
| return f"β Unexpected Error: {str(e)}", "", "" | |
| def format_icd_codes(icd_codes): | |
| """Format ICD codes for display""" | |
| if not icd_codes: | |
| return "βΉοΈ No ICD-10 codes identified from the provider notes." | |
| output = "### π₯ ICD-10 Diagnostic Codes\n\n" | |
| for idx, icd in enumerate(icd_codes, 1): | |
| output += f"**{idx}. Code: `{icd.get('code', 'N/A')}`**\n\n" | |
| output += f"**Description:** {icd.get('description', 'N/A')}\n\n" | |
| output += f"**Explanation:**\n{icd.get('explanation', 'N/A')}\n\n" | |
| output += "---\n\n" | |
| return output | |
| def format_cpt_codes(cpt_codes): | |
| """Format CPT codes for display""" | |
| if not cpt_codes: | |
| return "βΉοΈ No CPT codes identified from the provider notes." | |
| output = "### πΌ CPT Procedure Codes\n\n" | |
| for idx, cpt in enumerate(cpt_codes, 1): | |
| output += f"**{idx}. Code: `{cpt.get('code', 'N/A')}`**\n\n" | |
| output += f"**Description:** {cpt.get('description', 'N/A')}\n\n" | |
| output += f"**Explanation:**\n{cpt.get('explanation', 'N/A')}\n\n" | |
| output += "---\n\n" | |
| return output | |
| def load_example(): | |
| """Load example provider notes""" | |
| return """Patient presents with acute bronchitis. Cough for 5 days, productive with yellow sputum. Lung exam reveals diffuse wheezing. Prescribed azithromycin 500mg.""" | |
| def clear_all(): | |
| """Clear all fields""" | |
| return "", "", "", "" | |
| # ==================== Gradio Interface ==================== | |
| # Custom CSS | |
| custom_css = """ | |
| .gradio-container { | |
| font-family: 'Arial', sans-serif; | |
| } | |
| .header { | |
| text-align: center; | |
| padding: 20px; | |
| background: linear-gradient(90deg, #1f77b4 0%, #2ca02c 100%); | |
| color: white; | |
| border-radius: 10px; | |
| margin-bottom: 20px; | |
| } | |
| .footer { | |
| text-align: center; | |
| margin-top: 30px; | |
| padding: 15px; | |
| color: #666; | |
| font-size: 0.9em; | |
| } | |
| """ | |
| # Create Gradio Interface | |
| with gr.Blocks(css=custom_css, title="ICD-10 & CPT Coding Assistant") as demo: | |
| # Header | |
| gr.HTML(""" | |
| <div class="header"> | |
| <h1>π₯ ICD-10 & CPT Coding Assistant</h1> | |
| <p>AI-Powered Medical Coding Analysis using Groq LLaMA 3.3 70B</p> | |
| </div> | |
| """) | |
| # API Configuration | |
| with gr.Accordion("βοΈ API Configuration", open=False): | |
| api_url_input = gr.Textbox( | |
| label="Backend API URL", | |
| value="https://Distopia22-icd-cpt-coding-api.hf.space", | |
| placeholder="https://your-backend-api.hf.space", | |
| info="Enter your FastAPI backend URL" | |
| ) | |
| api_health_btn = gr.Button("π Check API Status", variant="secondary", size="sm") | |
| api_health_output = gr.Textbox(label="API Status", lines=3, interactive=False) | |
| gr.Markdown("---") | |
| # Main Content - Two Columns | |
| with gr.Row(): | |
| # Left Column - Input | |
| with gr.Column(scale=1): | |
| gr.Markdown("### π Provider Notes Input") | |
| provider_notes_input = gr.Textbox( | |
| label="Enter Clinical Provider Notes", | |
| placeholder="Enter detailed clinical documentation here...", | |
| lines=15, | |
| max_lines=20, | |
| info="Provide comprehensive clinical notes for accurate coding" | |
| ) | |
| with gr.Row(): | |
| analyze_btn = gr.Button("π¬ Analyze & Generate Codes", variant="primary", size="lg") | |
| clear_btn = gr.Button("ποΈ Clear All", variant="secondary", size="lg") | |
| example_btn = gr.Button("π Load Example", variant="secondary", size="lg") | |
| # Right Column - Output | |
| with gr.Column(scale=1): | |
| gr.Markdown("### π Analysis Results") | |
| summary_output = gr.Markdown(label="Summary", value="*Enter provider notes and click 'Analyze' to see results*") | |
| with gr.Tabs(): | |
| with gr.Tab("π₯ ICD-10 Codes"): | |
| icd_output = gr.Markdown(value="*No results yet*") | |
| with gr.Tab("πΌ CPT Codes"): | |
| cpt_output = gr.Markdown(value="*No results yet*") | |
| # Information Section | |
| gr.Markdown("---") | |
| with gr.Accordion("βΉοΈ How to Use This Application", open=False): | |
| gr.Markdown(""" | |
| ### π Instructions: | |
| 1. **Configure API**: Ensure the backend API URL is correct (default is set) | |
| 2. **Check API Status**: Click 'Check API Status' to verify connection | |
| 3. **Enter Notes**: Type or paste clinical provider notes in the text area | |
| 4. **Load Example**: Click 'Load Example' to see a sample note | |
| 5. **Analyze**: Click 'Analyze & Generate Codes' to process the notes | |
| 6. **Review Results**: View ICD-10 and CPT codes in the tabs on the right | |
| ### π Privacy & Security: | |
| - All data is processed securely via encrypted API calls | |
| - No patient data is stored on servers | |
| - Compliant with healthcare data standards | |
| ### β‘ Features: | |
| - Real-time AI analysis using Groq LLaMA 3.3 70B | |
| - Detailed explanations for each code | |
| - Separate ICD-10 and CPT code categorization | |
| - Overall summary of coding decisions | |
| """) | |
| # 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 ICD-CPT Coding Assistant</p> | |
| </div> | |
| """) | |
| # ==================== Event Handlers ==================== | |
| # Check API Health | |
| api_health_btn.click( | |
| fn=check_api_health, | |
| inputs=[api_url_input], | |
| outputs=[api_health_output] | |
| ) | |
| # Analyze Provider Notes | |
| analyze_btn.click( | |
| fn=analyze_provider_notes, | |
| inputs=[api_url_input, provider_notes_input], | |
| outputs=[summary_output, icd_output, cpt_output] | |
| ) | |
| # Load Example | |
| example_btn.click( | |
| fn=load_example, | |
| inputs=[], | |
| outputs=[provider_notes_input] | |
| ) | |
| # Clear All | |
| clear_btn.click( | |
| fn=clear_all, | |
| inputs=[], | |
| outputs=[provider_notes_input, summary_output, icd_output, cpt_output] | |
| ) | |
| # Launch the app | |
| if __name__ == "__main__": | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=False | |
| ) |