Skip to content

Basic Usage⚓︎

This section covers the basic entry points for PyPDFForm's Python API and CLI, along with global options that affect PyPDFForm behavior.

The main user interface of the library is the PdfWrapper class. It implements most PyPDFForm APIs and accepts various optional parameters, the most important of which is the PDF form template.

For example, to use this PDF as a template, instantiate the PdfWrapper object as follows:

from PyPDFForm import PdfWrapper

pdf = PdfWrapper("sample_template.pdf")
from PyPDFForm import PdfWrapper

with open("sample_template.pdf", "rb+") as template:
    pdf = PdfWrapper(template)
from PyPDFForm import PdfWrapper

with open("sample_template.pdf", "rb+") as template:
    pdf = PdfWrapper(template.read())
Tip

PyPDFForm provides an adapter for different file interaction methods in Python, which allows you to pass your PDF form to PdfWrapper as a file path, an open file object, or a bytes file stream. This file adaptation applies to all PyPDFForm APIs. You can replace file path parameters with file objects or streams throughout the documentation.

To see CLI help, run:

pypdfform -h

The CLI shows help for available commands and usage. Subcommands show their own help when run without arguments or options.

Handling appearance streams⚓︎

For a PDF viewer to display content in a form field (especially text fields), it needs an "appearance stream." This stream defines how the field's content is rendered. PyPDFForm offers two ways to handle this.

Appearance stream handling options are set with keyword arguments when instantiating PdfWrapper.

Set need_appearances=True to instruct the PDF viewer to generate appearance streams. This is often the best choice when you expect the PDF to be opened in powerful, proprietary software like Adobe Acrobat, which has sophisticated rendering capabilities.

from PyPDFForm import PdfWrapper

pdf = PdfWrapper("sample_template.pdf", need_appearances=True)

Set generate_appearance_streams=True to use PyPDFForm's built-in generator. This is a good fallback if the PDF viewer lacks the ability to generate its own appearance streams.

from PyPDFForm import PdfWrapper

pdf = PdfWrapper("sample_template.pdf", generate_appearance_streams=True)
Warning

PyPDFForm's internal appearance stream generation relies on qpdf and shares its limitations. Some known limitations include:

  • Limited to ASCII text: Only ASCII characters are supported.
  • Single-line text fields only: It does not support multi-line text fields.
  • No text alignment handling: Text alignment (left, center, right) is not preserved or applied.

Appearance stream handling options are set with global options when running a command.

pypdfform --need-appearances
pypdfform --generate-appearance-streams
Warning

PyPDFForm's internal appearance stream generation relies on qpdf and shares its limitations. Some known limitations include:

  • Limited to ASCII text: Only ASCII characters are supported.
  • Single-line text fields only: It does not support multi-line text fields.
  • No text alignment handling: Text alignment (left, center, right) is not preserved or applied.

Handling metadata⚓︎

Note

PDF metadata preservation must be enabled explicitly due to regressions identified in the test suites.

To ensure the original metadata of a PDF template is maintained after performing operations with PdfWrapper, set the preserve_metadata parameter to True during instantiation:

from PyPDFForm import PdfWrapper

pdf = PdfWrapper("sample_template.pdf", preserve_metadata=True)

For the CLI, set the global option --preserve-metadata when running a command:

pypdfform --preserve-metadata

Use full name for PDF form fields⚓︎

According to section 12.7.3.2 of the PDF standard, PDF form fields can have fully qualified names constructed using the pattern <parent_field_name>.<field_name>.

PyPDFForm allows you to access fields by their full names. For example, to use this PDF:

Set use_full_widget_name to True when instantiating PdfWrapper:

from PyPDFForm import PdfWrapper

pdf = PdfWrapper("sample_template_with_full_key.pdf", use_full_widget_name=True)
Warning

When using full names, the update_widget_key and commit_widget_key_updates methods of PdfWrapper are disabled and raise a NotImplementedError because full names involve both the field and its parent.

Set the global option --use-full-widget-name when running a command:

pypdfform --use-full-widget-name
Warning

As with the library API, pypdfform update rename raises an error when called with --use-full-widget-name.

This enables accessing fields by their full names. For instance, you can access the checkbox labeled Gain de 2 classes using its full name Gain de 2 classes.0 instead of its partial name 0.

Write to a file⚓︎

The PdfWrapper acts as a file-like object, enabling you to write the processed PDF to another file-like object:

from PyPDFForm import PdfWrapper

pdf = PdfWrapper("sample_template.pdf")

with open("output.pdf", "wb+") as output:
    output.write(pdf.read())
from io import BytesIO
from PyPDFForm import PdfWrapper

pdf = PdfWrapper("sample_template.pdf")

with BytesIO() as output:
    output.write(pdf.read())

Additionally, PdfWrapper offers a convenient write method to save the PDF directly.

from PyPDFForm import PdfWrapper

pdf = PdfWrapper("sample_template.pdf")
pdf.write("output.pdf")
from io import BytesIO
from PyPDFForm import PdfWrapper

buff = BytesIO()

pdf = PdfWrapper("sample_template.pdf")
pdf.write(buff)

buff.seek(0)

The CLI is stateless. When a command writes a file, it either updates the input file in place or writes to the location specified by the --output/-o option.