Skip to content

fix: Clean up temporary PDF file after FileResponse using BackgroundTask#18

Open
Devguru-codes wants to merge 1 commit intoOSIPI:mainfrom
Devguru-codes:Temporary_PDF
Open

fix: Clean up temporary PDF file after FileResponse using BackgroundTask#18
Devguru-codes wants to merge 1 commit intoOSIPI:mainfrom
Devguru-codes:Temporary_PDF

Conversation

@Devguru-codes
Copy link

@Devguru-codes Devguru-codes commented Feb 27, 2026

The download_pdf endpoint creates a temp PDF with delete=False but never cleans it up. Each request leaks a temp file. This fix attaches a BackgroundTask to the FileResponse that calls os.unlink(tmp_path) after the response is fully sent.

Fix

  • Added from starlette.background import BackgroundTask import
  • Attached background=BackgroundTask(os.unlink, tmp_path) to the FileResponse

File Changed

apps/backend/app/routers/reports.py

+from starlette.background import BackgroundTask

     with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp:
         HTML(string=html_content).write_pdf(tmp.name)
         tmp_path = tmp.name
-    return FileResponse(tmp_path, media_type="application/pdf", filename="report.pdf")
+    return FileResponse(
+        tmp_path,
+        media_type="application/pdf",
+        filename="report.pdf",
+        background=BackgroundTask(os.unlink, tmp_path)
+    )

Note: delete=False is intentionally kept because the file must persist until FileResponse finishes streaming it. The BackgroundTask runs after the response is fully sent.


API Endpoint Validation (POST /api/report/report-pdf)

Request

{
    "report_data": {
        "asl_parameters": [["Magnetic Field Strength", "3T"], ["Manufacturer", "Siemens"]],
        "basic_report": "Test report content",
        "extended_report": "Extended test report",
        "missing_parameters": ["EchoTime"]
    }
}

Response (after fix)

Status Code: 200
Content-Type: application/pdf
Content-Disposition: attachment; filename="report.pdf"
Content-Length: 37 bytes
Leftover temp PDFs: 0

API Endpoint Test Results

# Test Status Detail
1 POST /api/report/report-pdf returns 200 PASS
2 Response content-type is application/pdf PASS
3 Response body is non-empty PASS
4 Content-Disposition includes report.pdf PASS
5 No leftover temp PDF files after response PASS BackgroundTask cleaned up

API Summary: PASSED=5 FAILED=0


Before/After Comparison

main branch (before fix)

# Test Status Detail
1 Temp PDF created with delete=False FAIL File persists after response
2 Temp PDF is cleaned up after response FAIL No cleanup found
3 FileResponse uses BackgroundTask FAIL No BackgroundTask attached

Summary: PASSED=0 FAILED=3

Temporary_PDF branch (after fix)

# Test Status Detail
1 delete=False paired with BackgroundTask cleanup PASS File persists for streaming, then cleaned up
2 Temp PDF is cleaned up after response PASS os.unlink via BackgroundTask
3 FileResponse uses BackgroundTask PASS BackgroundTask attached

Summary: PASSED=3 FAILED=0
Resolves #17

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Temporary PDF file created with delete=False is never cleaned up

1 participant