docling-studio/document-parser/api/schemas.py
Pier-Jean Malandrino 4af6b5b231 Add chunk-to-bbox hover highlighting in Prepare mode
Extract bounding boxes from chunk doc_items provenance in the chunker,
propagate through domain/service/API layers, and render highlighted
bboxes on canvas when hovering a chunk card. Reset highlights on
mode and page changes to prevent stale visual state.
2026-04-02 14:47:31 +02:00

126 lines
3.5 KiB
Python

"""Pydantic schemas — API request/response DTOs.
All responses use camelCase serialization to match the existing frontend contract
(originally served by the Spring Boot backend).
"""
from __future__ import annotations
from datetime import datetime
from pydantic import BaseModel, ConfigDict, field_validator
def _to_camel(name: str) -> str:
parts = name.split("_")
return parts[0] + "".join(w.capitalize() for w in parts[1:])
class _CamelModel(BaseModel):
"""Base model that serializes field names to camelCase."""
model_config = ConfigDict(
alias_generator=_to_camel,
populate_by_name=True,
serialize_by_alias=True,
)
class DocumentResponse(_CamelModel):
id: str
filename: str
content_type: str | None = None
file_size: int | None = None
page_count: int | None = None
created_at: str | datetime
class AnalysisResponse(_CamelModel):
id: str
document_id: str = ""
document_filename: str | None = None
status: str
content_markdown: str | None = None
content_html: str | None = None
pages_json: str | None = None
chunks_json: str | None = None
has_document_json: bool = False
error_message: str | None = None
started_at: str | datetime | None = None
completed_at: str | datetime | None = None
created_at: str | datetime
class PipelineOptionsRequest(BaseModel):
"""Docling pipeline configuration options."""
do_ocr: bool = True
do_table_structure: bool = True
table_mode: str = "accurate" # "accurate" or "fast"
do_code_enrichment: bool = False
do_formula_enrichment: bool = False
do_picture_classification: bool = False
do_picture_description: bool = False
generate_picture_images: bool = False
generate_page_images: bool = False
images_scale: float = 1.0
@field_validator("table_mode")
@classmethod
def validate_table_mode(cls, v: str) -> str:
if v not in ("accurate", "fast"):
raise ValueError('table_mode must be "accurate" or "fast"')
return v
@field_validator("images_scale")
@classmethod
def validate_images_scale(cls, v: float) -> float:
if v <= 0 or v > 10:
raise ValueError("images_scale must be between 0 (exclusive) and 10")
return v
class ChunkingOptionsRequest(BaseModel):
"""Docling chunking configuration options."""
chunker_type: str = "hybrid" # "hybrid", "hierarchical"
max_tokens: int = 512
merge_peers: bool = True
repeat_table_header: bool = True
@field_validator("chunker_type")
@classmethod
def validate_chunker_type(cls, v: str) -> str:
if v not in ("hybrid", "hierarchical"):
raise ValueError('chunker_type must be "hybrid" or "hierarchical"')
return v
@field_validator("max_tokens")
@classmethod
def validate_max_tokens(cls, v: int) -> int:
if v < 64 or v > 8192:
raise ValueError("max_tokens must be between 64 and 8192")
return v
class ChunkBboxResponse(_CamelModel):
page: int
bbox: list[float]
class ChunkResponse(_CamelModel):
text: str
headings: list[str] = []
source_page: int | None = None
token_count: int = 0
bboxes: list[ChunkBboxResponse] = []
class CreateAnalysisRequest(BaseModel):
documentId: str # camelCase to match existing frontend contract
pipelineOptions: PipelineOptionsRequest | None = None
chunkingOptions: ChunkingOptionsRequest | None = None
class RechunkRequest(BaseModel):
chunkingOptions: ChunkingOptionsRequest