mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-07-17 10:08:46 +02:00
read_pdf_upload() bounds reads at 10 MB and requires the %PDF magic before anything reaches pdftotext (SEC-06); rejections land in the per-file errors list with the filename. Parsing now runs via asyncio.to_thread so a slow PDF no longer blocks the event loop for up to 30s (BE-14). Review notes: temp files were already context-managed (BE-09 overstated) and the pension batch already commits atomically (BE-10 overstated). 69 tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
23 lines
772 B
Python
23 lines
772 B
Python
from fastapi import UploadFile
|
|
|
|
MAX_UPLOAD_BYTES = 10 * 1024 * 1024 # 10 MB — statements are a few hundred KB
|
|
|
|
|
|
async def read_pdf_upload(
|
|
file: UploadFile, max_bytes: int = MAX_UPLOAD_BYTES
|
|
) -> bytes:
|
|
"""Read an uploaded PDF with a size cap and magic-byte check.
|
|
|
|
Raises ValueError with a user-readable, filename-prefixed message —
|
|
upload endpoints surface these in their per-file `errors` list.
|
|
"""
|
|
filename = file.filename or "unknown.pdf"
|
|
data = await file.read(max_bytes + 1)
|
|
if len(data) > max_bytes:
|
|
raise ValueError(
|
|
f"{filename}: file exceeds the {max_bytes // (1024 * 1024)} MB limit"
|
|
)
|
|
if not data.startswith(b"%PDF"):
|
|
raise ValueError(f"{filename}: not a PDF file")
|
|
return data
|