Files
hunjing/tianmu/src/schemas/ocr.py
T
2026-08-21 16:00:13 +08:00

105 lines
3.6 KiB
Python

"""
OCR 请求 / 响应 Pydantic 模型。
定义天目微服务内部的 API 契约,供 endpoints 和 engine 使用。
"""
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, Field
class OCRRequest(BaseModel):
"""通用 OCR 请求。"""
image: str = Field(description="图片数据:base64 编码字符串或 HTTP(s) URL")
engine: str = Field(
default="auto",
description="引擎选择:auto(自动选择)/ ppocrv6 / paddleocr-vl",
)
lang: list[str] = Field(
default_factory=lambda: ["ch", "en"],
description="识别语言列表,默认中英文。仅对 ppocrv6 引擎生效",
)
resize: int | None = Field(
default=None,
description="可选:图片最大边长(px),超过则等比缩放。减少传输 / 推理耗时",
)
save_md: bool = Field(
default=False,
description="是否将识别结果保存为 Markdown 文件到 output/md/ 目录",
)
class BBox(BaseModel):
"""文本框坐标。"""
points: list[list[float]] = Field(description="四个顶点坐标 [[x1,y1],[x2,y1],[x3,y2],[x4,y2]]")
class TextBlock(BaseModel):
"""单行/单块识别结果。"""
text: str = Field(description="识别文字")
confidence: float = Field(description="置信度 0~1", ge=0, le=1)
bbox: BBox = Field(description="文本框坐标")
class OCRResponse(BaseModel):
"""通用 OCR 响应。"""
engine: str = Field(description="实际使用的引擎,如 ppocrv6 / paddleocr-vl")
text: str = Field(default="", description="拼接后的全文")
blocks: list[TextBlock] = Field(default_factory=list, description="逐块识别结果")
duration_ms: float = Field(default=0, description="推理耗时(毫秒)")
error: str | None = Field(default=None, description="错误信息,成功时为 null")
saved_md_path: str | None = Field(
default=None, description="保存的 Markdown 文件路径(仅 save_md=true 时有值)"
)
class OCRVLRequest(BaseModel):
"""PaddleOCR-VL 复杂文档解析请求。"""
image: str = Field(description="图片数据:base64 编码字符串或 HTTP(s) URL")
output_format: str = Field(
default="markdown",
description="输出格式:markdown / json / text",
)
save_md: bool = Field(
default=False,
description="是否将识别结果保存为 Markdown 文件到 output/md/ 目录",
)
class OCRVLResponse(BaseModel):
"""PaddleOCR-VL 响应。"""
engine: str = Field(default="paddleocr-vl")
text: str = Field(default="", description="结构化输出文本(Markdown / JSON / 纯文本)")
format: str = Field(default="markdown", description="实际输出格式")
duration_ms: float = Field(default=0, description="推理耗时(毫秒)")
error: str | None = Field(default=None, description="错误信息,成功时为 null")
saved_md_path: str | None = Field(
default=None, description="保存的 Markdown 文件路径(仅 save_md=true 时有值)"
)
# ── 健康检查 ──────────────────────────────────────────────
class EngineStatus(BaseModel):
"""引擎状态。"""
status: str = Field(description="ok / degraded / error / unavailable")
class HealthResponse(BaseModel):
"""健康检查响应。"""
status: str = Field(description="整体状态:ok / degraded / error")
engines: dict[str, Any] = Field(default_factory=dict, description="各引擎状态")
version: str = Field(description="天目版本")