Files
cmm-report-analyzer/app/routers/upload.py
chrisryn 9abf9b4b58 Initial commit: CMM Report Analyzer
FastAPI app that parses CMM inspection reports (PDF/Excel/CSV),
computes SPC metrics (Cp/Cpk/Pp/Ppk, control limits, Shapiro-Wilk),
generates interactive Plotly charts, and provides AI-powered quality
summaries via Azure OpenAI with graceful fallback.

Includes 21 passing tests covering parsers, SPC calculations, and
API endpoints.
2026-02-19 10:38:51 -06:00

47 lines
1.4 KiB
Python

from __future__ import annotations
import tempfile
from pathlib import Path
from fastapi import APIRouter, HTTPException, UploadFile
from app.config import settings
from app.services.batch import process_batch
router = APIRouter()
ALLOWED_EXTENSIONS = {".pdf", ".xlsx", ".xls", ".csv"}
@router.post("/upload")
async def upload_files(files: list[UploadFile]):
if not files:
raise HTTPException(400, "No files provided")
saved: list[Path] = []
tmp_dir = Path(tempfile.mkdtemp(prefix="cmm_"))
for f in files:
if not f.filename:
continue
ext = Path(f.filename).suffix.lower()
if ext not in ALLOWED_EXTENSIONS:
raise HTTPException(
400, f"Unsupported file type: {ext}. Allowed: {ALLOWED_EXTENSIONS}"
)
size = 0
dest = tmp_dir / f.filename
with open(dest, "wb") as out:
while chunk := await f.read(1024 * 64):
size += len(chunk)
if size > settings.max_upload_mb * 1024 * 1024:
raise HTTPException(400, f"File too large (max {settings.max_upload_mb} MB)")
out.write(chunk)
saved.append(dest)
if not saved:
raise HTTPException(400, "No valid files uploaded")
batch_id = await process_batch(saved)
return {"batch_id": batch_id, "file_count": len(saved)}