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 ofservices/flyer-taggersupplies 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 inpdfpolish/structwalk.py. - Config:
~/.config/pdfpolish/config.tomlviapdfpolish configure(API key, default metadata tags, defaults).THEACCESSIBLE_API_KEYenv 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 existingalt-textoperation type. Works on Lambda and Node.POST /api/pdf/validateβ raw PDF (β€50 MB) β veraPDF PDF/UA-1 result. Node .4 only (veraPDF sidecar atVERAPDF_URL); returns 503VERAPDF_UNAVAILABLEon 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
verapdfand no API key β validation skipped, noted per file. - flyer-tagger absent β font repairs skipped, noted per file.
- Untagged / encrypted / corrupt PDFs β
unrepairablein the report, no output written; originals never touched.