Update app.py
Browse files
app.py
CHANGED
@@ -4,9 +4,8 @@ import pdfplumber
|
|
4 |
import re
|
5 |
import gradio as gr
|
6 |
from typing import List, Dict
|
7 |
-
from concurrent.futures import ThreadPoolExecutor
|
8 |
import hashlib
|
9 |
-
import asyncio
|
10 |
|
11 |
# Persistent directories
|
12 |
persistent_dir = "/data/hf_cache"
|
@@ -37,7 +36,7 @@ def extract_all_pages(file_path: str) -> str:
|
|
37 |
except Exception:
|
38 |
return ""
|
39 |
|
40 |
-
|
41 |
"""Convert supported file types to text, caching results."""
|
42 |
try:
|
43 |
h = file_hash(file_path)
|
@@ -88,14 +87,13 @@ def parse_analysis_response(raw_response: str) -> Dict[str, List[str]]:
|
|
88 |
|
89 |
return sections
|
90 |
|
91 |
-
|
92 |
-
"""Analyze medical records and
|
93 |
# Split text into chunks to handle large inputs
|
94 |
chunk_size = 10000
|
95 |
chunks = [extracted_text[i:i + chunk_size] for i in range(0, len(extracted_text), chunk_size)]
|
96 |
|
97 |
# Placeholder for analysis (replace with model or rule-based logic)
|
98 |
-
# Simulate chunked analysis with sample response
|
99 |
raw_response_template = """
|
100 |
Missed Diagnoses:
|
101 |
- Undiagnosed hypertension despite elevated BP readings.
|
@@ -121,27 +119,12 @@ async def analyze_medical_records(extracted_text: str) -> str:
|
|
121 |
|
122 |
for chunk_idx, chunk in enumerate(chunks, 1):
|
123 |
# Simulate analysis per chunk (replace with real logic)
|
124 |
-
raw_response = raw_response_template
|
125 |
-
|
126 |
-
# Parse chunk response
|
127 |
parsed = parse_analysis_response(raw_response)
|
128 |
for section, items in parsed.items():
|
129 |
all_sections[section].update(items)
|
130 |
-
|
131 |
-
# Stream partial results
|
132 |
-
response = [f"### Clinical Oversight Analysis (Chunk {chunk_idx}/{len(chunks)})\n"]
|
133 |
-
has_findings = False
|
134 |
-
for section, items in all_sections.items():
|
135 |
-
response.append(f"#### {section}")
|
136 |
-
if items:
|
137 |
-
response.extend(sorted(items))
|
138 |
-
has_findings = True
|
139 |
-
else:
|
140 |
-
response.append("- None identified.")
|
141 |
-
response.append("")
|
142 |
-
yield "\n".join(response)
|
143 |
|
144 |
-
#
|
145 |
response = ["### Clinical Oversight Analysis\n"]
|
146 |
has_findings = False
|
147 |
for section, items in all_sections.items():
|
@@ -159,12 +142,12 @@ async def analyze_medical_records(extracted_text: str) -> str:
|
|
159 |
"No significant oversights identified. Continue monitoring."
|
160 |
response.append(summary)
|
161 |
|
162 |
-
|
163 |
|
164 |
-
|
165 |
"""Create Gradio UI for clinical oversight analysis."""
|
166 |
-
|
167 |
-
"""Handle analysis and
|
168 |
history.append({"role": "user", "content": message})
|
169 |
history.append({"role": "assistant", "content": "⏳ Analyzing..."})
|
170 |
yield history, None
|
@@ -172,24 +155,21 @@ async def create_ui():
|
|
172 |
extracted_text = ""
|
173 |
file_hash_value = ""
|
174 |
if files:
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
|
|
179 |
|
180 |
history.pop() # Remove "Analyzing..."
|
181 |
report_path = os.path.join(report_dir, f"{file_hash_value}_report.txt") if file_hash_value else None
|
182 |
-
full_response = []
|
183 |
|
184 |
try:
|
185 |
-
|
186 |
-
|
187 |
-
history.append({"role": "assistant", "content": partial_response})
|
188 |
-
yield history, None
|
189 |
-
|
190 |
if report_path:
|
191 |
with open(report_path, "w", encoding="utf-8") as f:
|
192 |
-
f.write(
|
193 |
yield history, report_path if report_path and os.path.exists(report_path) else None
|
194 |
except Exception as e:
|
195 |
history.append({"role": "assistant", "content": f"❌ Error: {str(e)}"})
|
@@ -210,8 +190,8 @@ async def create_ui():
|
|
210 |
if __name__ == "__main__":
|
211 |
print("🚀 Launching app...")
|
212 |
try:
|
213 |
-
demo =
|
214 |
-
demo.
|
215 |
server_name="0.0.0.0",
|
216 |
server_port=7860,
|
217 |
show_error=True,
|
|
|
4 |
import re
|
5 |
import gradio as gr
|
6 |
from typing import List, Dict
|
7 |
+
from concurrent.futures import ThreadPoolExecutor
|
8 |
import hashlib
|
|
|
9 |
|
10 |
# Persistent directories
|
11 |
persistent_dir = "/data/hf_cache"
|
|
|
36 |
except Exception:
|
37 |
return ""
|
38 |
|
39 |
+
def convert_file_to_text(file_path: str, file_type: str) -> str:
|
40 |
"""Convert supported file types to text, caching results."""
|
41 |
try:
|
42 |
h = file_hash(file_path)
|
|
|
87 |
|
88 |
return sections
|
89 |
|
90 |
+
def analyze_medical_records(extracted_text: str) -> str:
|
91 |
+
"""Analyze medical records and return structured response."""
|
92 |
# Split text into chunks to handle large inputs
|
93 |
chunk_size = 10000
|
94 |
chunks = [extracted_text[i:i + chunk_size] for i in range(0, len(extracted_text), chunk_size)]
|
95 |
|
96 |
# Placeholder for analysis (replace with model or rule-based logic)
|
|
|
97 |
raw_response_template = """
|
98 |
Missed Diagnoses:
|
99 |
- Undiagnosed hypertension despite elevated BP readings.
|
|
|
119 |
|
120 |
for chunk_idx, chunk in enumerate(chunks, 1):
|
121 |
# Simulate analysis per chunk (replace with real logic)
|
122 |
+
raw_response = raw_response_template
|
|
|
|
|
123 |
parsed = parse_analysis_response(raw_response)
|
124 |
for section, items in parsed.items():
|
125 |
all_sections[section].update(items)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
|
127 |
+
# Format final response
|
128 |
response = ["### Clinical Oversight Analysis\n"]
|
129 |
has_findings = False
|
130 |
for section, items in all_sections.items():
|
|
|
142 |
"No significant oversights identified. Continue monitoring."
|
143 |
response.append(summary)
|
144 |
|
145 |
+
return "\n".join(response)
|
146 |
|
147 |
+
def create_ui():
|
148 |
"""Create Gradio UI for clinical oversight analysis."""
|
149 |
+
def analyze(message: str, history: List[dict], files: List):
|
150 |
+
"""Handle analysis and return results."""
|
151 |
history.append({"role": "user", "content": message})
|
152 |
history.append({"role": "assistant", "content": "⏳ Analyzing..."})
|
153 |
yield history, None
|
|
|
155 |
extracted_text = ""
|
156 |
file_hash_value = ""
|
157 |
if files:
|
158 |
+
with ThreadPoolExecutor(max_workers=4) as executor:
|
159 |
+
futures = [executor.submit(convert_file_to_text, f.name, f.name.split(".")[-1].lower()) for f in files]
|
160 |
+
results = [f.result() for f in futures]
|
161 |
+
extracted_text = "\n".join(sanitize_utf8(r) for r in results if r)
|
162 |
+
file_hash_value = file_hash(files[0].name) if files else ""
|
163 |
|
164 |
history.pop() # Remove "Analyzing..."
|
165 |
report_path = os.path.join(report_dir, f"{file_hash_value}_report.txt") if file_hash_value else None
|
|
|
166 |
|
167 |
try:
|
168 |
+
response = analyze_medical_records(extracted_text)
|
169 |
+
history.append({"role": "assistant", "content": response})
|
|
|
|
|
|
|
170 |
if report_path:
|
171 |
with open(report_path, "w", encoding="utf-8") as f:
|
172 |
+
f.write(response)
|
173 |
yield history, report_path if report_path and os.path.exists(report_path) else None
|
174 |
except Exception as e:
|
175 |
history.append({"role": "assistant", "content": f"❌ Error: {str(e)}"})
|
|
|
190 |
if __name__ == "__main__":
|
191 |
print("🚀 Launching app...")
|
192 |
try:
|
193 |
+
demo = create_ui()
|
194 |
+
demo.launch(
|
195 |
server_name="0.0.0.0",
|
196 |
server_port=7860,
|
197 |
show_error=True,
|