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:
- A Python package and CLI:
oc-pdf-filler(subcommands:extract,fill,list-backends). - 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:
- pypdf -- pure Python, required dependency.
- pdfrw -- fine-grained dictionary control (optional).
- PyMuPDF -- robust appearance regeneration, native checkbox/radio handling (optional).
- 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file oc_pdf_filler-0.1.5.tar.gz.
File metadata
- Download URL: oc_pdf_filler-0.1.5.tar.gz
- Upload date:
- Size: 20.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9757593e0b244ff1a5f9fe345676b39d37022db007d04ae1517d335b3950af3b
|
|
| MD5 |
823a69fcace4c7a3c62ab266a4139cbd
|
|
| BLAKE2b-256 |
b38ed4b817338d4456980f132d3535f5be16e57b099c66a28f5c795790a6efb7
|
File details
Details for the file oc_pdf_filler-0.1.5-py3-none-any.whl.
File metadata
- Download URL: oc_pdf_filler-0.1.5-py3-none-any.whl
- Upload date:
- Size: 18.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11162bf0837518a1c4c4e3de9db5cc9c07e2f18a63450c72b235bb9f2e99b453
|
|
| MD5 |
1dddb8fedbd9f8a7d4cb5502556ef138
|
|
| BLAKE2b-256 |
b08fd92a38495037c5df63b2d1770543b08436835449dcc00fc2b5802991db4d
|