Skip to content

Add optional segment_boxes to /markdown and /html to skip re-analysis - #138

Merged
ali6parmak merged 1 commit into
huridocs:mainfrom
makothap:feat/segment-boxes-for-conversion
Jul 13, 2026
Merged

Add optional segment_boxes to /markdown and /html to skip re-analysis#138
ali6parmak merged 1 commit into
huridocs:mainfrom
makothap:feat/segment-boxes-for-conversion

Conversation

@makothap

@makothap makothap commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Motivation

Callers that already ran layout analysis on a document — most commonly via
POST / — have no way to reuse those segments when subsequently calling
/markdown or /html. Today both endpoints always re-run analysis
internally, even when the caller already has an equivalent, freshly-computed
segment list in hand. For a pipeline that calls POST / once and then
/markdown and/or /html for output, that's up to 3 analysis passes over the
same document where 1 would do.

This mirrors a pattern already in this codebase: /toc_from_xml accepts a
segment_boxes form field and skips analysis entirely, using the caller's
segments directly. This PR extends the same idea to the two conversion
endpoints.

Design

  • segment_boxes: optional JSON-encoded list of segment dicts (same shape as
    POST /'s response), added as a Form field on /markdown and /html,
    parsed the same way /toc_from_xml already parses its own segment_boxes.
  • In ConvertToMarkdownUseCase.execute / ConvertToHtmlUseCase.execute, when
    segment_boxes is provided it's used as the analysis result directly
    (skipping both analyze_pdf_layout and analyze_pdf_layout_fast); when
    absent, behavior is completely unchanged (including fast mode routing).
  • No changes to PDFAnalysisService, the conversion services, or the
    Clean-Architecture layering — segment_boxes flows in as a use-case
    parameter, not a driver-level hack, consistent with extract_toc,
    dpi, etc.
  • Malformed JSON in segment_boxes raises JSONDecodeError, already caught
    by the existing @catch_exceptions decorator and turned into a 422, so
    no new error handling was needed.

Evidence

From pepng (a downstream consumer, not part of this PR) reprocessing the same
fixtures with and without segment reuse — end-to-end pipeline duration,
INGEST startedCOMPLETE completed:

fixture 3 passes (no reuse) 1 pass (this feature) reduction
table-bordered.pdf 6.975s 2.277s −67.3%
table-merged.pdf 6.540s 2.205s −66.3%
twocol-continuous.pdf 7.808s 3.142s −59.8%

The engine's own logs confirm the skip (this PR adds the equivalent log
lines, matching /toc_from_xml's existing logging style):

[INFO] Calling endpoint: convert_to_html_endpoint
[INFO] Received 3 segment boxes for /html; skipping analysis.

Output was verified byte-for-byte identical with vs. without segment reuse
across three fixtures (document.md, document.html, document.json).

Test coverage

  • Unit tests (src/use_cases/markdown_conversion/test_convert_to_markdown_use_case.py,
    src/use_cases/html_conversion/test_convert_to_html_use_case.py, new in
    this PR): analysis is skipped when segment_boxes is given (asserted via a
    PDFAnalysisService stub that raises if called), and unchanged (including
    fast-mode routing) when it isn't.
  • End-to-end tests (src/tests/test_end_to_end.py, new in this PR, run
    against the real service):
    • /markdown and /html output is identical with vs. without reusing
      segment_boxes from a prior POST / call, on test_pdfs/regular.pdf.
    • Malformed segment_boxes ("not-json") returns 422 for both
      endpoints, not 500.
  • Full existing suite run against the patched build, all 34 tests
    passing
    (src/tests/test_end_to_end.py, includes the 4 new tests above):
    built natively on a DGX Spark (ARM64, NVIDIA GB10 GPU) via
    docker build --build-arg BUILDER_IMAGE=nvidia/cuda:13.0.3-cudnn-devel-ubuntu24.04 --build-arg TORCH_INDEX_URL=https://download.pytorch.org/whl/cu130 --build-arg TORCH_CUDA_ARCH_LIST=12.0;12.1,
    run on a non-default port, verified against the live GPU-backed engine (not
    mocked), then torn down.
  • black --check --line-length 125 clean on all changed files.
  • Not run: the project's CI only targets ubuntu-latest/amd64; this was
    verified on aarch64 instead as that's the available hardware. No GPU-less
    CPU-only run was attempted (out of scope — this change has no CPU/GPU
    branching).

What wasn't run and why

  • The repo's own CI (test.yml, GitHub Actions, amd64) wasn't triggered —
    this is a fork branch, not yet a PR, so Actions haven't run. All tests
    above were run manually against a natively-built image on aarch64
    hardware instead.
  • Translation-related tests (Ollama-backed) weren't specifically re-verified
    for this change since segment_boxes doesn't interact with translation;
    the existing translation tests are part of the "full suite" pass above and
    passed unmodified.

Callers that already ran layout analysis on a document (e.g. via POST /)
can now pass those segments back into /markdown and /html to skip a
redundant re-analysis pass, mirroring the segment_boxes pattern
/toc_from_xml already uses.

- Both endpoints accept an optional segment_boxes form field (JSON list,
  same shape as POST /'s response); when present, analysis is skipped
  entirely and the given segments are converted directly.
- Malformed segment_boxes JSON returns 422 via the existing
  catch_exceptions handling (no new error handling needed).
- Unit tests for both use cases verify analysis is skipped when
  segment_boxes is provided and unchanged when it isn't (including fast
  mode).
- End-to-end tests verify /markdown and /html output is identical with
  and without reusing segment_boxes, and that malformed payloads 4xx.

In a downstream pipeline that already calls POST / for analysis, this
cut markdown+html conversion from 3 HURIDOCS calls per document to 1,
a ~60-67% reduction in end-to-end processing time.
@ali6parmak ali6parmak assigned ali6parmak and unassigned ali6parmak Jul 13, 2026
@ali6parmak

Copy link
Copy Markdown
Collaborator

Thanks for the PR, merging.

@ali6parmak
ali6parmak merged commit c4776ea into huridocs:main Jul 13, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants