Rammohan0504 commited on
Commit
f957621
·
verified ·
1 Parent(s): d1efcfd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +77 -108
app.py CHANGED
@@ -9,10 +9,7 @@ import base64
9
  import joblib
10
  from datetime import datetime
11
  import shutil
12
- from reportlab.lib.pagesizes import letter
13
- from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Image
14
- from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
15
- from reportlab.lib import colors
16
  import atexit
17
  import glob
18
 
@@ -130,112 +127,84 @@ def build_table(title, rows):
130
  # Function to save the health report to PDF
131
  def save_results_to_pdf(profile_image_base64, test_results, summary, patient_name, patient_age, patient_gender, patient_id, filename):
132
  try:
133
- doc = SimpleDocTemplate(filename, pagesize=letter)
134
- styles = getSampleStyleSheet()
135
- title_style = ParagraphStyle(
136
- name='Title',
137
- fontSize=16,
138
- leading=20,
139
- alignment=1,
140
- spaceAfter=20,
141
- textColor=colors.black,
142
- fontName='Helvetica-Bold'
143
- )
144
- header_style = ParagraphStyle(
145
- name='Header',
146
- fontSize=14,
147
- leading=16,
148
- textColor=colors.darkblue,
149
- fontName='Helvetica-Bold'
150
- )
151
- body_style = ParagraphStyle(
152
- name='Body',
153
- fontSize=12,
154
- leading=14,
155
- spaceAfter=10,
156
- textColor=colors.black,
157
- fontName='Helvetica'
158
- )
159
-
160
- flowables = []
161
-
162
- # Header with Profile Image and Patient Details
163
  current_date = datetime.now().strftime("%B %d, %Y")
