File size: 3,248 Bytes
d0f3cbe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
from __future__ import annotations
import logging
import uuid
from datetime import datetime
from typing import List, Optional

from fastapi import APIRouter, File, Form, HTTPException, UploadFile
from pydantic import BaseModel

from schemas.report import ReportInput, ReportType, UploadBatch
from services.pipeline import Pipeline
from services.storage import get_storage

logger = logging.getLogger(__name__)
router = APIRouter(prefix="/reports", tags=["reports"])


@router.post("/upload")
async def upload_reports(
    session_id: Optional[str] = Form(default=None),
    scenario_name: Optional[str] = Form(default=None),
    files: List[UploadFile] = File(default=[]),
    text_messages: Optional[str] = Form(default=None),
) -> dict:
    sid = session_id or str(uuid.uuid4())
    reports: List[ReportInput] = []

    if text_messages:
        for i, msg in enumerate(text_messages.split("|||")):
            msg = msg.strip()
            if msg:
                reports.append(ReportInput(
                    id=str(uuid.uuid4()),
                    session_id=sid,
                    report_type=ReportType.TEXT,
                    content=msg,
                    metadata={"source": "upload", "index": i},
                    created_at=datetime.utcnow(),
                ))

    for file in files:
        filename = file.filename or "unknown"
        name_lower = filename.lower()
        if name_lower.endswith((".mp3", ".wav", ".ogg", ".m4a")):
            rtype = ReportType.AUDIO
        elif name_lower.endswith((".jpg", ".jpeg", ".png", ".webp")):
            rtype = ReportType.IMAGE
        elif name_lower.endswith(".csv"):
            rtype = ReportType.CSV
        else:
            rtype = ReportType.TEXT

        content = await file.read()
        reports.append(ReportInput(
            id=str(uuid.uuid4()),
            session_id=sid,
            report_type=rtype,
            content=content.decode("utf-8", errors="replace") if rtype in (ReportType.TEXT, ReportType.CSV) else None,
            file_path=filename,
            metadata={"original_filename": filename, "size_bytes": len(content)},
            created_at=datetime.utcnow(),
        ))

    storage = get_storage()
    await storage.save_session(sid, {
        "session_id": sid,
        "scenario_name": scenario_name,
        "total_reports": len(reports),
        "status": "uploaded",
        "created_at": datetime.utcnow().isoformat(),
    })

    return {"session_id": sid, "batch_id": sid, "report_count": len(reports), "status": "uploaded"}


@router.post("/process")
async def process_batch(batch: UploadBatch) -> dict:
    pipeline = Pipeline()
    try:
        summary = await pipeline.process_batch(batch)
    except Exception as exc:
        logger.exception("Batch processing error: %s", exc)
        raise HTTPException(status_code=500, detail=str(exc))
    return summary.model_dump(mode="json")


@router.get("/{session_id}")
async def list_session_reports(session_id: str) -> dict:
    storage = get_storage()
    session = await storage.get_session(session_id)
    if session is None:
        raise HTTPException(status_code=404, detail=f"Session {session_id} not found")
    return {"session_id": session_id, "session": session}