Skip to main content

Extract and fill PDF AcroForm fields with a multi-backend fallback chain (pypdf, pdfrw, PyMuPDF, pdftk).

Project description

oc-pdf-filler

Extract and fill PDF AcroForm fields from the command line, with a multi-backend fallback chain so a single quirky PDF doesn't block your workflow.

The repo ships two artifacts:

  1. A Python package and CLI: oc-pdf-filler (subcommands: extract, fill, list-backends).
  2. An OpenClaw / AgentSkills skill at skills/pdf-filler/ that wraps the CLI so agents can use it.

Why a fallback chain?

PDF AcroForms are notoriously inconsistent. The orchestrator tries each backend in order and stops at the first one that fills every requested field:

  1. pypdf -- pure Python, required dependency.
  2. pdfrw -- fine-grained dictionary control (optional).
  3. PyMuPDF -- robust appearance regeneration, native checkbox/radio handling (optional).
  4. pdftk -- system binary, last resort (optional).

Backends without their dependency present are skipped automatically.

Install

pip install -e ".[all]"          # full fallback chain (pypdf + pdfrw + PyMuPDF)
# or, minimal:
pip install -e .                 # pypdf only
# Optional system dep:
brew install pdftk-java          # macOS
apt install pdftk-java           # Debian/Ubuntu

Verify your backends:

oc-pdf-filler list-backends

CLI usage

Extract a field schema

oc-pdf-filler extract form.pdf --output schema.json --include-values

Output is JSON with one entry per field:

{
  "field_count": 27,
  "fields": [
    {
      "name": "Name Verantwortlicher",
      "type": "text",
      "value": "ACME GmbH",
      "options": [],
      "max_length": null,
      "required": false,
      "multiline": false,
      "read_only": false
    }
  ]
}

type is one of text, checkbox, radio, choice, signature, pushbutton, unknown.

Fill a PDF

Build a JSON values file. Field names come from the schema verbatim.

{
  "Name Verantwortlicher": "ACME GmbH",
  "Postleitzahl Verantwortlicher": "10115",
  "Beschäftigte": true,
  "Verarbeitungstyp": "Automatisiert"
}

Then run:

# default: writes ./form_done.pdf next to your cwd
oc-pdf-filler fill form.pdf values.json
# or pass --output explicitly
oc-pdf-filler fill form.pdf values.json --output filled.pdf

Useful flags:

Flag Effect
--backend NAME Force one of pypdf / pdfrw / pymupdf / pdftk (default: auto)
--best-effort Chain backends so partial fills accumulate
--flatten Bake values into the PDF (best support: PyMuPDF, pdftk)
--strict Exit non-zero if any field is missing or unfillable

Value coercion per field type

Type JSON value
text string (newlines preserved when multiline is true)
checkbox true / false or "true", "yes", "on", "x", "1", "checked"
radio string equal to one of the entries in the field's options array
choice string equal to one of the dropdown options
signature not supported -- reported in the schema, ignored at fill time

Tests

pip install -e ".[dev]"
pytest -q

Tests run against the three real PDFs in test_pdfs/ and parametrize across every available backend. They round-trip text and checkbox values (fill, re-extract, assert).

OpenClaw skill

The skills/pdf-filler/ folder is an AgentSkills.io spec-compliant skill that an OpenClaw agent can load to get PDF-filling capabilities. It contains:

skills/pdf-filler/
├── SKILL.md                    # frontmatter + instructions
├── scripts/
│   ├── extract.py
│   ├── fill.py
│   └── list_backends.py
├── references/
│   ├── FIELD_TYPES.md
│   └── BACKENDS.md
└── assets/
    └── values.example.json

Validate it:

npx skills-ref validate ./skills/pdf-filler

Releasing a new version

Bump metadata.version in skills/pdf-filler/SKILL.md, then run:

clawhub publish ./skills/pdf-filler --version <semver>

--version is required and must be valid semver, and should match metadata.version so the registry record stays in sync.

The agent that loads the skill needs oc-pdf-filler installed in its workspace Python environment for the scripts to run; the skill's compatibility field documents this.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

oc_pdf_filler-0.1.2.tar.gz (17.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

oc_pdf_filler-0.1.2-py3-none-any.whl (16.7 kB view details)

Uploaded Python 3

File details

Details for the file oc_pdf_filler-0.1.2.tar.gz.

File metadata

  • Download URL: oc_pdf_filler-0.1.2.tar.gz
  • Upload date:
  • Size: 17.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for oc_pdf_filler-0.1.2.tar.gz
Algorithm Hash digest
SHA256 c3057a45ffbe38f5355427a4279da494b97d92da45030f9191fa8eae66d6a67f
MD5 1b83516bc20a90de5890a06ff5f4eab3
BLAKE2b-256 3036b079a71b79cf1c675eea54ac5cc83f66a846ca785ea9238dc48ed3b8054a

See more details on using hashes here.

File details

Details for the file oc_pdf_filler-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: oc_pdf_filler-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 16.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for oc_pdf_filler-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 995f15fe591587cd13e2a20e8f2030ac8f587b3e6184cdc918087aeb00fff230
MD5 e6afb75520d6322bc544bc74ec66fde1
BLAKE2b-256 6c04e5903e529872d0c2e4c20978c5ed58c973dea68615858daf4e88c72b82bc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page