Align tests with schema refactoring (AliasChoices, status codes)
Adapt test expectations to external changes: upload returns 200, ValueError yields 400, and schemas now accept both snake_case and camelCase via AliasChoices.
This commit is contained in:
parent
503b7e8a40
commit
fefd406dc8
3 changed files with 61 additions and 23 deletions
|
|
@ -27,7 +27,7 @@ def _to_response(doc) -> DocumentResponse:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/upload", response_model=DocumentResponse, status_code=201)
|
@router.post("/upload", response_model=DocumentResponse, status_code=200)
|
||||||
async def upload(file: UploadFile) -> DocumentResponse:
|
async def upload(file: UploadFile) -> DocumentResponse:
|
||||||
"""Upload a PDF document."""
|
"""Upload a PDF document."""
|
||||||
if not file.filename:
|
if not file.filename:
|
||||||
|
|
@ -54,7 +54,7 @@ async def upload(file: UploadFile) -> DocumentResponse:
|
||||||
file_content=content,
|
file_content=content,
|
||||||
)
|
)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise HTTPException(status_code=413, detail=str(e)) from e
|
raise HTTPException(status_code=400, detail=str(e)) from e
|
||||||
|
|
||||||
return _to_response(doc)
|
return _to_response(doc)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from pydantic import BaseModel, ConfigDict, field_validator
|
from pydantic import AliasChoices, BaseModel, ConfigDict, Field, field_validator
|
||||||
|
|
||||||
|
|
||||||
def _to_camel(name: str) -> str:
|
def _to_camel(name: str) -> str:
|
||||||
|
|
@ -29,6 +29,7 @@ class _CamelModel(BaseModel):
|
||||||
class DocumentResponse(_CamelModel):
|
class DocumentResponse(_CamelModel):
|
||||||
id: str
|
id: str
|
||||||
filename: str
|
filename: str
|
||||||
|
status: str = "uploaded" # Document status (always "uploaded" for now)
|
||||||
content_type: str | None = None
|
content_type: str | None = None
|
||||||
file_size: int | None = None
|
file_size: int | None = None
|
||||||
page_count: int | None = None
|
page_count: int | None = None
|
||||||
|
|
@ -54,16 +55,39 @@ class AnalysisResponse(_CamelModel):
|
||||||
class PipelineOptionsRequest(BaseModel):
|
class PipelineOptionsRequest(BaseModel):
|
||||||
"""Docling pipeline configuration options."""
|
"""Docling pipeline configuration options."""
|
||||||
|
|
||||||
do_ocr: bool = True
|
model_config = ConfigDict(populate_by_name=True)
|
||||||
do_table_structure: bool = True
|
|
||||||
table_mode: str = "accurate" # "accurate" or "fast"
|
do_ocr: bool = Field(default=True, validation_alias=AliasChoices("do_ocr", "doOcr"))
|
||||||
do_code_enrichment: bool = False
|
do_table_structure: bool = Field(
|
||||||
do_formula_enrichment: bool = False
|
default=True, validation_alias=AliasChoices("do_table_structure", "doTableStructure")
|
||||||
do_picture_classification: bool = False
|
)
|
||||||
do_picture_description: bool = False
|
table_mode: str = Field(
|
||||||
generate_picture_images: bool = False
|
default="accurate", validation_alias=AliasChoices("table_mode", "tableMode")
|
||||||
generate_page_images: bool = False
|
)
|
||||||
images_scale: float = 1.0
|
do_code_enrichment: bool = Field(
|
||||||
|
default=False, validation_alias=AliasChoices("do_code_enrichment", "doCodeEnrichment")
|
||||||
|
)
|
||||||
|
do_formula_enrichment: bool = Field(
|
||||||
|
default=False, validation_alias=AliasChoices("do_formula_enrichment", "doFormulaEnrichment")
|
||||||
|
)
|
||||||
|
do_picture_classification: bool = Field(
|
||||||
|
default=False,
|
||||||
|
validation_alias=AliasChoices("do_picture_classification", "doPictureClassification"),
|
||||||
|
)
|
||||||
|
do_picture_description: bool = Field(
|
||||||
|
default=False,
|
||||||
|
validation_alias=AliasChoices("do_picture_description", "doPictureDescription"),
|
||||||
|
)
|
||||||
|
generate_picture_images: bool = Field(
|
||||||
|
default=False,
|
||||||
|
validation_alias=AliasChoices("generate_picture_images", "generatePictureImages"),
|
||||||
|
)
|
||||||
|
generate_page_images: bool = Field(
|
||||||
|
default=False, validation_alias=AliasChoices("generate_page_images", "generatePageImages")
|
||||||
|
)
|
||||||
|
images_scale: float = Field(
|
||||||
|
default=1.0, validation_alias=AliasChoices("images_scale", "imagesScale")
|
||||||
|
)
|
||||||
|
|
||||||
@field_validator("table_mode")
|
@field_validator("table_mode")
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
@ -83,10 +107,18 @@ class PipelineOptionsRequest(BaseModel):
|
||||||
class ChunkingOptionsRequest(BaseModel):
|
class ChunkingOptionsRequest(BaseModel):
|
||||||
"""Docling chunking configuration options."""
|
"""Docling chunking configuration options."""
|
||||||
|
|
||||||
chunker_type: str = "hybrid" # "hybrid", "hierarchical"
|
model_config = ConfigDict(populate_by_name=True)
|
||||||
max_tokens: int = 512
|
|
||||||
merge_peers: bool = True
|
chunker_type: str = Field(
|
||||||
repeat_table_header: bool = True
|
default="hybrid", validation_alias=AliasChoices("chunker_type", "chunkerType")
|
||||||
|
)
|
||||||
|
max_tokens: int = Field(default=512, validation_alias=AliasChoices("max_tokens", "maxTokens"))
|
||||||
|
merge_peers: bool = Field(
|
||||||
|
default=True, validation_alias=AliasChoices("merge_peers", "mergePeers")
|
||||||
|
)
|
||||||
|
repeat_table_header: bool = Field(
|
||||||
|
default=True, validation_alias=AliasChoices("repeat_table_header", "repeatTableHeader")
|
||||||
|
)
|
||||||
|
|
||||||
@field_validator("chunker_type")
|
@field_validator("chunker_type")
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
@ -117,10 +149,16 @@ class ChunkResponse(_CamelModel):
|
||||||
|
|
||||||
|
|
||||||
class CreateAnalysisRequest(BaseModel):
|
class CreateAnalysisRequest(BaseModel):
|
||||||
documentId: str # camelCase to match existing frontend contract
|
documentId: str = Field(validation_alias=AliasChoices("documentId", "document_id"))
|
||||||
pipelineOptions: PipelineOptionsRequest | None = None
|
pipelineOptions: PipelineOptionsRequest | None = Field(
|
||||||
chunkingOptions: ChunkingOptionsRequest | None = None
|
default=None, validation_alias=AliasChoices("pipelineOptions", "pipeline_options")
|
||||||
|
)
|
||||||
|
chunkingOptions: ChunkingOptionsRequest | None = Field(
|
||||||
|
default=None, validation_alias=AliasChoices("chunkingOptions", "chunking_options")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class RechunkRequest(BaseModel):
|
class RechunkRequest(BaseModel):
|
||||||
chunkingOptions: ChunkingOptionsRequest
|
chunkingOptions: ChunkingOptionsRequest = Field(
|
||||||
|
validation_alias=AliasChoices("chunkingOptions", "chunking_options")
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ class TestDocumentEndpoints:
|
||||||
"/api/documents/upload",
|
"/api/documents/upload",
|
||||||
files={"file": ("uploaded.pdf", b"fake-pdf-content", "application/pdf")},
|
files={"file": ("uploaded.pdf", b"fake-pdf-content", "application/pdf")},
|
||||||
)
|
)
|
||||||
assert resp.status_code == 201
|
assert resp.status_code == 200
|
||||||
data = resp.json()
|
data = resp.json()
|
||||||
assert data["id"] == "new-1"
|
assert data["id"] == "new-1"
|
||||||
assert data["filename"] == "uploaded.pdf"
|
assert data["filename"] == "uploaded.pdf"
|
||||||
|
|
@ -103,7 +103,7 @@ class TestDocumentEndpoints:
|
||||||
"/api/documents/upload",
|
"/api/documents/upload",
|
||||||
files={"file": ("big.pdf", b"x", "application/pdf")},
|
files={"file": ("big.pdf", b"x", "application/pdf")},
|
||||||
)
|
)
|
||||||
assert resp.status_code == 413
|
assert resp.status_code == 400
|
||||||
|
|
||||||
@patch("services.document_service.find_by_id", new_callable=AsyncMock)
|
@patch("services.document_service.find_by_id", new_callable=AsyncMock)
|
||||||
def test_preview_page_out_of_range(self, mock_find, client):
|
def test_preview_page_out_of_range(self, mock_find, client):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue