Distopia22 commited on
Commit
d7c0aa2
·
0 Parent(s):

Initial frontend deployment

Browse files
.gitignore ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ venv/
8
+ ENV/
9
+ env/
10
+
11
+ # Gradio
12
+ flagged/
13
+
14
+ # IDE
15
+ .vscode/
16
+ .idea/
17
+ *.swp
18
+ *.swo
19
+
20
+ # OS
21
+ .DS_Store
22
+ Thumbs.db
23
+
24
+ # Logs
25
+ *.log
README.md ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: ICD CPT Coding Frontend Gradio
3
+ emoji: 🏥
4
+ colorFrom: blue
5
+ colorTo: green
6
+ sdk: gradio
7
+ sdk_version: 4.44.0
8
+ app_file: app.py
9
+ pinned: false
10
+ license: mit
11
+ ---
12
+
13
+ # ICD-10 & CPT Coding Assistant - Gradio Frontend
14
+
15
+ AI-powered medical coding assistant that analyzes clinical provider notes and generates appropriate ICD-10 and CPT codes with detailed explanations.
16
+
17
+ ## Features
18
+
19
+ - 🔬 **AI-Powered Analysis**: Uses Groq LLaMA 3.3 70B for accurate medical coding
20
+ - 📝 **User-Friendly Interface**: Simple and intuitive Gradio UI
21
+ - 🏥 **ICD-10 Codes**: Diagnostic codes with explanations
22
+ - 💼 **CPT Codes**: Procedure codes with explanations
23
+ - 📊 **Detailed Results**: Comprehensive breakdown of coding decisions
24
+ - 🔍 **API Health Check**: Real-time backend status monitoring
25
+
26
+ ## How to Use
27
+
28
+ 1. Enter clinical provider notes in the text area
29
+ 2. Click "Analyze & Generate Codes"
30
+ 3. View ICD-10 and CPT codes in separate tabs
31
+ 4. Review explanations for each code
32
+
33
+ ## Backend API
34
+
35
+ This frontend connects to a FastAPI backend. Default URL: `https://Distopia22-icd-cpt-coding-api.hf.space`
36
+
37
+ Configure your backend URL in the API Configuration section.
38
+
39
+ ## Technology Stack
40
+
41
+ - **Frontend**: Gradio 4.44.0
42
+ - **Backend**: FastAPI
43
+ - **AI Model**: Groq LLaMA 3.3 70B Versatile
44
+ - **Deployment**: Hugging Face Spaces
45
+
46
+ ## Privacy & Security
47
+
48
+ - No patient data is stored
49
+ - All API calls are encrypted
50
+ - HIPAA-compliant processing
app.py ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import json
4
+
5
+ # ==================== API Functions ====================
6
+
7
+ def check_api_health(api_url):
8
+ """Check if the backend API is healthy"""
9
+ try:
10
+ response = requests.get(f"{api_url}/api/v1/health", timeout=10)
11
+ response.raise_for_status()
12
+ health_data = response.json()
13
+ return f"✅ API Status: {health_data.get('status', 'Unknown')}\n\nService: {health_data.get('service', 'N/A')}"
14
+ except requests.exceptions.Timeout:
15
+ return "❌ API Health Check Failed: Request timed out"
16
+ except requests.exceptions.RequestException as e:
17
+ return f"❌ API Health Check Failed: {str(e)}"
18
+ except Exception as e:
19
+ return f"❌ Unexpected Error: {str(e)}"
20
+
21
+ def analyze_provider_notes(api_url, provider_notes, progress=gr.Progress()):
22
+ """Send provider notes to backend API for analysis"""
23
+ if not provider_notes or not provider_notes.strip():
24
+ return "⚠️ Please enter provider notes before analyzing.", "", ""
25
+
26
+ progress(0, desc="Starting analysis...")
27
+
28
+ try:
29
+ payload = {"provider_notes": provider_notes}
30
+
31
+ progress(0.3, desc="Sending request to API...")
32
+
33
+ response = requests.post(
34
+ f"{api_url}/api/v1/analyze",
35
+ json=payload,
36
+ headers={"Content-Type": "application/json"},
37
+ timeout=60
38
+ )
39
+
40
+ progress(0.6, desc="Processing response...")
41
+
42
+ response.raise_for_status()
43
+ result = response.json()
44
+
45
+ progress(0.9, desc="Formatting results...")
46
+
47
+ # Format ICD codes
48
+ icd_output = format_icd_codes(result.get("icd_codes", []))
49
+
50
+ # Format CPT codes
51
+ cpt_output = format_cpt_codes(result.get("cpt_codes", []))
52
+
53
+ # Overall summary
54
+ summary = result.get("overall_summary", "No summary available")
55
+ summary_output = f"### 📋 Overall Summary\n\n{summary}\n\n---\n"
56
+
57
+ progress(1.0, desc="Complete!")
58
+
59
+ return summary_output, icd_output, cpt_output
60
+
61
+ except requests.exceptions.Timeout:
62
+ return "❌ Request timed out. The API is taking too long to respond.", "", ""
63
+ except requests.exceptions.HTTPError as e:
64
+ return f"❌ HTTP Error: {e.response.status_code}\n\n{e.response.text}", "", ""
65
+ except requests.exceptions.RequestException as e:
66
+ return f"❌ Request Error: {str(e)}", "", ""
67
+ except Exception as e:
68
+ return f"❌ Unexpected Error: {str(e)}", "", ""
69
+
70
+ def format_icd_codes(icd_codes):
71
+ """Format ICD codes for display"""
72
+ if not icd_codes:
73
+ return "ℹ️ No ICD-10 codes identified from the provider notes."
74
+
75
+ output = "### 🏥 ICD-10 Diagnostic Codes\n\n"
76
+
77
+ for idx, icd in enumerate(icd_codes, 1):
78
+ output += f"**{idx}. Code: `{icd.get('code', 'N/A')}`**\n\n"
79
+ output += f"**Description:** {icd.get('description', 'N/A')}\n\n"
80
+ output += f"**Explanation:**\n{icd.get('explanation', 'N/A')}\n\n"
81
+ output += "---\n\n"
82
+
83
+ return output
84
+
85
+ def format_cpt_codes(cpt_codes):
86
+ """Format CPT codes for display"""
87
+ if not cpt_codes:
88
+ return "ℹ️ No CPT codes identified from the provider notes."
89
+
90
+ output = "### 💼 CPT Procedure Codes\n\n"
91
+
92
+ for idx, cpt in enumerate(cpt_codes, 1):
93
+ output += f"**{idx}. Code: `{cpt.get('code', 'N/A')}`**\n\n"
94
+ output += f"**Description:** {cpt.get('description', 'N/A')}\n\n"
95
+ output += f"**Explanation:**\n{cpt.get('explanation', 'N/A')}\n\n"
96
+ output += "---\n\n"
97
+
98
+ return output
99
+
100
+ def load_example():
101
+ """Load example provider notes"""
102
+ return """Patient presents with acute bronchitis. Cough for 5 days, productive with yellow sputum. Lung exam reveals diffuse wheezing. Prescribed azithromycin 500mg."""
103
+
104
+ def clear_all():
105
+ """Clear all fields"""
106
+ return "", "", "", ""
107
+
108
+ # ==================== Gradio Interface ====================
109
+
110
+ # Custom CSS
111
+ custom_css = """
112
+ .gradio-container {
113
+ font-family: 'Arial', sans-serif;
114
+ }
115
+ .header {
116
+ text-align: center;
117
+ padding: 20px;
118
+ background: linear-gradient(90deg, #1f77b4 0%, #2ca02c 100%);
119
+ color: white;
120
+ border-radius: 10px;
121
+ margin-bottom: 20px;
122
+ }
123
+ .footer {
124
+ text-align: center;
125
+ margin-top: 30px;
126
+ padding: 15px;
127
+ color: #666;
128
+ font-size: 0.9em;
129
+ }
130
+ """
131
+
132
+ # Create Gradio Interface
133
+ with gr.Blocks(css=custom_css, title="ICD-10 & CPT Coding Assistant") as demo:
134
+
135
+ # Header
136
+ gr.HTML("""
137
+ <div class="header">
138
+ <h1>🏥 ICD-10 & CPT Coding Assistant</h1>
139
+ <p>AI-Powered Medical Coding Analysis using Groq LLaMA 3.3 70B</p>
140
+ </div>
141
+ """)
142
+
143
+ # API Configuration
144
+ with gr.Accordion("⚙️ API Configuration", open=False):
145
+ api_url_input = gr.Textbox(
146
+ label="Backend API URL",
147
+ value="https://Distopia22-icd-cpt-coding-api.hf.space",
148
+ placeholder="https://your-backend-api.hf.space",
149
+ info="Enter your FastAPI backend URL"
150
+ )
151
+
152
+ api_health_btn = gr.Button("🔍 Check API Status", variant="secondary", size="sm")
153
+ api_health_output = gr.Textbox(label="API Status", lines=3, interactive=False)
154
+
155
+ gr.Markdown("---")
156
+
157
+ # Main Content - Two Columns
158
+ with gr.Row():
159
+ # Left Column - Input
160
+ with gr.Column(scale=1):
161
+ gr.Markdown("### 📝 Provider Notes Input")
162
+
163
+ provider_notes_input = gr.Textbox(
164
+ label="Enter Clinical Provider Notes",
165
+ placeholder="Enter detailed clinical documentation here...",
166
+ lines=15,
167
+ max_lines=20,
168
+ info="Provide comprehensive clinical notes for accurate coding"
169
+ )
170
+
171
+ with gr.Row():
172
+ analyze_btn = gr.Button("🔬 Analyze & Generate Codes", variant="primary", size="lg")
173
+ clear_btn = gr.Button("🗑️ Clear All", variant="secondary", size="lg")
174
+ example_btn = gr.Button("📄 Load Example", variant="secondary", size="lg")
175
+
176
+ # Right Column - Output
177
+ with gr.Column(scale=1):
178
+ gr.Markdown("### 📊 Analysis Results")
179
+
180
+ summary_output = gr.Markdown(label="Summary", value="*Enter provider notes and click 'Analyze' to see results*")
181
+
182
+ with gr.Tabs():
183
+ with gr.Tab("🏥 ICD-10 Codes"):
184
+ icd_output = gr.Markdown(value="*No results yet*")
185
+
186
+ with gr.Tab("💼 CPT Codes"):
187
+ cpt_output = gr.Markdown(value="*No results yet*")
188
+
189
+ # Information Section
190
+ gr.Markdown("---")
191
+
192
+ with gr.Accordion("ℹ️ How to Use This Application", open=False):
193
+ gr.Markdown("""
194
+ ### 📖 Instructions:
195
+
196
+ 1. **Configure API**: Ensure the backend API URL is correct (default is set)
197
+ 2. **Check API Status**: Click 'Check API Status' to verify connection
198
+ 3. **Enter Notes**: Type or paste clinical provider notes in the text area
199
+ 4. **Load Example**: Click 'Load Example' to see a sample note
200
+ 5. **Analyze**: Click 'Analyze & Generate Codes' to process the notes
201
+ 6. **Review Results**: View ICD-10 and CPT codes in the tabs on the right
202
+
203
+ ### 🔒 Privacy & Security:
204
+ - All data is processed securely via encrypted API calls
205
+ - No patient data is stored on servers
206
+ - Compliant with healthcare data standards
207
+
208
+ ### ⚡ Features:
209
+ - Real-time AI analysis using Groq LLaMA 3.3 70B
210
+ - Detailed explanations for each code
211
+ - Separate ICD-10 and CPT code categorization
212
+ - Overall summary of coding decisions
213
+ """)
214
+
215
+ # Footer
216
+ gr.HTML("""
217
+ <div class="footer">
218
+ <p>Powered by <strong>Groq LLaMA 3.3 70B</strong> | <strong>FastAPI</strong> | <strong>Gradio</strong></p>
219
+ <p>© 2025 ICD-CPT Coding Assistant</p>
220
+ </div>
221
+ """)
222
+
223
+ # ==================== Event Handlers ====================
224
+
225
+ # Check API Health
226
+ api_health_btn.click(
227
+ fn=check_api_health,
228
+ inputs=[api_url_input],
229
+ outputs=[api_health_output]
230
+ )
231
+
232
+ # Analyze Provider Notes
233
+ analyze_btn.click(
234
+ fn=analyze_provider_notes,
235
+ inputs=[api_url_input, provider_notes_input],
236
+ outputs=[summary_output, icd_output, cpt_output]
237
+ )
238
+
239
+ # Load Example
240
+ example_btn.click(
241
+ fn=load_example,
242
+ inputs=[],
243
+ outputs=[provider_notes_input]
244
+ )
245
+
246
+ # Clear All
247
+ clear_btn.click(
248
+ fn=clear_all,
249
+ inputs=[],
250
+ outputs=[provider_notes_input, summary_output, icd_output, cpt_output]
251
+ )
252
+
253
+ # Launch the app
254
+ if __name__ == "__main__":
255
+ demo.launch(
256
+ server_name="0.0.0.0",
257
+ server_port=7860,
258
+ share=False
259
+ )
assets/styles.css ADDED
File without changes
components/__init__.py ADDED
File without changes
components/ui_components.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def create_header():
2
+ """Create application header HTML"""
3
+ return """
4
+ <div style="text-align: center; padding: 20px; background: linear-gradient(90deg, #1f77b4 0%, #2ca02c 100%); color: white; border-radius: 10px; margin-bottom: 20px;">
5
+ <h1>🏥 ICD-10 & CPT Coding Assistant</h1>
6
+ <p>AI-Powered Medical Coding Analysis</p>
7
+ </div>
8
+ """
9
+
10
+ def create_footer():
11
+ """Create application footer HTML"""
12
+ return """
13
+ <div style="text-align: center; margin-top: 30px; padding: 15px; color: #666;">
14
+ <p>Powered by <strong>Groq LLaMA 3.3 70B</strong> | <strong>FastAPI</strong> | <strong>Gradio</strong></p>
15
+ </div>
16
+ """
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio==4.44.0
2
+ requests==2.31.0
utils/__init__.py ADDED
File without changes
utils/api_client.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+
3
+ def check_api_health(api_url: str) -> dict:
4
+ """Check if the backend API is healthy"""
5
+ try:
6
+ response = requests.get(f"{api_url}/api/v1/health", timeout=10)
7
+ response.raise_for_status()
8
+ return response.json()
9
+ except Exception as e:
10
+ return {"status": "unhealthy", "error": str(e)}
11
+
12
+ def analyze_notes(api_url: str, provider_notes: str) -> dict:
13
+ """Send provider notes to backend API for analysis"""
14
+ try:
15
+ payload = {"provider_notes": provider_notes}
16
+ response = requests.post(
17
+ f"{api_url}/api/v1/analyze",
18
+ json=payload,
19
+ headers={"Content-Type": "application/json"},
20
+ timeout=60
21
+ )
22
+ response.raise_for_status()
23
+ return response.json()
24
+ except Exception as e:
25
+ return {"error": str(e)}