vikramvasudevan commited on
Commit
7348db6
·
verified ·
1 Parent(s): 93bdf8b

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. pdf_helper.py +70 -11
  2. test_pdf_generation.py +51 -0
pdf_helper.py CHANGED
@@ -121,16 +121,24 @@ from weasyprint import HTML, CSS
121
  import base64
122
 
123
  def generate_pdf(pdf_path: str, interpretation_html: str, plot_files: list):
 
 
 
 
 
124
  if interpretation_html.startswith("```"):
125
  interpretation_html = interpretation_html.strip("`").replace("html", "", 1).strip()
126
 
127
- # Convert plots to base64-embedded images
 
 
 
 
128
  plots_html = "<div style='display:flex; flex-wrap:wrap; gap:20px; margin-top:0;'>"
129
  for test_name, filepath in plot_files:
130
  with open(filepath, "rb") as f:
131
  img_base64 = base64.b64encode(f.read()).decode("utf-8")
132
- plot_html = f"<img src='data:image/png;base64,{img_base64}' style='width:100%; height:auto;'>"
133
- # Each plot occupies ~48% so exactly 2 fit per row
134
  plots_html += f"<div style='flex:0 0 48%; margin-bottom:20px; text-align:center;'>{plot_html}</div>"
135
  plots_html += "</div>"
136
 
@@ -146,21 +154,72 @@ def generate_pdf(pdf_path: str, interpretation_html: str, plot_files: list):
146
  <html>
147
  <head>
148
  <style>
