rajsecrets0 commited on
Commit
b9022c3
·
verified ·
1 Parent(s): 88cf3bf

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +187 -0
app.py ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import base64
3
+ import requests
4
+ from PIL import Image
5
+ from io import BytesIO
6
+ from pdf2image import convert_from_bytes
7
+
8
+ # Configuration - Replace with your API key
9
+ GEMINI_API_KEY = st.secrets["GEMINI_API_KEY"]
10
+ GEMINI_MODEL = "gemini-2.0-flash"
11
+
12
+ DOCUMENT_TYPES = [
13
+ "Insurance Policies", "Explanation of Benefits (EOBs)",
14
+ "Claims (Approved, Denied, or Pending)", "Visit Summaries",
15
+ "Test Results (Lab Reports, Imaging Reports)",
16
+ "Prescriptions (E-Prescriptions, Handwritten)",
17
+ "Discharge Summaries", "Medical Bills", "Payment Statements",
18
+ "Pharmacy Receipts", "Prior Authorization Requests",
19
+ "Consent Forms", "Referral Letters", "Others"
20
+ ]
21
+
22
+ def initialize_session_state():
23
+ """Initialize all session state variables"""
24
+ if "chat_history" not in st.session_state:
25
+ st.session_state.chat_history = []
26
+ if "processed_doc" not in st.session_state:
27
+ st.session_state.processed_doc = None
28
+ if "doc_preview" not in st.session_state:
29
+ st.session_state.doc_preview = None
30
+
31
+ def encode_file(uploaded_file):
32
+ """Safely encode different file types to base64"""
33
+ try:
34
+ file_bytes = uploaded_file.getvalue()
35
+
36
+ if uploaded_file.type == "application/pdf":
37
+ images = convert_from_bytes(file_bytes, first_page=1, last_page=1)
38
+ if not images:
39
+ raise ValueError("Failed to convert PDF to image")
40
+ img_byte_arr = BytesIO()
41
+ images[0].save(img_byte_arr, format='JPEG')
42
+ return base64.b64encode(img_byte_arr.getvalue()).decode('utf-8')
43
+
44
+ return base64.b64encode(file_bytes).decode('utf-8')
45
+ except Exception as e:
46
+ st.error(f"File processing error: {str(e)}")
47
+ return None
48
+
49
+ def query_gemini(prompt, image_b64=None):
50
+ """Handle Gemini API communication"""
51
+ url = f"https://generativelanguage.googleapis.com/v1/models/{GEMINI_MODEL}:generateContent?key={GEMINI_API_KEY}"
52
+
53
+ parts = [{"text": prompt}]
54
+ if image_b64:
55
+ parts.append({
56
+ "inline_data": {
57
+ "mime_type": "image/jpeg",
58
+ "data": image_b64
59
+ }
60
+ })
61
+
62
+ try:
63
+ response = requests.post(
64
+ url,
65
+ json={"contents": [{"parts": parts}]},
66
+ headers={"Content-Type": "application/json"},
67
+ timeout=30
68
+ )
69
+ response.raise_for_status()
70
+ return response.json()["candidates"][0]["content"]["parts"][0]["text"]
71
+ except Exception as e:
72
+ st.error(f"API Error: {str(e)}")
73
+ return None
74
+
75
+ def process_document():
76
+ """Handle document processing pipeline"""
77
+ uploaded_file = st.session_state.uploaded_file
78
+ if not uploaded_file:
79
+ return
80
+
81
+ try:
82
+ with st.spinner("Analyzing document..."):
83
+ # Convert to base64
84
+ image_b64 = encode_file(uploaded_file)
85
+ if not image_b64:
86
+ return
87
+
88
+ # Generate preview
89
+ if uploaded_file.type == "application/pdf":
90
+ images = convert_from_bytes(uploaded_file.getvalue(), first_page=1, last_page=1)
91
+ st.session_state.doc_preview = images[0]
92
+ else:
93
+ st.session_state.doc_preview = Image.open(uploaded_file)
94
+
95
+ # Classify document
96
+ classify_prompt = f"Classify this healthcare document into one of: {DOCUMENT_TYPES}. Respond only with the category name."
97
+ doc_type = query_gemini(classify_prompt, image_b64) or "Others"
98
+
99
+ # Store results
100
+ st.session_state.processed_doc = {
101
+ "type": doc_type,
102
+ "content": image_b64,
103
+ "summary": query_gemini("Create a detailed structured summary of this healthcare document.", image_b64)
104
+ }
105
+
106
+ except Exception as e:
107
+ st.error(f"Processing failed: {str(e)}")
108
+ st.session_state.processed_doc = None
109
+
110
+ def handle_chat_query():
111
+ """Process user chat input"""
112
+ user_input = st.session_state.chat_input
113
+ if not user_input or not st.session_state.processed_doc:
114
+ return
115
+
116
+ prompt = f"""
117
+ Document Context:
118
+ - Type: {st.session_state.processed_doc['type']}
119
+ - Summary: {st.session_state.processed_doc['summary']}
120
+
121
+ Question: {user_input}
122
+
123
+ Answer concisely and factually. If unsure, state "Information not found".
124
+ """
125
+
126
+ with st.spinner("Generating response..."):
127
+ response = query_gemini(prompt, st.session_state.processed_doc['content'])
128
+
129
+ st.session_state.chat_history.append(("user", user_input))
130
+ st.session_state.chat_history.append(("assistant", response or "Could not generate response"))
131
+
132
+ # UI Layout
133
+ def main():
134
+ st.set_page_config(page_title="Healthcare Document Assistant", layout="wide")
135
+ initialize_session_state()
136
+
137
+ # Sidebar Section
138
+ with st.sidebar:
139
+ st.header("Document Management")
140
+
141
+ # Preview above upload button
142
+ if st.session_state.doc_preview:
143
+ st.subheader("Preview")
144
+ st.image(st.session_state.doc_preview, use_container_width=True)
145
+
146
+ # Upload button
147
+ st.file_uploader(
148
+ "Upload Document",
149
+ type=["pdf", "png", "jpg", "jpeg"],
150
+ key="uploaded_file",
151
+ on_change=process_document
152
+ )
153
+
154
+ # Document type below upload button
155
+ if st.session_state.processed_doc:
156
+ st.divider()
157
+ st.subheader("Document Type")
158
+ st.markdown(f"**{st.session_state.processed_doc['type']}**")
159
+
160
+ # Main Content
161
+ st.title("Healthcare Document Assistant")
162
+
163
+ if st.session_state.processed_doc:
164
+ # Document Summary
165
+ st.subheader("Document Summary")
166
+ st.markdown(st.session_state.processed_doc['summary'])
167
+
168
+ # Chat Interface
169
+ st.divider()
170
+ st.subheader("Document Q&A")
171
+
172
+ # Chat history
173
+ for role, message in st.session_state.chat_history:
174
+ with st.chat_message(role.capitalize()):
175
+ st.markdown(message)
176
+
177
+ # Chat input
178
+ st.chat_input(
179
+ "Ask about the document...",
180
+ key="chat_input",
181
+ on_submit=handle_chat_query
182
+ )
183
+ else:
184
+ st.info("Please upload a document to begin analysis")
185
+
186
+ if __name__ == "__main__":
187
+ main()