|
32 | 32 |
|
33 | 33 | from src.constants import Artifacts as A
|
34 | 34 | from src.constants import Directories
|
| 35 | +from src.utils.visualizations.shared_styles import get_html_template |
35 | 36 |
|
36 | 37 | logger = get_logger(__name__)
|
37 | 38 |
|
@@ -131,79 +132,70 @@ def get_direct_dependencies():
|
131 | 132 |
|
132 | 133 |
|
133 | 134 | def generate_sbom_html(sbom_data: Dict[str, Any], timestamp: str) -> str:
|
134 |
| - """Generate HTML representation of SBOM data.""" |
| 135 | + """Generate HTML representation of SBOM data using shared CSS.""" |
135 | 136 | components = sbom_data.get("components", [])
|
136 | 137 | metadata = sbom_data.get("metadata", {})
|
137 | 138 |
|
138 |
| - html = f""" |
139 |
| - <!DOCTYPE html> |
140 |
| - <html> |
141 |
| - <head> |
142 |
| - <title>Software Bill of Materials (SBOM)</title> |
143 |
| - <style> |
144 |
| - body {{ font-family: Arial, sans-serif; margin: 20px; }} |
145 |
| - .header {{ background-color: #f5f5f5; padding: 20px; border-radius: 5px; margin-bottom: 20px; }} |
146 |
| - .metadata {{ background-color: #e8f4fd; padding: 15px; border-radius: 5px; margin-bottom: 20px; }} |
147 |
| - table {{ border-collapse: collapse; width: 100%; }} |
148 |
| - th, td {{ border: 1px solid #ddd; padding: 8px; text-align: left; }} |
149 |
| - th {{ background-color: #f2f2f2; font-weight: bold; }} |
150 |
| - .checksum {{ font-family: monospace; word-break: break-all; }} |
151 |
| - .purl {{ font-family: monospace; font-size: 0.9em; color: #666; }} |
152 |
| - </style> |
153 |
| - </head> |
154 |
| - <body> |
155 |
| - <div class="header"> |
156 |
| - <h1>Software Bill of Materials (SBOM)</h1> |
157 |
| - <p><strong>Format:</strong> {sbom_data.get('bomFormat', 'CycloneDX')}</p> |
158 |
| - <p><strong>Spec Version:</strong> {sbom_data.get('specVersion', 'N/A')}</p> |
159 |
| - <p><strong>Serial Number:</strong> <span class="checksum">{sbom_data.get('serialNumber', 'N/A')}</span></p> |
160 |
| - <p><strong>Generated:</strong> {timestamp}</p> |
161 |
| - </div> |
162 |
| - |
163 |
| - <div class="metadata"> |
164 |
| - <h2>Metadata</h2> |
165 |
| - <p><strong>Timestamp:</strong> {metadata.get('timestamp', 'N/A')}</p> |
166 |
| - <p><strong>Total Components:</strong> {len(components)}</p> |
167 |
| - </div> |
168 |
| - |
169 |
| - <h2>Components ({len(components)} total)</h2> |
170 |
| - <table> |
171 |
| - <thead> |
172 |
| - <tr> |
173 |
| - <th>Name</th> |
174 |
| - <th>Version</th> |
175 |
| - <th>Type</th> |
176 |
| - <th>Package URL</th> |
177 |
| - </tr> |
178 |
| - </thead> |
179 |
| - <tbody> |
180 |
| - """ |
181 |
| - |
| 139 | + # Build component table rows |
| 140 | + component_rows = "" |
182 | 141 | for component in sorted(components, key=lambda x: x.get("name", "")):
|
183 | 142 | name = component.get("name", "Unknown")
|
184 | 143 | version = component.get("version", "Unknown")
|
185 | 144 | comp_type = component.get("type", "Unknown")
|
186 | 145 | purl = component.get("purl", "")
|
187 | 146 |
|
188 |
| - html += f""" |
| 147 | + component_rows += f""" |
189 | 148 | <tr>
|
190 | 149 | <td><strong>{name}</strong></td>
|
191 | 150 | <td>{version}</td>
|
192 | 151 | <td>{comp_type}</td>
|
193 |
| - <td class="purl">{purl}</td> |
194 |
| - </tr> |
195 |
| - """ |
| 152 | + <td class="monospace purl">{purl}</td> |
| 153 | + </tr>""" |
196 | 154 |
|
197 |
| - html += """ |
198 |
| - </tbody> |
199 |
| - </table> |
| 155 | + # Generate main content using shared CSS classes |
| 156 | + content = f""" |
| 157 | + <div class="header"> |
| 158 | + <h1>Software Bill of Materials (SBOM)</h1> |
| 159 | + <p>EU AI Act Article 15 Compliance - Accuracy & Robustness</p> |
| 160 | + </div> |
200 | 161 |
|
201 |
| - <div style="margin-top: 30px; padding: 15px; background-color: #f9f9f9; border-radius: 5px;"> |
202 |
| - <h3>About this SBOM</h3> |
203 |
| - <p>This Software Bill of Materials (SBOM) was automatically generated as part of EU AI Act compliance requirements (Article 15 - Accuracy & Robustness). It provides a comprehensive inventory of all software components used in the credit scoring model deployment.</p> |
| 162 | + <div class="content"> |
| 163 | + <div class="card sbom-header"> |
| 164 | + <h2>SBOM Information</h2> |
| 165 | + <p><strong>Format:</strong> {sbom_data.get('bomFormat', 'CycloneDX')}</p> |
| 166 | + <p><strong>Spec Version:</strong> {sbom_data.get('specVersion', 'N/A')}</p> |
| 167 | + <p><strong>Serial Number:</strong> <span class="monospace checksum">{sbom_data.get('serialNumber', 'N/A')}</span></p> |
| 168 | + <p><strong>Generated:</strong> {timestamp}</p> |
| 169 | + </div> |
| 170 | + |
| 171 | + <div class="card sbom-metadata"> |
| 172 | + <h2>Metadata</h2> |
| 173 | + <p><strong>Timestamp:</strong> {metadata.get('timestamp', 'N/A')}</p> |
| 174 | + <p><strong>Total Components:</strong> {len(components)}</p> |
| 175 | + </div> |
| 176 | + |
| 177 | + <div class="card"> |
| 178 | + <h2>Components ({len(components)} total)</h2> |
| 179 | + <table class="table"> |
| 180 | + <thead> |
| 181 | + <tr> |
| 182 | + <th>Name</th> |
| 183 | + <th>Version</th> |
| 184 | + <th>Type</th> |
| 185 | + <th>Package URL</th> |
| 186 | + </tr> |
| 187 | + </thead> |
| 188 | + <tbody> |
| 189 | + {component_rows} |
| 190 | + </tbody> |
| 191 | + </table> |
| 192 | + </div> |
| 193 | + |
| 194 | + <div class="alert alert-info mt-4"> |
| 195 | + <h3>About this SBOM</h3> |
| 196 | + <p>This Software Bill of Materials (SBOM) was automatically generated as part of EU AI Act compliance requirements (Article 15 - Accuracy & Robustness). It provides a comprehensive inventory of all software components used in the credit scoring model deployment.</p> |
| 197 | + </div> |
204 | 198 | </div>
|
205 |
| - </body> |
206 |
| - </html> |
207 | 199 | """
|
208 | 200 |
|
209 |
| - return html |
| 201 | + return get_html_template("Software Bill of Materials (SBOM)", content) |
0 commit comments