Export scan results as CSV. Args: scan_id: Scan identifier Returns: CSV file download
(scan_id: str)
| 99 | |
| 100 | |
| 101 | @router.get("/scans/{scan_id}/export/csv") |
| 102 | async def export_scan_csv(scan_id: str): |
| 103 | """Export scan results as CSV. |
| 104 | |
| 105 | Args: |
| 106 | scan_id: Scan identifier |
| 107 | |
| 108 | Returns: |
| 109 | CSV file download |
| 110 | """ |
| 111 | import csv |
| 112 | import tempfile |
| 113 | |
| 114 | from api.routers.scans import scans_db |
| 115 | |
| 116 | if scan_id not in scans_db: |
| 117 | raise HTTPException(status_code=404, detail="Scan not found") |
| 118 | |
| 119 | scan = scans_db[scan_id] |
| 120 | |
| 121 | with tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False, newline='') as f: |
| 122 | writer = csv.DictWriter( |
| 123 | f, |
| 124 | fieldnames=['Title', 'Severity', 'Module', 'Description'], |
| 125 | ) |
| 126 | writer.writeheader() |
| 127 | |
| 128 | for finding in scan["findings"]: |
| 129 | writer.writerow({ |
| 130 | 'Title': finding['title'], |
| 131 | 'Severity': finding['severity'].value, |
| 132 | 'Module': finding['module'], |
| 133 | 'Description': finding['description'], |
| 134 | }) |
| 135 | |
| 136 | temp_path = f.name |
| 137 | |
| 138 | return FileResponse( |
| 139 | temp_path, |
| 140 | filename=f"scan_{scan_id}.csv", |
| 141 | media_type="text/csv", |
| 142 | ) |
| 143 |
nothing calls this directly
no outgoing calls
no test coverage detected