164
- header_table_data = [
165
- [Paragraph("HEALTH CARD", header_style), "", Paragraph(f"Report Date: {current_date}<br/>{f'Patient ID: {patient_id}' if patient_id else ''}", body_style)]
166
- ]
167
- header_table = Table(header_table_data, colWidths=[100, 300, 150])
168
- header_table.setStyle(TableStyle([
169
- ('BACKGROUND', (0, 0), (0, 0), colors.lightblue),
170
- ('BACKGROUND', (2, 0), (2, 0), colors.lightgrey),
171
- ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
172
- ('ALIGN', (0, 0), (0, 0), 'LEFT'),
173
- ('ALIGN', (2, 0), (2, 0), 'RIGHT'),
174
- ]))
175
- flowables.append(header_table)
176
-
177
- # Profile Image and Patient Info
178
- if profile_image_base64:
179
- import io
180
- from reportlab.lib.utils import ImageReader
181
- img_data = base64.b64decode(profile_image_base64)
182
- img_file = io.BytesIO(img_data)
183
- img = ImageReader(img_file)
184
- img_width = 90
185
- img_height = 90
186
- img.drawHeight = img_height * 0.5
187
- img.drawWidth = img_width * 0.5
188
- patient_info = f"{patient_name if patient_name else 'Lab Test Results'}<br/>{f'Age: {patient_age} | Gender: {patient_gender}' if patient_age and patient_gender else 'AI-Generated Health Analysis'}<br/>Face-Based Health Analysis Report"
189
- profile_table_data = [[Image(img, width=img_width, height=img_height), Paragraph(patient_info, body_style)]]
190
- profile_table = Table(profile_table_data, colWidths=[100, 400])
191
- profile_table.setStyle(TableStyle([
192
- ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
193
- ('LEFTPADDING', (0, 0), (0, 0), 0),
194
- ('RIGHTPADDING', (1, 0), (1, 0), 10),
195
- ]))
196
- flowables.append(profile_table)
197
- flowables.append(Spacer(1, 20))
198
-
199
- # Test Results Sections
200
- section_tests = {
201
- "Hematology": [("Hemoglobin", (13.5, 17.5)), ("WBC Count", (4.0, 11.0)), ("Platelet Count", (150, 450))],
202
- "Iron Panel": [("Iron", (60, 170)), ("Ferritin", (30, 300)), ("TIBC", (250, 400))],
203
- "Liver & Kidney": [("Bilirubin", (0.3, 1.2)), ("Creatinine", (0.6, 1.2)), ("Urea", (7, 20))],
204
- "Electrolytes": [("Sodium", (135, 145)), ("Potassium", (3.5, 5.1))],
205
- "Vitals": [("SpO2", (95, 100)), ("Heart Rate", (60, 100)), ("Respiratory Rate", (12, 20)),
206
- ("Temperature", (97, 99)), ("BP Systolic", (90, 120)), ("BP Diastolic", (60, 80))]
207
- }
208
-
209
- for section_name, html in test_results.items():
210
- flowables.append(Paragraph(section_name, styles['Heading2']))
211
- table_data = [["Test", "Result", "Range", "Level"]]
212
- for label, ref_range in section_tests.get(section_name, []):
213
- value = float(test_results[section_name].split(f'{label}</td><td style="padding:10px 8px;text-align:center;color:#2c3e50;font-weight:600;">')[1].split('</td>')[0]) if label in test_results[section_name] else ref_range[0] + random.uniform(-1, 1)
214
- level, _, _ = get_risk_color(value, ref_range)
215
- table_data.append([label, f"{value:.2f}" if label not in ["WBC Count", "Platelet Count"] else f"{value:.0f}", f"{ref_range[0]} - {ref_range[1]}", f"{level}"])
216
- table = Table(table_data)
217
- table.setStyle(TableStyle([
218
- ('BACKGROUND', (0, 0), (-1, 0), colors.grey),
219
- ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
220
- ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
221
- ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
222
- ('FONTSIZE', (0, 0), (-1, 0), 12),
223
- ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
224
- ('BACKGROUND', (0, 1), (-1, -1), colors.beige),
225
- ('GRID', (0, 0), (-1, -1), 1, colors.black),
226
- ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
227
- ]))
228
- flowables.append(table)
229
- flowables.append(Spacer(1, 12))
230
-
231
- # Summary & Recommendations
232
- flowables.append(Paragraph("Summary & Recommendations", styles['Heading2']))
233
- flowables.append(Paragraph(summary.replace("<ul>", "").replace("</ul>", "").replace("<li>", "\u2022 ").replace("</li>", "<br/>"), body_style))
234
- flowables.append(Spacer(1, 20))
235
-
236
- doc.build(flowables)
237
  print(f"PDF generated successfully at: {filename}") # Debug log
238
- return f"PDF saved successfully as {filename}", filename
 
 
 
 
 
 
 
 
239
  except Exception as e:
240
  print(f"Error saving PDF: {str(e)}") # Debug log
241
  return f"Error saving PDF: {str(e)}", None
 
9
  import joblib
10
  from datetime import datetime
11
  import shutil
12
+ import pdfkit
 
 
 
13
  import atexit
14
  import glob
15
 
 
127
  # Function to save the health report to PDF
128
  def save_results_to_pdf(profile_image_base64, test_results, summary, patient_name, patient_age, patient_gender, patient_id, filename):
129
  try:
