""" Pydantic models for request/response validation across the Puff n Parse API. """ from pydantic import BaseModel, Field from typing import Literal, Optional from enum import Enum class FileType(str, Enum): """Supported input file types.""" PDF = "pdf" JPEG = "jpeg" PNG = "png" URL = "url" class ProcessingLane(str, Enum): """Which engine processes the file.""" PDF_PARSER = "pdf_parser" OCR_ENGINE = "ocr_engine" URL_PARSER = "url_parser" class DocumentType(str, Enum): """How the document data is structured.""" FORM = "form" FREE_TEXT = "free_text" class ExportFormat(str, Enum): """Supported output file formats.""" CSV = "csv" XLSX = "xlsx" DOCX = "docx" PDF = "pdf" class ExtractedField(BaseModel): """A single extracted field with its name, value, and metadata.""" name: str = Field(..., description="The field label/name extracted from the document") value: str = Field(..., description="The field value extracted from the document") field_type: str = Field(default="text", description="Type of field: text, number, date, etc.") confidence: float = Field(default=0.0, ge=0.0, le=1.0, description="OCR confidence score 0-1") editable: bool = Field(default=True, description="Whether the user can edit this value") class ExtractionMetadata(BaseModel): """Metadata about the extraction process.""" filename: str file_type: FileType processing_lane: ProcessingLane document_type: DocumentType = DocumentType.FORM page_count: int = 1 language_detected: Optional[str] = None processing_time_ms: int = 0 confidence_score: float = 0.0 class ExtractionResponse(BaseModel): """Response returned after file upload and extraction.""" success: bool = True fields: list[ExtractedField] = [] metadata: ExtractionMetadata summary: Optional[str] = None message: str = "Extraction completed successfully" class ExportRequest(BaseModel): """Request body for file export.""" fields: list[ExtractedField] format: ExportFormat filename: Optional[str] = "export" class TierStatus(BaseModel): """Current usage status for the user's tier.""" is_registered: bool = False sessions_used: int = 0 sessions_limit: int = 5 files_this_session: int = 0 files_limit: int = 3 max_file_size_mb: int = 10 class TierCheckResponse(BaseModel): """Response from tier validation.""" allowed: bool tier: TierStatus message: str = "" class ErrorResponse(BaseModel): """Standard error response.""" success: bool = False error: str code: str = "UNKNOWN_ERROR"