feat: add parse_document to the MonkeyOCR transport
Unrecognizable bytes are rejected before any request. The result package is downloaded as a stream with a cumulative size cap, and error statuses are classified before the size check. Parsing runs in a worker thread so cancellation and call deadlines stay effective. parse_layout shares the first protocol stage without behavior change.
This commit is contained in:
@@ -20,67 +20,16 @@ from polygateway.errors import ResultInvalidError
|
||||
from polygateway.transports import _monkey_document
|
||||
from polygateway.transports._monkey_document import parse_document_package
|
||||
from polygateway.types import OcrDocumentElement
|
||||
|
||||
_BBOX = (10.0, 20.0, 110.0, 40.0)
|
||||
|
||||
|
||||
def _span(content="SYNTH-TEXT", type_="text"):
|
||||
return {"type": type_, "content": content, "bbox": list(_BBOX), "score": 1.0}
|
||||
|
||||
|
||||
def _text_block(content="SYNTH-TEXT", *, type_="text", bbox=_BBOX):
|
||||
return {
|
||||
"type": type_,
|
||||
"bbox": list(bbox),
|
||||
"index": 0,
|
||||
"lines": [{"bbox": list(bbox), "spans": [_span(content)]}],
|
||||
}
|
||||
|
||||
|
||||
def _body(type_, spans, bbox=_BBOX):
|
||||
return {"type": type_, "bbox": list(bbox), "lines": [{"bbox": list(bbox), "spans": spans}]}
|
||||
|
||||
|
||||
def _table_block(html="<table><tr><td>SYNTH-CELL</td></tr></table>", extra_subs=()):
|
||||
body = _body("table_body", [{"type": "table", "html": html, "image_path": "synth.jpg"}])
|
||||
return {"type": "table", "bbox": list(_BBOX), "index": 1, "blocks": [*extra_subs, body]}
|
||||
|
||||
|
||||
def _image_block():
|
||||
body = _body("image_body", [{"type": "image", "image_path": "synth.jpg"}])
|
||||
return {"type": "image", "bbox": list(_BBOX), "index": 2, "blocks": [body]}
|
||||
|
||||
|
||||
def _page(blocks=None, *, page_idx=0, page_size=(612.0, 792.0), **extra):
|
||||
page = {"page_idx": page_idx, "page_size": list(page_size), "discarded_blocks": []}
|
||||
if blocks is not None:
|
||||
page["para_blocks"] = blocks
|
||||
page.update(extra)
|
||||
return page
|
||||
|
||||
|
||||
def _package(
|
||||
pages=None,
|
||||
*,
|
||||
md="# synth\n",
|
||||
middle=None,
|
||||
middle_name="doc_middle.json",
|
||||
md_name=None,
|
||||
extra=(),
|
||||
):
|
||||
"""组装结果包。`middle` 给原始 bytes 时原样写入;`md_name` 默认由 middle 名配对。"""
|
||||
if middle is None:
|
||||
middle = json.dumps({"pdf_info": pages if pages is not None else [_page([])]}).encode()
|
||||
if md_name is None:
|
||||
md_name = middle_name[: -len("_middle.json")] + ".md"
|
||||
buf = io.BytesIO()
|
||||
with zipfile.ZipFile(buf, "w") as zf:
|
||||
zf.writestr(middle_name, middle)
|
||||
if md is not None:
|
||||
zf.writestr(md_name, md if isinstance(md, bytes) else md.encode())
|
||||
for name, data in extra:
|
||||
zf.writestr(name, data)
|
||||
return buf.getvalue()
|
||||
from tests.unit._document_fixtures import (
|
||||
_BBOX,
|
||||
_body,
|
||||
_image_block,
|
||||
_package,
|
||||
_page,
|
||||
_span,
|
||||
_table_block,
|
||||
_text_block,
|
||||
)
|
||||
|
||||
|
||||
def _parse(pages=None, **kwargs):
|
||||
|
||||
Reference in New Issue
Block a user