130
+ # Generate HTML content
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  current_date = datetime.now().strftime("%B %d, %Y")
132
+ health_card_html = f"""
133
+ <!DOCTYPE html>
134
+ <html>
135
+ <head>
136
+ <style>
137
+ body {{ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; max-width: 700px; margin: 20px auto; color: #1a1a1a; }}
138
+ #health-card {{ border-radius: 16px; background: linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%); border: 2px solid #ddd; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15); padding: 30px; }}
139
+ .header {{ background-color: rgba(255, 255, 255, 0.9); border-radius: 12px; padding: 20px; margin-bottom: 25px; border: 1px solid #e0e0e0; display: flex; align-items: center; }}
140
+ .header-title {{ background: linear-gradient(135deg, #64b5f6, #42a5f5); padding: 8px 16px; border-radius: 8px; margin-right: 20px; }}
141
+ .header-title h3 {{ margin: 0; color: white; font-size: 16px; font-weight: 600; }}
142
+ .header-date {{ margin-left: auto; text-align: right; color: #666; font-size: 12px; }}
143
+ .profile {{ display: flex; align-items: center; }}
144
+ .profile img {{ width: 90px; height: 90px; border-radius: 50%; margin-right: 20px; border: 3px solid #fff; box-shadow: 0 4px 12px rgba(0,0,0,0.1); }}
145
+ .results {{ background-color: rgba(255, 255, 255, 0.95); border-radius: 12px; padding: 25px; margin-bottom: 25px; border: 1px solid #e0e0e0; }}
146
+ .summary {{ background-color: rgba(255, 255, 255, 0.95); padding: 20px; border-radius: 12px; border: 1px solid #e0e0e0; margin-bottom: 25px; }}
147
+ .summary h4 {{ margin: 0 0 15px 0; color: #2c3e50; font-size: 18px; font-weight: 600; }}
148
+ .buttons {{ display: flex; gap: 15px; justify-content: center; flex-wrap: wrap; }}
149
+ button:disabled {{ padding: 12px 24px; background: #ccc; color: white; border: none; border-radius: 8px; cursor: not-allowed; font-weight: 600; font-size: 14px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); }}
150
+ button {{ padding: 12px 24px; background: linear-gradient(135deg, #2196f3, #1976d2); color: white; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; font-size: 14px; box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3); }}
151
+ @media print {{ .gradio-container {{ display: block; }} #health-card {{ display: block; }} }}
152
+ </style>
153
+ </head>
154
+ <body>
155
+ <div id="health-card">
156
+ <div class="header">
157
+ <div class="header-title"><h3>HEALTH CARD</h3></div>
158
+ <div class="header-date">
159
+ <div>Report Date: {current_date}</div>
160
+ {f'<div>Patient ID: {patient_id}</div>' if patient_id else ''}
161
+ </div>
162
+ </div>
163
+ <div class="profile">
164
+ <img src="data:image/png;base64,{profile_image_base64}" alt="Profile">
165
+ <div>
166
+ <h2>{patient_name if patient_name else 'Lab Test Results'}</h2>
167
+ <p>{f'Age: {patient_age} | Gender: {patient_gender}' if patient_age and patient_gender else 'AI-Generated Health Analysis'}</p>
168
+ <p>Face-Based Health Analysis Report</p>
169
+ </div>
170
+ </div>
171
+ <div class="results">
172
+ {test_results['Hematology']}
173
+ {test_results['Iron Panel']}
174
+ {test_results['Liver & Kidney']}
175
+ {test_results['Electrolytes']}
176
+ {test_results['Vitals']}
177
+ </div>
178
+ <div class="summary">
179
+ <h4>📝 Summary & Recommendations</h4>
180
+ <div>{summary}</div>
181
+ </div>
182
+ <div class="buttons">
183
+ <button disabled>📥 Download Report</button>
184
+ <button>📞 Find Labs Near Me</button>
185
+ </div>
186
+ </div>
187
+ </body>
188
+ </html>
189
+ """
190
+
191
+ # Save HTML to a temporary file
192
+ html_temp_path = "/tmp/health_card.html"
193
+ with open(html_temp_path, "w", encoding="utf-8") as f:
194
+ f.write(health_card_html)
195
+
196
+ # Convert HTML to PDF using pdfkit
197
+ pdfkit.from_file(html_temp_path, filename, options={"quiet": ""})
 
 
 
 
 
 
 
198
  print(f"PDF generated successfully at: {filename}") # Debug log
199
+
200
+ # Move to /tmp for Gradio access
201
+ temp_pdf_path = "/tmp/" + os.path.basename(filename)
202
+ shutil.copy(filename, temp_pdf_path)
203
+
204
+ if os.path.exists(temp_pdf_path) and os.access(temp_pdf_path, os.R_OK):
205
+ return f"PDF saved successfully as {filename}", temp_pdf_path
206
+ else:
207
+ return "Error: PDF file not accessible.", None
208
  except Exception as e:
209
  print(f"Error saving PDF: {str(e)}") # Debug log
210
  return f"Error saving PDF: {str(e)}", None