Skip to content

pdfpolish

tools/pdfpolish/ β€” standalone Python CLI that batch-repairs PDF structural accessibility defects (veraPDF/Matterhorn scope) and cleans tag trees. See tools/pdfpolish/README.md for usage; this page covers operational wiring.

Architecture

  • Python 3.11+, pikepdf + pymupdf; optional editable install of services/flyer-tagger supplies ToUnicode synthesis (flyer_tagger.tounicode.add_missing_tounicode, in-memory) and substitute font embedding (flyer_tagger.fontsub.embed_substitute_fonts, fileβ†’file β€” it runs after the polished copy is saved).
  • Own repair code lives in pdfpolish/repairs/ (docmeta, structrepair, tagtree, linkalt, fonts); tree-walk helpers in pdfpolish/structwalk.py.
  • Config: ~/.config/pdfpolish/config.toml via pdfpolish configure (API key, default metadata tags, defaults). THEACCESSIBLE_API_KEY env overrides.

API dependencies (merged in PR #2429)

Two workers/api endpoints, X-API-Key auth, {success, data} envelope:

  • POST /api/pdf/alt-text β€” JSON {imageBase64, mimeType, context?, pageText?} β†’ {alt, decorative, confidence}. Bedrock Haiku (ZDR-compliant), cost recorded with existing alt-text operation type. Works on Lambda and Node.
  • POST /api/pdf/validate β€” raw PDF (≀50 MB) β†’ veraPDF PDF/UA-1 result. Node .4 only (veraPDF sidecar at VERAPDF_URL); returns 503 VERAPDF_UNAVAILABLE on Lambda. The CLI treats that as β€œvalidation unavailable” and says so in the report.

Deployed 2026-08-29 (Lambda auto-deploy + .4 rebuild); both endpoints are live on api.gevell.com.

Failure modes

  • No local verapdf and no API key β†’ validation skipped, noted per file.
  • flyer-tagger absent β†’ font repairs skipped, noted per file.
  • Untagged / encrypted / corrupt PDFs β†’ unrepairable in the report, no output written; originals never touched.