149
- body {{ font-family: sans-serif; }}
150
- h1 {{ text-align: center; }}
151
- h2 {{ color: #2c3e50; margin-top: 30px; }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  table {{ border-collapse: collapse; width: 100%; margin: 10px 0; }}
153
  th, td {{ border: 1px solid #aaa; padding: 6px; text-align: left; }}
154
  th {{ background: #eee; }}
 
155
  .disclaimer {{ font-size: 10px; color: red; margin-top: 20px; text-align: center; }}
156
  </style>
157
  </head>
158
  <body>
159
- {interpretation_html}
160
- <h2>Trends</h2>
161
- {plots_html}
162
- <p class="disclaimer">{DISCLAIMER_TEXT}</p>
 
 
 
 
 
 
 
 
 
163
  </body>
164
  </html>
165
  """
166
- HTML(string=full_html).write_pdf(pdf_path)
 
 
121
  import base64
122
 
123
  def generate_pdf(pdf_path: str, interpretation_html: str, plot_files: list):
124
+ import base64
125
+ from weasyprint import HTML
126
+
127
+ logo_path = SheamiConfig.logo_path
128
+
129
  if interpretation_html.startswith("```"):
130
  interpretation_html = interpretation_html.strip("`").replace("html", "", 1).strip()
131
 
132
+ # Base64 logo
133
+ with open(logo_path, "rb") as f:
134
+ logo_base64 = base64.b64encode(f.read()).decode("utf-8")
135
+
136
+ # Base64 plots
137
  plots_html = "<div style='display:flex; flex-wrap:wrap; gap:20px; margin-top:0;'>"
138
  for test_name, filepath in plot_files:
139
  with open(filepath, "rb") as f:
140
  img_base64 = base64.b64encode(f.read()).decode("utf-8")
141
+ plot_html = f"<img src='data:image/png;base64,{img_base64}' style='width:100%; height:auto; display:block;'>"
 
142
  plots_html += f"<div style='flex:0 0 48%; margin-bottom:20px; text-align:center;'>{plot_html}</div>"
143
  plots_html += "</div>"
144
 
 
154
  <html>
155
  <head>
156
  <style>
157
+ @page {{
158
+ size: A4;
159
+ margin: 2cm;
160
+ @top-center {{
161
+ content: element(header);
162
+ }}
163
+ @bottom-center {{
164
+ content: "Page " counter(page) " of " counter(pages);
165
+ font-size: 10px;
166
+ color: #555;
167
+ }}
168
+ }}
169
+
170
+ body {{
171
+ font-family: sans-serif;
172
+ margin: 0;
173
+ }}
174
+
175
+ header {{
176
+ position: running(header);
177
+ display: block;
178
+ text-align: center;
179
+ width: 100%;
180
+ height: 100px; /* explicit height ensures image renders */
181
+ line-height: 100px; /* vertical centering */
182
+ overflow: hidden;
183
+ }}
184
+
185
+ header img {{
186
+ max-height: 100%;
187
+ max-width: 100%;
188
+ display: block;
189
+ margin: 0 auto;
190
+ }}
191
+
192
+ .content {{
193
+ margin-top: 120px; /* space for header */
194
+ margin-bottom: 60px; /* space for footer */
195
+ }}
196
+
197
+ h1 {{ text-align: center; margin-bottom:10px; }}
198
+ h2 {{ color:#2c3e50; margin-top:10px; }}
199
+
200
  table {{ border-collapse: collapse; width: 100%; margin: 10px 0; }}
201
  th, td {{ border: 1px solid #aaa; padding: 6px; text-align: left; }}
202
  th {{ background: #eee; }}
203
+
204
  .disclaimer {{ font-size: 10px; color: red; margin-top: 20px; text-align: center; }}
205
  </style>
206
  </head>
207
  <body>
208
+ <header>
209
+ <img src='data:image/png;base64,{logo_base64}' alt="Sheami Logo">
210
+ </header>
211
+
212
+ <div class="content">
213
+ {interpretation_html}
214
+
215
+ <h2>Trends</h2>
216
+ {plots_html}
217
+
218
+ <p class="disclaimer">{DISCLAIMER_TEXT}</p>
219
+ </div>
220
+
221
  </body>
222
  </html>
223
  """
224
+
225
+ HTML(string=full_html, base_url=".").write_pdf(pdf_path)
test_pdf_generation.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import tempfile
3
+ import matplotlib.pyplot as plt
4
+ import base64
5
+ from weasyprint import HTML
6
+
7
+ from config import SheamiConfig
8
+ from pdf_helper import generate_pdf
9
+
10
+ def test_generate_pdf():
11
+ from pathlib import Path
12
+
13
+ # Temporary directory for plots
14
+ tmp_dir = tempfile.mkdtemp()
15
+
16
+ # 1. Fake interpretation HTML
17
+ interpretation_html = """
18
+ <h1>Test Patient: John Doe</h1>
19
+ <p>Age: 45, Sex: Male</p>
20
+ <p>Clinical Summary:</p>
21
+ <ul>
22
+ <li>All vitals normal ✅</li>
23
+ <li>Minor deviation in cholesterol ▲</li>
24
+ <li>Vitamin D slightly low ▼</li>
25
+ </ul>
26
+ """
27
+
28
+ # 2. Generate 4 fake plots
29
+ plot_files = []
30
+ for i in range(4):
31
+ plt.figure(figsize=(4,3))
32
+ plt.plot([1,2,3,4], [i*2+1, i*2+2, i*2+1, i*2+3], marker='o')
33
+ plt.title(f"Test Plot {i+1}")
34
+ plt.xlabel("X")
35
+ plt.ylabel("Y")
36
+ plot_path = os.path.join(tmp_dir, f"plot_{i+1}.png")
37
+ plt.savefig(plot_path)
38
+ plt.close()
39
+ plot_files.append((f"Test {i+1}", plot_path))
40
+
41
+ # 3. Use your SheamiConfig logo path, or fallback to a sample image
42
+ logo_path = SheamiConfig.logo_path if hasattr(SheamiConfig, 'logo_path') else plot_files[0][1]
43
+
44
+ # 4. Call the generate_pdf function
45
+ pdf_path = os.path.join(tmp_dir, "test_report.pdf")
46
+ generate_pdf(pdf_path=pdf_path, interpretation_html=interpretation_html, plot_files=plot_files)
47
+
48
+ print(f"Test PDF generated at: {pdf_path}")
49
+
50
+
51
+ test_generate_pdf()