MFF212 commited on
Commit
dc52e17
Β·
verified Β·
1 Parent(s): f700a31

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +332 -6
app.py CHANGED
@@ -1,8 +1,334 @@
1
- from fastapi import FastAPI
2
- from fastapi.responses import FileResponse
 
 
3
 
4
- app = FastAPI()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- @app.get("/audio")
7
- def get_audio():
8
- return FileResponse("sample.mp3", media_type="audio/mpeg")
 
1
+ """
2
+ Streamlit App: PDF & JSON Response Viewer
3
+ View PDFs from EDTReports with their corresponding JSON responses
4
+ """
5
 
6
+ import streamlit as st
7
+ import json
8
+ from pathlib import Path
9
+ import base64
10
+ import fitz # PyMuPDF
11
+ from PIL import Image
12
+ import io
13
+
14
+ # Configuration
15
+ PDF_DIR = "EDTReports"
16
+ JSON_DIR = "response"
17
+
18
+ # Page config
19
+ st.set_page_config(
20
+ page_title="PDF & JSON Viewer",
21
+ page_icon="πŸ“„",
22
+ layout="wide",
23
+ initial_sidebar_state="expanded"
24
+ )
25
+
26
+ # Custom CSS
27
+ st.markdown("""
28
+ <style>
29
+ .main-header {
30
+ font-size: 2.5rem;
31
+ font-weight: bold;
32
+ color: #1f77b4;
33
+ text-align: center;
34
+ margin-bottom: 2rem;
35
+ }
36
+ .pdf-container {
37
+ border: 2px solid #e0e0e0;
38
+ border-radius: 10px;
39
+ padding: 10px;
40
+ background-color: #f9f9f9;
41
+ }
42
+ .json-container {
43
+ background-color: #f5f5f5;
44
+ border-radius: 10px;
45
+ padding: 20px;
46
+ max-height: 800px;
47
+ overflow-y: auto;
48
+ }
49
+ .section-header {
50
+ background-color: #1f77b4;
51
+ color: white;
52
+ padding: 10px;
53
+ border-radius: 5px;
54
+ margin: 10px 0;
55
+ font-weight: bold;
56
+ }
57
+ .info-box {
58
+ background-color: #e3f2fd;
59
+ padding: 15px;
60
+ border-radius: 8px;
61
+ border-left: 4px solid #1f77b4;
62
+ margin: 10px 0;
63
+ }
64
+ .success-box {
65
+ background-color: #e8f5e9;
66
+ padding: 10px;
67
+ border-radius: 5px;
68
+ border-left: 4px solid #4caf50;
69
+ }
70
+ .warning-box {
71
+ background-color: #fff3e0;
72
+ padding: 10px;
73
+ border-radius: 5px;
74
+ border-left: 4px solid #ff9800;
75
+ }
76
+ </style>
77
+ """, unsafe_allow_html=True)
78
+
79
+
80
+ def get_pdf_files():
81
+ """Get all PDF files from EDTReports directory"""
82
+ pdf_dir = Path(PDF_DIR)
83
+ if not pdf_dir.exists():
84
+ return []
85
+ return sorted(list(pdf_dir.glob("*.pdf")))
86
+
87
+
88
+ def get_json_for_pdf(pdf_filename):
89
+ """Get corresponding JSON file for a PDF"""
90
+ # Remove .pdf extension and add .json
91
+ json_filename = pdf_filename.replace('.pdf', '.json')
92
+ json_path = Path(JSON_DIR) / json_filename
93
+
94
+ if json_path.exists():
95
+ try:
96
+ with open(json_path, 'r', encoding='utf-8') as f:
97
+ return json.load(f)
98
+ except Exception as e:
99
+ return {"error": f"Failed to load JSON: {str(e)}"}
100
+ return None
101
+
102
+
103
+ def display_pdf(pdf_path, zoom_level=2.0):
104
+ """Display PDF by converting pages to images using PyMuPDF"""
105
+ try:
106
+ # Open PDF
107
+ pdf_document = fitz.open(pdf_path)
108
+
109
+ # Get total pages
110
+ total_pages = len(pdf_document)
111
+
112
+ # Page selector
113
+ if total_pages > 1:
114
+ page_num = st.slider("πŸ“– Select Page", 1, total_pages, 1) - 1
115
+ else:
116
+ page_num = 0
117
+
118
+ # Render page
119
+ page = pdf_document[page_num]
120
+
121
+ # Convert to image with adjustable resolution
122
+ mat = fitz.Matrix(zoom_level, zoom_level)
123
+ pix = page.get_pixmap(matrix=mat)
124
+
125
+ # Convert to PIL Image
126
+ img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
127
+
128
+ # Display image
129
+ st.image(img, use_column_width=True)
130
+
131
+ # Show page info
132
+ if total_pages > 1:
133
+ st.caption(f"Page {page_num + 1} of {total_pages}")
134
+
135
+ pdf_document.close()
136
+
137
+ except Exception as e:
138
+ st.error(f"Error displaying PDF: {str(e)}")
139
+
140
+ # Fallback: Provide download link
141
+ st.warning("PDF could not be displayed. Click below to download:")
142
+ with open(pdf_path, "rb") as f:
143
+ st.download_button(
144
+ label="πŸ“₯ Download PDF",
145
+ data=f.read(),
146
+ file_name=pdf_path.name,
147
+ mime="application/pdf"
148
+ )
149
+
150
+
151
+ def display_json_section(title, data, level=0):
152
+ """Recursively display JSON data in a structured format"""
153
+ indent = " " * level
154
+
155
+ if isinstance(data, dict):
156
+ if level == 0:
157
+ st.markdown(f'<div class="section-header">{title}</div>', unsafe_allow_html=True)
158
+ else:
159
+ st.markdown(f"**{title}**")
160
+
161
+ for key, value in data.items():
162
+ if isinstance(value, dict):
163
+ display_json_section(key, value, level + 1)
164
+ elif isinstance(value, list):
165
+ st.markdown(f"{indent}**{key}:**")
166
+ for item in value:
167
+ if isinstance(item, dict):
168
+ display_json_section("", item, level + 1)
169
+ else:
170
+ st.markdown(f"{indent} β€’ {item}")
171
+ else:
172
+ st.markdown(f"{indent}**{key}:** {value}")
173
+ elif isinstance(data, list):
174
+ for item in data:
175
+ if isinstance(item, dict):
176
+ display_json_section("", item, level)
177
+ else:
178
+ st.markdown(f"{indent}β€’ {item}")
179
+ else:
180
+ st.markdown(f"{indent}{data}")
181
+
182
+
183
+ def main():
184
+ # Header
185
+ st.markdown('<div class="main-header">πŸ“„ PDF & JSON Response Viewer</div>', unsafe_allow_html=True)
186
+
187
+ # Get all PDF files
188
+ pdf_files = get_pdf_files()
189
+
190
+ if not pdf_files:
191
+ st.error(f"No PDF files found in '{PDF_DIR}' directory")
192
+ return
193
+
194
+ # Sidebar
195
+ with st.sidebar:
196
+ st.markdown("### πŸ“ File Selection")
197
+
198
+ # Search box
199
+ search_term = st.text_input("πŸ” Search files:", "")
200
+
201
+ # Filter files
202
+ if search_term:
203
+ filtered_files = [f for f in pdf_files if search_term.lower() in f.name.lower()]
204
+ else:
205
+ filtered_files = pdf_files
206
+
207
+ st.markdown(f"**Found: {len(filtered_files)} files**")
208
+
209
+ # File selector
210
+ if filtered_files:
211
+ selected_file = st.selectbox(
212
+ "Select a PDF file:",
213
+ filtered_files,
214
+ format_func=lambda x: x.name
215
+ )
216
+ else:
217
+ st.warning("No files match your search")
218
+ return
219
+
220
+ st.markdown("---")
221
+
222
+ # Statistics
223
+ st.markdown("### πŸ“Š Statistics")
224
+ total_pdfs = len(pdf_files)
225
+ total_jsons = len(list(Path(JSON_DIR).glob("*.json"))) if Path(JSON_DIR).exists() else 0
226
+
227
+ st.metric("Total PDFs", total_pdfs)
228
+ st.metric("Total JSONs", total_jsons)
229
+
230
+ # Navigation buttons
231
+ st.markdown("---")
232
+ st.markdown("### πŸ”„ Quick Navigation")
233
+
234
+ col1, col2 = st.columns(2)
235
+ current_idx = filtered_files.index(selected_file)
236
+
237
+ with col1:
238
+ if st.button("⬅️ Previous"):
239
+ if current_idx > 0:
240
+ selected_file = filtered_files[current_idx - 1]
241
+ st.rerun()
242
+
243
+ with col2:
244
+ if st.button("Next ➑️"):
245
+ if current_idx < len(filtered_files) - 1:
246
+ selected_file = filtered_files[current_idx + 1]
247
+ st.rerun()
248
+
249
+ # Main content
250
+ if selected_file:
251
+ # File info
252
+ st.markdown(f'<div class="info-box">', unsafe_allow_html=True)
253
+ col1, col2 = st.columns([3, 1])
254
+ with col1:
255
+ st.markdown(f"**Selected File:** `{selected_file.name}`")
256
+ with col2:
257
+ file_size = selected_file.stat().st_size / 1024
258
+ st.markdown(f"**Size:** {file_size:.1f} KB")
259
+ st.markdown('</div>', unsafe_allow_html=True)
260
+
261
+ # Create two columns
262
+ col_pdf, col_json = st.columns([1, 1])
263
+
264
+ # PDF Column
265
+ with col_pdf:
266
+ st.markdown("### πŸ“„ PDF Document")
267
+
268
+ # Zoom control
269
+ zoom_level = st.select_slider(
270
+ "πŸ” Zoom Level",
271
+ options=[1.0, 1.5, 2.0, 2.5, 3.0],
272
+ value=2.0,
273
+ format_func=lambda x: f"{int(x*100)}%"
274
+ )
275
+
276
+ with st.container():
277
+ st.markdown('<div class="pdf-container">', unsafe_allow_html=True)
278
+ display_pdf(selected_file, zoom_level)
279
+ st.markdown('</div>', unsafe_allow_html=True)
280
+
281
+ # JSON Column
282
+ with col_json:
283
+ st.markdown("### πŸ“‹ JSON Response")
284
+
285
+ json_data = get_json_for_pdf(selected_file.name)
286
+
287
+ if json_data:
288
+ if "error" in json_data:
289
+ st.error(json_data["error"])
290
+ else:
291
+ with st.container():
292
+ st.markdown('<div class="json-container">', unsafe_allow_html=True)
293
+
294
+ # Status
295
+ if json_data.get("status") == "success":
296
+ st.markdown('<div class="success-box">βœ… Status: Success</div>', unsafe_allow_html=True)
297
+
298
+ # Display sections
299
+ if "data" in json_data:
300
+ data = json_data["data"]
301
+
302
+ # Section 1
303
+ if "SECTION 1" in data or "SECTION_1" in data:
304
+ section1 = data.get("SECTION 1") or data.get("SECTION_1")
305
+ display_json_section("SECTION 1: Subject Identification", section1)
306
+
307
+ # Section 2
308
+ if "SECTION 2" in data or "SECTION_2" in data:
309
+ section2 = data.get("SECTION 2") or data.get("SECTION_2")
310
+ display_json_section("SECTION 2: Findings & Interpretation", section2)
311
+
312
+ # Section 3
313
+ if "SECTION 3" in data or "SECTION_3" in data:
314
+ section3 = data.get("SECTION 3") or data.get("SECTION_3")
315
+ display_json_section("SECTION 3: Brief Medical Summary", section3)
316
+
317
+ # Section 4
318
+ if "SECTION 4" in data or "SECTION_4" in data:
319
+ section4 = data.get("SECTION 4") or data.get("SECTION_4")
320
+ display_json_section("SECTION 4: Life Insurance Underwriting View", section4)
321
+
322
+ # Raw JSON (collapsible)
323
+ with st.expander("πŸ“ View Raw JSON"):
324
+ st.json(json_data)
325
+
326
+ st.markdown('</div>', unsafe_allow_html=True)
327
+ else:
328
+ st.markdown('<div class="warning-box">⚠️ No JSON response found for this PDF</div>', unsafe_allow_html=True)
329
+ st.info(f"Expected file: `{JSON_DIR}/{selected_file.name.replace('.pdf', '.json')}`")
330
+
331
+
332
+ if __name__ == "__main__":
333
+ main()
334