Main objects

class pikepdf.Pdf(*args, **kwargs)

In-memory representation of a PDF.

Parameters:
  • args (object)

  • kwargs (object)

property Root: Object
Return type:

Object

property acroform: AcroForm

Returns a helper object for working with interactive forms.

Tip

This creates a new AcroForm helper object each time this property is used. If you’re planning on doing multiple form-related operations, keep a reference to this object. The helper has an internal cache that can speed up certain operations.

Return type:

AcroForm

add_blank_page(*, page_size=...)

Add a blank page to this PDF.

If pages already exist, the page will be added to the end. Pages may be reordered using Pdf.pages.

The caller may add content to the page by modifying its objects after creating it.

Parameters:

page_size (tuple) – The size of the page in PDF units (1/72 inch or 0.35mm). Default size is set to a US Letter 8.5” x 11” page.

Return type:

Page

add_pages_from(src, pages=None, *, forms='preserve', layers='preserve', outlines='preserve')

Append pages from another Pdf, with what the document holds for them.

Unlike pdf.pages.extend(src.pages), this carries the document’s AcroForm form fields so they remain functional in Adobe Acrobat. Fields whose fully-qualified names collide with existing fields are automatically renamed; the mapping is available on the returned pikepdf.PageCopyResult. The original→new name mapping in renamed_fields is best-effort (it pairs source and destination page fields positionally).

Independent top-level fields are only carried over when a widget is on a copied page, so unrelated forms on separate pages are not imported. However, a field sharing a top-level ancestor with a copied field is carried as an entire subtree; such partially-represented fields are listed in the result’s partial_fields. Use forms='strip' for a hard guarantee of no form data.

Named destinations referenced by the copied pages’ annotations (such as table-of-contents links) are carried into this document, preserving both the Names.Dests name tree and the legacy Root.Dests dictionary. A destination whose target page is not among the copied pages cannot be migrated and is reported in pikepdf.PageCopyResult.dropped_dests; names that collide with existing destinations are renamed and reported in pikepdf.PageCopyResult.renamed_dests.

Optional content groups (layers) that the copied pages depend on are listed in this document’s /OCProperties, without which viewers ignore them and show content that the source hid. Each group keeps the default state it had in the source, and its place in the layer list, lock, radio button groups and automatic states, as given by the source’s default configuration. Layers already in this document are unaffected. Only the default configuration is carried, not alternate ones in /Configs.

Outline items (bookmarks) of the source that lead to a copied page are appended to this document’s outline, leading to the copy. An item that leads elsewhere is kept, without a destination, only if an item below it is kept, so the hierarchy survives. Titles, colour, bold and italic and whether an item is open are preserved. Items that lead to pages that were not copied, or that run an action other than going to a page, are left behind and counted in pikepdf.PageCopyResult.outline_items_dropped.

Parameters:
  • src (Pdf) – Source Pdf to copy pages from.

  • pages (collections.abc.Iterable[int] | range | slice | None) – Zero-based indices (iterable, range, or slice) of pages in src to copy. None copies all pages. A slice is clamped to the document length; explicit indices (including range) must be valid or IndexError is raised.

  • forms (Literal['preserve', 'strip']) – 'preserve' (default) carries AcroForm fields along with the pages; 'strip' removes widget annotations from the copied pages so no form data is imported.

  • layers (Literal['preserve', 'ignore']) – 'preserve' (default) lists the optional content groups used by the copied pages in this document; 'ignore' copies the pages only, as before pikepdf 10.18, which leaves their optional content always visible unless this document already lists the groups.

  • outlines (Literal['preserve', 'ignore']) – 'preserve' (default) carries the outline items that lead to the copied pages; 'ignore' carries none.

Returns:

A pikepdf.PageCopyResult describing the operation, including which fields were added and any automatic renames.

Return type:

pikepdf._page_copy.PageCopyResult

Changed in version 10.18: Added layers and outlines. Layers and outline items are now carried by default.

property allow: pikepdf.models.encryption.Permissions

Report permissions associated with this PDF.

By default these permissions will be replicated when the PDF is saved. Permissions may also only be changed when a PDF is being saved, and are only available for encrypted PDFs. If a PDF is not encrypted, all operations are reported as allowed.

pikepdf has no way of enforcing permissions.

Return type:

pikepdf.models.encryption.Permissions

property attachments: Attachments

Returns a mapping that provides access to all files attached to this PDF.

PDF supports attaching (or embedding, if you prefer) any other type of file, including other PDFs. This property provides read and write access to these objects by filename.

Return type:

Attachments

check_linearization(stream=...)

Checks the PDF’s linearization data.

The problems found are added to the PDF’s warnings, which get_warnings() and check_pdf_syntax() return.

Parameters:

stream (object) – A stream to write this information too; must implement .write() and .flush() method. Defaults to sys.stderr. Current versions of qpdf report problems as warnings and write nothing to it.

Returns:

True if the file is correctly linearized, and False if the file is linearized but the linearization data contains errors or was incorrectly generated.

Raises:

RuntimeError – If the PDF in question is not linearized at all.

Return type:

bool

check_pdf_syntax(progress=...)

Check if PDF is syntactically well-formed.

Performs the checks that qpdf --check does, looking for syntax or structural problems in the PDF. This is mainly useful to PDF developers and may not be informative to the average user. PDFs with these problems still render correctly, if PDF viewers are capable of working around the issues they contain. In many cases, pikepdf can also fix the problems.

The checks are, in order:

  • if the file is linearized, that its linearization data and hint tables are consistent with the file (as check_linearization() does);

  • that the interactive form, embedded files, page labels and outlines are well formed;

  • that the document has at least one page;

  • that every stream in the file can be decoded;

  • that the content stream of every page can be parsed.

Each problem is reported as a string that begins with WARNING: if qpdf can work around it, or ERROR: if it cannot. Two kinds of error are reported this way: a document with no pages, and a page whose content stream cannot be read at all (ERROR: page 3: ...). Where qpdf --check fails after printing these, this function returns them along with everything else it found. Other errors that prevent the check from completing, such as a damaged page tree, raise pikepdf.PdfError.

The warnings reported are those the Pdf has accumulated, so they include warnings from earlier operations that get_warnings() has not yet collected, and calling this function collects them. Warnings issued while the file was being opened are not included. To see exactly what qpdf --check prints for a file, use pikepdf.Job(['pikepdf', '--check', 'input.pdf']).run().

An example problem found by this function is a xref table that is missing an object reference. A page dictionary with the wrong type of key, such as a string instead of an array of integers for its mediabox, is not the sort of issue checked for. If this were an XML checker, it would tell you if the XML is well-formed, but could not tell you if the XML is valid XHTML or if it can be rendered as a usable web page.

This function also attempts to decompress all streams in the PDF. If no JBIG2 decoder is available and JBIG2 images are presented, a warning will occur that JBIG2 cannot be checked.

This function returns a list of strings describing the issues. The text is subject to change and should not be treated as a stable API.

Parameters:

progress (collections.abc.Callable[[int], None] | None) – A function to call with progress updates, from 0 to 100. If None (default), no progress will be reported.

Returns:

Empty list if no issues were found. List of issues as text strings if issues were found.

Return type:

list[str]

Changed in version 10.18.0: Linearization, the interactive form, embedded files, page labels and outlines are now checked, a document with no pages is reported, and a page whose content stream cannot be read is reported instead of raising an exception.

close()

Close a Pdf object and release resources acquired by pikepdf.

If pikepdf opened the file handle it will close it (e.g. when opened with a file path). If the caller opened the file for pikepdf, the caller close the file. with blocks will call close when exit.

pikepdf lazily loads data from PDFs, so some pikepdf.Object may implicitly depend on the pikepdf.Pdf being open. This is always the case for pikepdf.Stream but can be true for any object. Do not close the Pdf object if you might still be accessing content from it.

When an Object is copied from one Pdf to another, the Object is copied into the destination Pdf immediately, so after accessing all desired information from the source Pdf it may be closed.

Changed in version 3.0: In pikepdf 2.x, this function actually worked by resetting to a very short empty PDF. Code that relied on this quirk may not function correctly.

Return type:

None

content_scopes(*, pages=..., kinds=...)

Iterate over every content stream the pages of this PDF can draw.

Each pikepdf.ContentScope is a content stream together with the resource dictionary that the names in it refer to: the pages, and the form XObjects, annotation appearance streams, tiling patterns, Type 3 glyph procedures and soft masks that they use, however deeply these are nested. See pikepdf.Page.content_scopes() for what is found and in what order.

This is the way to find everything of some kind that a document’s pages use. For example, to list its fonts:

fonts = []
seen_fonts = pikepdf.ObjectSet()
for scope in pdf.content_scopes():
    if scope.resources is None:
        continue
    for font in (scope.resources.get_dict(Name.Font) or {}).values():
        if isinstance(font, pikepdf.Dictionary) and seen_fonts.add(font):
            fonts.append(font)

Each scope is reported once, with page set to the first page that uses it. Scopes are often shared: a logo drawn on every page is one form XObject. Resource dictionaries are shared too, so the same font may still be found in more than one scope, as the example allows for.

Pages are searched one at a time as the iterator advances, so a large document is not searched all at once, and a change made to a page before the iterator reaches it is seen.

Resources that belong to no page are not included, such as the default resources of an interactive form, /AcroForm /DR.

Parameters:
  • pages (collections.abc.Iterable[Page] | None) – The pages to examine, in the order given. The default is every page of the document.

  • kinds (collections.abc.Iterable[pikepdf._content_scopes.ContentScopeKind] | pikepdf._content_scopes.ContentScopeKind | None) – The kinds of scope to report, as one or more of 'page', 'form', 'appearance', 'pattern', 'glyph' and 'softmask'; see pikepdf.ContentScope.kind. The default is all of them. Everything is searched whichever kinds are reported.

Raises:

ValueError – If kinds contains anything else.

Return type:

collections.abc.Iterator[pikepdf._content_scopes.ContentScope]

Added in version 10.17.

conversion_mode: Literal['implicit', 'explicit'] | None

‘implicit’, ‘explicit’ or None.

When set, this overrides the global mode set by pikepdf.set_object_conversion_mode() for objects owned by this Pdf, in every thread. None (the default) means defer to the global setting. The pikepdf.explicit_conversion() and pikepdf.implicit_conversion() context managers take precedence over this setting in the thread where they are active.

Objects copied into another Pdf take on that document’s mode. Unowned objects, such as a bare pikepdf.Dictionary(...), are not attached to any document, so they follow the thread-local or global setting instead.

Added in version 10.14.

Type:

Object conversion mode for this PDF

copy_foreign(h)

Copy an Object from a foreign Pdf and return a copy.

The object must be owned by a different Pdf from this one.

If the object has previously been copied, return a reference to the existing copy, even if that copy has been modified in the meantime.

If you want to copy a page from one PDF to another, use: pdf_b.pages[0] = pdf_a.pages[0]. That interface accounts for the complexity of copying pages.

This function is used to copy a pikepdf.Object that is owned by some other Pdf into this one. This is performs a deep (recursive) copy and preserves all references that may exist in the foreign object. For example, if

>>> object_a = pdf.copy_foreign(object_x)
>>> object_b = pdf.copy_foreign(object_y)
>>> object_c = pdf.copy_foreign(object_z)

and object_z is a shared descendant of both object_x and object_y in the foreign PDF, then object_c is a shared descendant of both object_a and object_b in this PDF. If object_x and object_y refer to the same object, then object_a and object_b are the same object.

It also copies all pikepdf.Stream objects. Since this may copy a large amount of data, it is not done implicitly. This function does not copy references to pages in the foreign PDF - it stops at page boundaries. Thus, if you use copy_foreign() on a table of contents (/Outlines dictionary), you may have to update references to pages.

Direct objects, including dictionaries, do not need copy_foreign(). pikepdf will automatically convert and construct them. A direct object must not refer to another Pdf, though: a pikepdf.Dictionary or pikepdf.Array that holds an indirect object of another Pdf can be built, but inserting it into this one raises pikepdf.ForeignObjectError, naming where the foreign object was found. Copy the indirect object with copy_foreign() first.

Note

pikepdf automatically treats incoming pages from a foreign PDF as foreign objects, so Pdf.pages does not require this treatment.

Changed in version 2.1: Error messages improved.

Parameters:

h (Object)

Return type:

Object

property docinfo: Dictionary

Access the (deprecated) document information dictionary.

The document information dictionary is a brief metadata record that can store some information about the origin of a PDF. It is deprecated and removed in the PDF 2.0 specification (not deprecated from the perspective of pikepdf). Use the .open_metadata() API instead, which will edit the modern (and unfortunately, more complicated) XMP metadata object and synchronize changes to the document information dictionary.

This property simplifies access to the actual document information dictionary and ensures that it is created correctly if it needs to be created.

A new, empty dictionary will be created if this property is accessed and dictionary does not exist or the wrong object type exists at that location. (This is to ensure that convenient code like pdf.docinfo[Name.Title] = "Title" will work when the dictionary does not exist at all.) This dictionary is always indirect.

You can delete the document information dictionary by deleting this property, del pdf.docinfo. Note that accessing the property after deleting it will re-create with a new, empty dictionary.

Changed in version 2.4: Added support for del pdf.docinfo.

Return type:

Dictionary

property encryption: pikepdf.models.encryption.EncryptionInfo

Report encryption information for this PDF.

Encryption settings may only be changed when a PDF is saved.

Return type:

pikepdf.models.encryption.EncryptionInfo

property extension_level: int

Returns the extension level of this PDF.

If a developer has released multiple extensions of a PDF version against the same base version value, they shall increase the extension level by 1. To be interpreted with pdf_version.

Return type:

int

property filename: str

The source filename of an existing PDF, when available.

When the Pdf was created from scratch, this returns ‘empty PDF’. When the Pdf was created from a stream, the return value is the word ‘stream’ followed by some information about the stream, if available.

Return type:

str

fix_dangling_references(force=...)

Remove or repair references to objects that do not exist.

A dangling reference is an indirect reference to an object that is not present in the file; per the PDF specification these resolve to null. Calling this method replaces such references so that the document’s object structure is internally consistent.

Parameters:

force (bool) – Normally this is a no-op if qpdf believes the references are already consistent. Pass True to force the check to run.

Return type:

None

Added in version 10.9.

flatten_annotations(mode='all')

Flattens all PDF annotations into regular PDF content.

Annotations are markup such as review comments, highlights, proofreading marks. User data entered into interactive form fields also counts as an annotation.

When annotations are flattened, they are “burned into” the regular content stream of the document and the fact that they were once annotations is deleted. This can be useful when preparing a document for printing, to ensure annotations are printed, or to finalize a form that should no longer be changed.

Parameters:

mode (str) – One of the strings 'all', 'screen', 'print'. If omitted or set to empty, treated as 'all'. 'screen' flattens all except those marked with the PDF flag /NoView. 'print' flattens only those marked for printing. Default is 'all'.

Return type:

None

Added in version 2.11.

static from_qpdf_json(filename_or_stream)

Create a new Pdf from qpdf JSON, as written by write_qpdf_json().

The JSON must be a complete representation of a PDF (qpdf --json-output version 2 or higher). To merge JSON into an existing Pdf, use update_from_qpdf_json() instead.

Parameters:

filename_or_stream (pathlib.Path | str | BinaryIO) – A filename or readable binary stream containing qpdf JSON.

Return type:

Pdf

Added in version 10.9.

generate_appearance_streams()

Generates appearance streams for AcroForm forms and form fields.

Appearance streams describe exactly how annotations and form fields should appear to the user. If omitted, the PDF viewer is free to render the annotations and form fields according to its own settings, as needed.

For every form field in the document, this generates appearance streams, subject to the limitations of qpdf’s ability to create appearance streams.

When invoked, this method will modify the Pdf in memory. It may be best to do this after the Pdf is opened, or before it is saved, because it may modify objects that the user does not expect to be modified.

If Pdf.Root.AcroForm.NeedAppearances is False or not present, no action is taken (because no appearance streams need to be generated). If True, the appearance streams are generated, and the NeedAppearances flag is set to False.

See:

https://github.com/qpdf/qpdf/blob/bf6b9ba1c681a6fac6d585c6262fb2778d4bb9d2/include/qpdf/QPDFFormFieldObjectHelper.hh#L216

Added in version 2.11.

Return type:

None

get_object(objgen: tuple[int, int]) → Object

Retrieve an object from the PDF.

Can be called with either a 2-tuple of (objid, gen) or two integers objid and gen.

get_warnings()
Return type:

list[str]

get_xref_table()

Return the Pdf’s cross-reference (xref) table.

Returns a mapping from (object_number, generation) to an pikepdf.XrefEntry describing where that object is stored. Unlike show_xref_table(), which only prints the table, this returns it as structured data suitable for forensic or investigatory purposes.

As with show_xref_table(), pikepdf recalculates the xref table when saving, so this reflects the table as read from the input file.

Added in version 10.9.

Return type:

dict[tuple[int, int], XrefEntry]

property is_encrypted: bool

Returns True if the PDF is encrypted.

For information about the nature of the encryption, see Pdf.encryption.

Return type:

bool

property is_linearized: bool

Returns True if the PDF is linearized.

Specifically returns True iff the file starts with a linearization parameter dictionary. Does no additional validation.

Return type:

bool

lock()

Context manager to hold the per-Pdf lock for compound operations.

Individual method calls are serialized automatically, but multi-step operations (e.g. read-modify-write on the same dictionary) are not atomic. Wrap such sequences in with pdf.lock(): to prevent interleaving. The lock is re-entrant.

Changed in version 10.18: The lock is now in force on GIL-enabled builds too. It was previously a no-op there.

While holding the lock, use only this Pdf. If two threads each hold the lock of one Pdf and then need the other’s, pikepdf raises RuntimeError in one of them rather than letting both wait for ever. See Callbacks.

Return type:

contextlib.AbstractContextManager[None]

make_indirect(obj)

Attach an object to the Pdf as an indirect object.

Direct objects appear inline in the binary encoding of the PDF. Indirect objects appear inline as references (in English, “look up object 4 generation 0”) and then read from another location in the file. The PDF specification requires that certain objects are indirect - consult the PDF specification to confirm.

Generally a resource that is shared should be attached as an indirect object. pikepdf.Stream objects are always indirect, and creating them will automatically attach it to the Pdf.

Parameters:

obj (TObj) – The object to attach. If this a pikepdf.Object, it will be attached as an indirect object. If it is any other Python object, we attempt conversion to pikepdf.Object attach the result. If the object is already an indirect object, a reference to the existing object is returned. If the pikepdf.Object is owned by a different Pdf, an exception is raised; use pikepdf.Object.copy_foreign() instead.

Returns:

The indirect object. An array, dictionary or stream is made indirect in place, so obj itself becomes that indirect object. A scalar such as a pikepdf.Name is copied first, so obj stays direct and can still be hashed or reused in another Pdf; use the return value.

Return type:

TObj

Changed in version 10.14: Scalars are copied rather than made indirect in place.

make_stream(data, d=None, **kwargs)

Create a new pikepdf.Stream object that is attached to this PDF.

See:

pikepdf.Stream.__new__()

Parameters:
  • data (bytes)

  • d (Any)

  • kwargs (Any)

Return type:

Stream

classmethod new(*, conversion_mode=None)

Create a new, empty PDF.

This is best when you are constructing a PDF from scratch.

In most cases, if you are working from an existing PDF, you should open the PDF using pikepdf.Pdf.open() and transform it, instead of a creating a new one, to preserve metadata and structural information. For example, if you want to split a PDF into two parts, you should open the PDF and transform it into the desired parts, rather than creating a new PDF and copying pages into it.

Parameters:

conversion_mode (Literal['implicit', 'explicit'] | None)

Return type:

Pdf

property objects: _ObjectList

Return an iterable list of all objects in the PDF.

After deleting content from a PDF such as pages, objects related to that page, such as images on the page, may still be present in this list.

Return type:

_ObjectList

static open(filename_or_stream, *, password='', hex_password=False, ignore_xref_streams=False, suppress_warnings=True, attempt_recovery=True, inherit_page_attributes=True, access_mode=AccessMode.default, allow_overwriting_input=False, conversion_mode=None)

Open an existing file at filename_or_stream.

If filename_or_stream is path-like, the file will be opened for reading. The file should not be modified by another process while it is open in pikepdf, or undefined behavior may occur. This is because the file may be lazily loaded. When .close() is called, the file handle that pikepdf opened will be closed.

If filename_or_stream is stream, the data will be accessed as a readable binary stream, from the current position in that stream. When pdf = Pdf.open(stream) is called on a stream, pikepdf will not call stream.close(); the caller must call both pdf.close() and stream.close(), in that order, when the Pdf and stream are no longer needed. Use with-blocks will call .close() automatically.

Whether a file or stream is opened, you must ensure that the data is not modified by another thread or process, or undefined behavior will occur. You also may not overwrite the input file using .save(), unless allow_overwriting_input=True. This is because data may be lazily loaded.

If you intend to edit the file in place, or want to protect the file against modification by another process, use allow_overwriting_input=True. This tells pikepdf to make a private copy of the file.

Any changes to the file must be persisted by using .save().

Examples

>>> with Pdf.open("test.pdf") as pdf:
...     pass
>>> pdf = Pdf.open("test.pdf", password="rosebud")
Parameters:
  • filename_or_stream (pathlib.Path | str | BinaryIO) – Filename or Python readable and seekable file stream of PDF to open.

  • password (str | bytes) – User or owner password to open an encrypted PDF. If the type of this parameter is str it will be encoded as UTF-8. If the type is bytes it will be saved verbatim. Passwords are always padded or truncated to 32 bytes internally. Use ASCII passwords for maximum compatibility.

  • hex_password (bool) – If True, interpret the password as a hex-encoded version of the exact encryption key to use, without performing the normal key computation. Useful in forensics.

  • ignore_xref_streams (bool) – If True, ignore cross-reference streams. See qpdf documentation.

  • suppress_warnings (bool) – If True (default), warnings are not printed to stderr. Use pikepdf.Pdf.get_warnings() to retrieve warnings.

  • attempt_recovery (bool) – If True (default), attempt to recover from PDF parsing errors.

  • inherit_page_attributes (bool) – If True (the default), push attributes that are set on a group of pages in the /Pages tree (/MediaBox, /CropBox, /Resources and /Rotate) down onto each individual page, so that every page carries its own copy. This simplifies most PDF work, since these attributes can then be read directly from a page. If False, pikepdf leaves the page tree as stored and does not push inherited attributes down, so a page may lack these keys on its own dictionary; in that case use the managed accessors (mediabox, rotation, etc.), which resolve inheritance, rather than raw access, which may find the key absent. Disable this when you need to inspect or construct the page tree exactly as stored – for example, when building a test fixture that exercises attribute inheritance.

  • access_mode (AccessMode) – If .default, pikepdf will decide how to access the file. Currently, it will always selected stream access. To attempt memory mapping and fallback to stream if memory mapping failed, use .mmap. Use .mmap_only to require memory mapping or fail (this is expected to only be useful for testing). Applications should be prepared to handle the SIGBUS signal on POSIX in the event that the file is successfully mapped but later goes away. With stream access, a file that pikepdf opened itself from a filename is read directly through its file descriptor, while a stream object you supply is only ever read by calling its methods.

  • allow_overwriting_input (bool) – If True, allows calling .save() to overwrite the input file. This is performed by loading the entire input file into memory at open time; this will use more memory and may recent performance especially when the opened file will not be modified.

  • conversion_mode (Literal['implicit', 'explicit'] | None) –

    If given, sets this document’s object conversion mode to 'implicit' or 'explicit', overriding the global setting for objects owned by this Pdf. See pikepdf.Pdf.conversion_mode.

    Added in version 10.14.

Raises:
  • pikepdf.PasswordError – If the password failed to open the file.

  • pikepdf.PdfError – If for other reasons we could not open the file.

  • TypeError – If the type of filename_or_stream is not usable.

  • FileNotFoundError – If the file was not found.

Return type:

Pdf

Note

When filename_or_stream is a stream and the stream is located on a network, pikepdf assumes that the stream using buffering and read caches to achieve reasonable performance. Streams that fetch data over a network in response to every read or seek request, no matter how small, will perform poorly. It may be easier to download a PDF from network to temporary local storage (such as io.BytesIO), manipulate it, and then re-upload it.

Changed in version 3.0: Keyword arguments now mandatory for everything except the first argument.

open_metadata(set_pikepdf_as_editor=True, update_docinfo=True, strict=False)

Open the PDF’s XMP metadata for editing.

There is no .close() function on the metadata object, since this is intended to be used inside a with block only.

For historical reasons, certain parts of PDF metadata are stored in two different locations and formats. This feature coordinates edits so that both types of metadata are updated consistently and “atomically” (assuming single threaded access). It operates on the Pdf in memory, not any file on disk. To persist metadata changes, you must still use Pdf.save().

Example

>>> pdf = pikepdf.Pdf.open("../tests/resources/graph.pdf")
>>> with pdf.open_metadata() as meta:
...     meta['dc:title'] = 'Set the Dublic Core Title'
...     meta['dc:description'] = 'Put the Abstract here'
Parameters:
  • set_pikepdf_as_editor (bool) – Automatically update the metadata pdf:Producer to show that this version of pikepdf is the most recent software to modify the metadata, and xmp:MetadataDate to timestamp the update. Recommended, except for testing.

  • update_docinfo (bool) – Update the standard fields of DocumentInfo (the old PDF metadata dictionary) to match the corresponding XMP fields. The mapping is described in PdfMetadata.DOCINFO_MAPPING. Nonstandard DocumentInfo fields and XMP metadata fields with no DocumentInfo equivalent are ignored.

  • strict (bool) – If False (the default), we aggressively attempt to recover from any parse errors in XMP, and if that fails we overwrite the XMP with an empty XMP record. If True, raise errors when either metadata bytes are not valid and well-formed XMP (and thus, XML). Some trivial cases that are equivalent to empty or incomplete “XMP skeletons” are never treated as errors, and always replaced with a proper empty XMP block. Certain errors may be logged.

Return type:

pikepdf.models.metadata.PdfMetadata

open_outline(max_depth=15, strict=False)

Open the PDF outline (“bookmarks”) for editing.

Recommend for use in a with block. Changes are committed to the PDF when the block exits. (The Pdf must still be opened.)

Example

>>> pdf = pikepdf.open('../tests/resources/outlines.pdf')
>>> with pdf.open_outline() as outline:
...     outline.root.insert(0, pikepdf.OutlineItem('Intro', 0))
Parameters:
  • max_depth (int) – Maximum recursion depth of the outline to be imported and re-written to the document. 0 means only considering the root level, 1 the first-level sub-outline of each root element, and so on. Items beyond this depth will be silently ignored. Default is 15.

  • strict (bool) – When False (the default), pikepdf quietly corrects minor structural problems in the outline where the correct repair is known, recovering the valid parts of the document outline without raising an exception. For example, a missing required /Title is treated as an empty string; a structural error such as a reference loop cancels processing of further nodes on that level; and outline objects that have been accidentally duplicated are reproduced as new objects. When set to True, any such structural problem raises an OutlineStructureError.

Return type:

pikepdf.models.outlines.Outline

property owner_password_matched: bool

Returns True if the owner password matched when the Pdf was opened.

It is possible for both the user and owner passwords to match.

Added in version 2.10.

Return type:

bool

property pages: PageList

Returns the list of pages.

Return type:

PageList

property pdf_version: str

The version of the PDF specification used for this file, such as ‘1.7’.

More precise information about the PDF version can be opened from the Pdf’s XMP metadata.

Return type:

str

remove_unreferenced_resources()

Remove from /Resources any object not referenced in page’s contents.

PDF pages may share resource dictionaries with other pages. If pikepdf is used for page splitting, pages may reference resources in their /Resources dictionary that are not actually required. This purges all unnecessary resource entries.

For clarity, if all references to any type of object are removed, that object will be excluded from the output PDF on save. (Conversely, only objects that are discoverable from the PDF’s root object are included.) This function removes objects that are referenced from the page /Resources dictionary, but never called for in the content stream, making them unnecessary.

Suggested before saving, if content streams or /Resources dictionaries are edited.

Return type:

None

property root: Object

The /Root object of the PDF.

Return type:

Object

save(filename_or_stream=None, *, preserve_pdfa=True, min_version='', force_version='', fix_metadata_version=True, compress_streams=True, stream_decode_level=None, object_stream_mode=ObjectStreamMode.preserve, normalize_content=False, linearize=False, qdf=False, progress=None, encryption=None, recompress_flate=False, deterministic_id=False, static_id=False)

Save all modifications to this pikepdf.Pdf.

Parameters:
  • filename_or_stream (pathlib.Path | str | BinaryIO | None) – Where to write the output. If a file exists in this location it will be overwritten. If the file was opened with allow_overwriting_input=True, then it is permitted to overwrite the original file, and this parameter may be omitted to implicitly use the original filename. Otherwise, the filename may not be the same as the input file, as overwriting the input file would corrupt data since pikepdf using lazy loading.

  • preserve_pdfa (bool) – Ensures that the file is generated in a manner compliant with PDF/A and other stricter variants. This should be True, the default, in most cases.

  • min_version (str | tuple[str, int]) – Sets the minimum version of PDF specification that should be required. If left alone qpdf will decide. If a tuple, the second element is an integer, the extension level. If the version number is not a valid format, qpdf will decide what to do.

  • force_version (str | tuple[str, int]) – Override the version recommend by qpdf, potentially creating an invalid file that does not display in old versions. See qpdf manual for details. If a tuple, the second element is an integer, the extension level.

  • fix_metadata_version (bool) – If True (default) and the XMP metadata contains the optional PDF version field, ensure the version in metadata is correct. If the XMP metadata does not contain a PDF version field, none will be added. To ensure that the field is added, edit the metadata and insert a placeholder value in pdf:PDFVersion. If XMP metadata does not exist, it will not be created regardless of the value of this argument.

  • object_stream_mode (ObjectStreamMode) – disable prevents the use of object streams. preserve keeps object streams from the input file. generate uses object streams wherever possible, creating the smallest files but requiring PDF 1.5+.

  • compress_streams (bool) –

    Enables or disables the compression of uncompressed stream objects. By default this is set to True, and the only reason to set it to False is for debugging or inspecting PDF contents.

    When enabled, uncompressed stream objects will be compressed whether they were uncompressed in the PDF when it was opened, or when the user creates new pikepdf.Stream objects attached to the PDF. Stream objects can also be created indirectly, such as when content from another PDF is merged into the one being saved.

    Only stream objects that have no compression will be compressed when this object is set. If the object is compressed, compression will be preserved.

    Setting compress_streams=False does not trigger decompression unless decompression is specifically requested by setting both compress_streams=False and stream_decode_level to the desired decode level (e.g. .generalized will decompress most non-image content).

    This option does not trigger recompression of existing compressed streams. For that, use recompress_flate.

    The XMP metadata stream object, if present, is never compressed, to facilitate metadata reading by parsers that don’t understand the full structure of PDF.

  • stream_decode_level (StreamDecodeLevel | None) – Specifies how to encode stream objects. See documentation for pikepdf.StreamDecodeLevel.

  • recompress_flate (bool) – When disabled (the default), qpdf does not uncompress and recompress streams compressed with the Flate compression algorithm. If True, pikepdf will instruct qpdf to do this, which may be useful if recompressing streams to a higher compression level.

  • normalize_content (bool) – Enables parsing and reformatting the content stream within PDFs. This may debugging PDFs easier.

  • linearize (bool) – Enables creating linear or “fast web view”, where the file’s contents are organized sequentially so that a viewer can begin rendering before it has the whole file. As a drawback, it tends to make files larger.

  • qdf (bool) – Save output QDF mode. QDF mode is a special output mode in qpdf to allow editing of PDFs in a text editor. Use the program fix-qdf to fix convert back to a standard PDF.

  • progress (collections.abc.Callable[[int], None] | None) – Specify a callback function that is called as the PDF is written. The function will be called with an integer between 0-100 as the sole parameter, the progress percentage. This function may not access or modify the PDF while it is being written, or data corruption will almost certainly occur. The same goes for the write method of a stream being saved to. See Callbacks.

  • encryption (pikepdf.models.encryption.Encryption | bool | None) – If False or omitted, existing encryption will be removed. If True encryption settings are copied from the originating PDF. Alternately, an Encryption object may be provided that sets the parameters for new encryption.

  • deterministic_id (bool) – Compute the document /ID from a digest of the output file’s contents and /Info strings, without the current time. Saving the same document the same way produces the same /ID (and, with the same qpdf version, the same bytes), which is useful for reproducible builds and for caching or deduplicating output without depending on the clock. Documents with different content still receive different /ID values, so this is safe for production use. At a small runtime cost. Cannot be combined with encryption. Different qpdf versions may produce slightly different output, and hence different /ID values, for the same input.

  • static_id (bool) –

    Set the document /ID to a fixed dummy value that is identical in every PDF that pikepdf writes.

    Warning

    For testing and debugging only. Never use in production. The PDF specification expects /ID to identify a document uniquely; with static_id every document shares the same /ID, which can confuse software that uses it to track, cache or match documents. For reproducible production output, use deterministic_id instead.

    A typical use is a test suite that compares saved PDFs byte-for-byte. Takes precedence over deterministic_id.

Return type:

None

When neither deterministic_id nor static_id is set, the /ID is generated the conventional way described in the PDF specification: a hash that incorporates the current time, so every save produces a new value. In all three modes, if the document already has an /ID, its first element is preserved (as the specification requires) and only the second element is replaced.

Raises:
Parameters:
  • filename_or_stream (pathlib.Path | str | BinaryIO | None)

  • preserve_pdfa (bool)

  • min_version (str | tuple[str, int])

  • force_version (str | tuple[str, int])

  • fix_metadata_version (bool)

  • compress_streams (bool)

  • stream_decode_level (StreamDecodeLevel | None)

  • object_stream_mode (ObjectStreamMode)

  • normalize_content (bool)

  • linearize (bool)

  • qdf (bool)

  • progress (collections.abc.Callable[[int], None] | None)

  • encryption (pikepdf.models.encryption.Encryption | bool | None)

  • recompress_flate (bool)

  • deterministic_id (bool)

  • static_id (bool)

Return type:

None

You may call .save() multiple times with different parameters to generate different versions of a file, and you may continue to modify the file after saving it. .save() does not modify the Pdf object in memory, except possibly by updating the XMP metadata version with fix_metadata_version.

Note

pikepdf.Pdf.remove_unreferenced_resources() before saving may eliminate unnecessary resources from the output file if there are any objects (such as images) that are referenced in a page’s Resources dictionary but never called in the page’s content stream.

Note

pikepdf can read PDFs with incremental updates, but always coalesces any incremental updates into a single non-incremental PDF file when saving.

Note

If filename_or_stream is a stream and the process is interrupted during writing, the stream may be left in a corrupt state. It is the responsibility of the caller to manage the stream in this case.

Changed in version 2.7: Added recompress_flate.

Changed in version 3.0: Keyword arguments now mandatory for everything except the first argument.

Changed in version 8.1: If filename_or_stream is a filename and that file exists, the new file is written to a temporary file in the same directory and then moved into place. This prevents the existing destination file from being corrupted if the process is interrupted during writing; previously, corrupting the destination file was possible. If no file exists at the destination, output is written directly to the destination, but the destination will be deleted if errors occur during writing. Prior to 8.1, the file was always written directly to the destination, which could result in a corrupt destination file if the process was interrupted during writing.

Changed in version 9.1: When opened with allow_overwriting_input=True, we now attempt to restore the original file permissions, ownership and creation time. The modified time is always set to the time of saving. An unusual umask or other settings changes still cause a failure to restore permissions.

show_xref_table()

Pretty-print the Pdf’s xref (cross-reference table).

The xref table will be written to the pikepdf._core module’s logger with a logging level of logging.INFO. You may need to adjust the logging level to see the output.

This function is mainly for debugging or curiosity. In practice, pikepdf does not trust the xref table; it instead reads the PDF to determine the position of objects, and recalculates the xref table when a PDF is saved. One could use to locate objects within a PDF using a hex editor, assuming the PDF is well-formed.

Return type:

None

property trailer: Object

Provides access to the PDF trailer object.

See {{ pdfrm }} section 7.5.5. Generally speaking, the trailer should not be modified with pikepdf, and modifying it may not work. Some of the values in the trailer are automatically changed when a file is saved.

Return type:

Object

update_from_qpdf_json(filename_or_stream)

Update this Pdf from qpdf JSON, as written by write_qpdf_json().

Objects present in this Pdf but absent from the JSON are left unchanged. See from_qpdf_json() to create a new Pdf instead.

Parameters:

filename_or_stream (pathlib.Path | str | BinaryIO) – A filename or readable binary stream containing qpdf JSON.

Return type:

None

Added in version 10.9.

property user_password_matched: bool

Returns True if the user password matched when the Pdf was opened.

It is possible for both the user and owner passwords to match.

Added in version 2.10.

Return type:

bool

write_qpdf_json(filename_or_stream, *, decode_level=..., json_stream_data=..., file_prefix=...)

Write this PDF as qpdf JSON (the qpdf --json-output format, v2).

This is the whole-document JSON serialization, distinct from pikepdf.Object.to_json() which serializes a single object. The output can be read back with from_qpdf_json().

Parameters:
  • filename_or_stream (pathlib.Path | str | BinaryIO) – A filename or writable binary stream.

  • decode_level (StreamDecodeLevel) – How much to decode (uncompress) stream data in the JSON. Use StreamDecodeLevel.none to preserve stream data exactly.

  • json_stream_data (JSONStreamData) – How stream data is represented; see pikepdf.JSONStreamData.

  • file_prefix (str) – Required when json_stream_data is JSONStreamData.file; each stream is written to a file named {file_prefix}-{object_number}. If not given and a filename was supplied, the filename is used as the prefix.

Return type:

None

Added in version 10.9.

pikepdf.open()

Alias for pikepdf.Pdf.open().

pikepdf.new()

Alias for pikepdf.Pdf.new().

Access modes

class pikepdf.ObjectStreamMode

Options for saving object streams within PDFs.

Object streams are more a compact way of saving certain types of data that was added in PDF 1.5. All modern PDF viewers support object streams, but some third party tools and libraries cannot read them.

disable: ...

Disable the use of object streams.

If any object streams exist in the file, remove them when the file is saved.

generate: ...

Preserve any existing object streams in the original file.

This is the default behavior.

preserve: ...

Generate object streams.

class pikepdf.StreamDecodeLevel

Options for decoding streams within PDFs.

all: ...

In addition to generalized and non-lossy specialized filters, supported lossy compression filters will be applied. At present, this includes DCTDecode (JPEG) compression. Note that compressing the resulting data with DCTDecode again will accumulate loss, so avoid multiple compression and decompression cycles. This is mostly useful for (low-level) retrieving image data; see pikepdf.PdfImage for the preferred method.

generalized: ...

This is the default. libqpdf will apply LZWDecode, ASCII85Decode, ASCIIHexDecode, and FlateDecode filters on the input. When saved with compress_streams=True, the default, the effect of this is that streams filtered with these older and less efficient filters will be recompressed with the Flate filter. As a special case, if a stream is already compressed with FlateDecode and compress_streams=True, the original compressed data will be preserved.

none: ...

Do not attempt to apply any filters. Streams remain as they appear in the original file. Note that uncompressed streams may still be compressed on output. You can disable that by saving with .save(..., compress_streams=False).

specialized: ...

In addition to uncompressing the generalized compression formats, supported non-lossy specialized compression will also be decoded. At present, this includes the RunLengthDecode filter.

class pikepdf.Encryption

Specify the encryption settings to apply when a PDF is saved.

R: Literal[2, 3, 4, 5, 6] = 6

Select the security handler algorithm to use. Choose from: 2, 3, 4 or 6. By default, the highest version of is selected (6). 5 is a deprecated algorithm that should not be used.

aes: bool = True

If True, request the AES algorithm. If False, use RC4. If omitted, AES is selected whenever possible (R >= 4).

allow: Permissions

The permissions to set. If omitted, all permissions are granted to the user.

metadata: bool = True

If True, also encrypt the PDF metadata. If False, metadata is not encrypted. Reading document metadata without decryption may be desirable in some cases. Requires aes=True. If omitted, metadata is encrypted whenever possible.

owner: str = ''

The owner password to use. This allows full control of the file. If blank, the PDF will be encrypted and present as “(SECURED)” in PDF viewers. If the owner password is blank, the user password should be as well.

user: str = ''

The user password to use. With this password, some restrictions will be imposed by a typical PDF reader. If blank, the PDF can be opened by anyone, but only modified as allowed by the permissions in allow.

Explicit conversion mode

pikepdf.explicit_conversion()

Context manager for explicit conversion mode.

Within this context, PDF scalar values will be returned as pikepdf.Integer, pikepdf.Boolean, and pikepdf.Real objects instead of being automatically converted to Python native types.

This context manager is thread-local: it only affects the current thread and takes precedence over the global setting from set_object_conversion_mode(). Nested context managers are supported.

Example

>>> with pikepdf.explicit_conversion():
...     count = pikepdf.Dictionary(Count=5).Count
...     isinstance(count, pikepdf.Integer)
True

Added in version 10.1.

Changed in version 10.2: Now thread-local and takes precedence over global setting.

Return type:

collections.abc.Iterator[None]

pikepdf.implicit_conversion()

Context manager for implicit conversion mode.

Within this context, PDF scalar values are automatically converted to Python native types: int, bool and decimal.Decimal. This is pikepdf’s legacy behavior.

This context manager is thread-local: it only affects the current thread, and it takes precedence over both a document’s pikepdf.Pdf.conversion_mode and the global setting from set_object_conversion_mode(). It may be nested with explicit_conversion() in either order.

Example

>>> with pikepdf.explicit_conversion():
...     with pikepdf.implicit_conversion():
...         isinstance(pikepdf.Dictionary(Value=42).Value, int)
True

Added in version 10.14.

Return type:

collections.abc.Iterator[None]

pikepdf.unbox(value)

Return a PDF scalar as the native Python value implicit mode would give.

Implicit conversion mode already hands back int, bool or Decimal for a PDF number; explicit mode hands back a pikepdf.Integer, pikepdf.Boolean or pikepdf.Real. Code that computes with a value rather than storing it needs the native form in both modes, and unlike as_int() and friends this does not require knowing which of the three it is.

Integer becomes int, Boolean becomes bool and Real becomes decimal.Decimal. Anything else – a native Python value, None, a Name, String, Array, Dictionary or Stream – is returned unchanged, so unbox can be applied to a value read in either mode.

Arithmetic and comparisons on Integer and Real already produce native results, so unbox is needed only where Python offers no protocol for a foreign number: isinstance checks, is True, decimal.Decimal construction, JSON serialization, and returning a value from a function documented to give a native type.

When the expected type is known, prefer pikepdf.as_int() and friends, which also accept a value read in either mode but return default for a value of the wrong type instead of passing it through.

Example

>>> with pikepdf.explicit_conversion():
...     d = pikepdf.Dictionary(MaxLen=12, Marked=True)
...     pikepdf.unbox(d.MaxLen)
12
>>> pikepdf.unbox(d.Marked) is True
True

Added in version 10.14.

Parameters:

value (Any)

Return type:

Any

pikepdf.as_int(value: Any, default: None = None, *, coerce: bool = False) → int | None
pikepdf.as_bool(value: Any, default: None = None, *, coerce: bool = False) → bool | None
pikepdf.as_float(value: Any, default: None = None, *, coerce: bool = False) → float | None
pikepdf.as_decimal(value: Any, default: None = None, *, coerce: bool = False) → decimal.Decimal | None
pikepdf.as_dict(value: Any, default: None = None) → _ObjectMapping | None
pikepdf.as_list(value: Any, default: None = None) → _ObjectList | None
pikepdf.as_str(value: Any, default: None = None) → str | None
pikepdf.as_bytes(value: Any, default: None = None) → bytes | None
pikepdf.set_object_conversion_mode(mode)

Set global object conversion mode.

This controls how PDF scalar values (integers, booleans, reals) are returned when accessing PDF objects.

Parameters:

mode (Literal['implicit', 'explicit']) – 'implicit' (the default) converts PDF integers to Python int, booleans to bool, and reals to Decimal; this is the legacy behavior. 'explicit' returns PDF scalars as pikepdf.Integer, pikepdf.Boolean, and pikepdf.Real objects, which enables better type safety and static type checking.

Return type:

None

Example

>>> pikepdf.set_object_conversion_mode('explicit')
>>> count = pikepdf.Dictionary(Count=5).Count
>>> isinstance(count, pikepdf.Integer)  # True in explicit mode
True
>>> int(count)  # Convert to Python int
5
>>> pikepdf.set_object_conversion_mode('implicit')  # Restore the default

Added in version 10.1.

Changed in version 10.14: Raises ValueError if mode is not 'implicit' or 'explicit'. Previously any value other than 'explicit' was silently treated as 'implicit'.

pikepdf.get_object_conversion_mode(pdf=None)

Get current effective object conversion mode.

This returns the mode that is currently in effect for the calling thread, taking into account the global setting, any active explicit_conversion() or implicit_conversion() context managers, and, if pdf is given, that document’s own conversion mode.

Parameters:

pdf (pikepdf.Pdf | None) – If given, report the mode that applies to objects owned by this pikepdf.Pdf. The resolution order is context manager, then the document’s pikepdf.Pdf.conversion_mode, then the global setting.

Returns:

'implicit' or 'explicit'.

Return type:

The current effective conversion mode

Added in version 10.1.

Changed in version 10.2: Now returns the effective mode, including thread-local context manager state.

Changed in version 10.14: Accepts an optional pdf argument.

class pikepdf.Integer

A PDF integer object.

In explicit conversion mode, PDF integers are returned as this type instead of being automatically converted to Python int.

Supports int() conversion, indexing operations (via __index__), arithmetic, and ordering comparisons (<, <=, >, >=) against Python int, float, bool, Decimal, Integer and Real, as well as round(), divmod(), math.floor() and the like, and format specs such as f'{x:d}'. Arithmetic returns a native Python number, never a pikepdf object: int with an int, bool or Integer operand, float with a float, and Decimal with a Decimal or Real. A number computed from a document is not itself in the document, so there is nothing to box; assign the result to a dictionary or array to store it.

Added in version 10.1.

Changed in version 10.14: Added ordering comparisons, and arithmetic with Integer, Real, Decimal and bool operands.

Changed in version 10.14.1: Added round(), divmod(), math.trunc(), math.floor(), math.ceil() and format specs.

object_type: ObjectType
class pikepdf.Boolean

A PDF boolean object.

In explicit conversion mode, PDF booleans are returned as this type instead of being automatically converted to Python bool.

Supports bool() conversion via __bool__.

Added in version 10.1.

object_type: ObjectType
class pikepdf.Real

A PDF real (floating-point) object.

In explicit conversion mode, PDF reals are returned as this type instead of being automatically converted to Python Decimal.

Supports float() and int() conversion, arithmetic, and ordering comparisons (<, <=, >, >=) against Python int, float, bool, Decimal, Integer and Real, as well as round(), divmod(), math.floor() and the like, and format specs such as f'{x:.2f}'. int() truncates, as it does for a Decimal. Arithmetic and comparisons use the exact decimal value of the PDF token, as as_decimal() returns it, and arithmetic returns a native Python number, never a pikepdf object: a Decimal, except with a float operand, which Decimal would refuse, where the result is a float. Use as_decimal() for lossless conversion.

Added in version 10.1.

Changed in version 10.14: Added ordering comparisons, and arithmetic with Integer, Real, Decimal, int and bool operands.

Changed in version 10.14.1: int() truncates instead of raising TypeError. Added round(), divmod(), math.trunc(), math.floor(), math.ceil() and format specs.

object_type: ObjectType

Object construction

class pikepdf.Object
__abs__()
Return type:

int | decimal.Decimal

__add__(other, /)
Parameters:

other (_Number)

Return type:

_NumberResult

__bool__()
Return type:

bool

__bytes__()
Return type:

bytes

__ceil__()
Return type:

int

__contains__(obj: Object | str, /) → bool
__copy__()
Return type:

Object

__delattr__(name, /)
Parameters:

name (str)

Return type:

None

__delitem__(name: str | Name | int, /) → None
__dir__()
Return type:

list[str]

__divmod__(other, /)
Parameters:

other (_Number)

Return type:

tuple[_NumberResult, _NumberResult]

__eq__(other, /)
Parameters:

other (Any)

Return type:

bool

__float__()
Return type:

float

__floor__()
Return type:

int

__floordiv__(other, /)
Parameters:

other (_Number)

Return type:

_NumberResult

__format__(format_spec, /)
Parameters:

format_spec (str)

Return type:

str

__ge__(other, /)
Parameters:

other (_Number)

Return type:

bool

__getattr__(name, /)
Parameters:

name (str)

Return type:

Object

__getitem__(name: str | Name | int, /) → Object
__gt__(other, /)
Parameters:

other (_Number)

Return type:

bool

__hash__()
Return type:

int

__index__()
Return type:

int

__int__()
Return type:

int

__iter__()
Return type:

collections.abc.Iterator[Object]

__le__(other, /)
Parameters:

other (_Number)

Return type:

bool

__len__()
Return type:

int

__lt__(other, /)
Parameters:

other (_Number)

Return type:

bool

__mod__(other, /)
Parameters:

other (_Number)

Return type:

_NumberResult

__mul__(other, /)
Parameters:

other (_Number)

Return type:

_NumberResult

__neg__()
Return type:

int | decimal.Decimal

__pos__()
Return type:

int | decimal.Decimal

__pow__(other, /)
Parameters:

other (_Number)

Return type:

_NumberResult

__radd__(other, /)
Parameters:

other (_Number)

Return type:

_NumberResult

__rdivmod__(other, /)
Parameters:

other (_Number)

Return type:

tuple[_NumberResult, _NumberResult]

__rfloordiv__(other, /)
Parameters:

other (_Number)

Return type:

_NumberResult

__rmod__(other, /)
Parameters:

other (_Number)

Return type:

_NumberResult

__rmul__(other, /)
Parameters:

other (_Number)

Return type:

_NumberResult

__round__(ndigits: None = None, /) → int
__rpow__(other, /)
Parameters:

other (_Number)

Return type:

_NumberResult

__rsub__(other, /)
Parameters:

other (_Number)

Return type:

_NumberResult

__rtruediv__(other, /)
Parameters:

other (_Number)

Return type:

float | decimal.Decimal

__setattr__(name, value, /)
Parameters:
  • name (str)

  • value (Any)

Return type:

None

__setitem__(name: str | Name | int, value: Any, /) → None
__sub__(other, /)
Parameters:

other (_Number)

Return type:

_NumberResult

__truediv__(other, /)
Parameters:

other (_Number)

Return type:

float | decimal.Decimal

__trunc__()
Return type:

int

append(value, /)

Append another object to an array; fails if the object is not an array.

Parameters:

value (Any)

Return type:

None

as_bool(*, coerce: bool = False) → bool
as_bytes() → bytes
as_decimal(*, coerce: bool = False) → decimal.Decimal
as_dict() → _ObjectMapping
as_float(*, coerce: bool = False) → float
as_int(*, coerce: bool = False) → int
as_list() → _ObjectList
as_str() → str
clear()

Remove all items from the array.

Return type:

None

copy()

Create a shallow copy of the object.

Return type:

Object

count(value, /)

Return the number of items in the array equal to value.

Parameters:

value (Any)

Return type:

int

emplace(other, retain=...)

Copy all items from other without making a new object.

Particularly when working with pages, it may be desirable to remove all of the existing page’s contents and emplace (insert) a new page on top of it, in a way that preserves all links and references to the original page. (Or similarly, for other Dictionary objects in a PDF.)

Any Dictionary keys in the iterable retain are preserved. By default, /Parent is retained.

When a page is assigned (pdf.pages[0] = new_page), only the application knows if references to the original the original page are still valid. For example, a PDF optimizer might restructure a page object into another visually similar one, and references would be valid; but for a program that reorganizes page contents such as a N-up compositor, references may not be valid anymore.

This method takes precautions to ensure that child objects in common with self and other are not inadvertently deleted.

Example

>>> pdf = pikepdf.Pdf.open('../tests/resources/fourpages.pdf')
>>> pdf.pages[0].objgen
(3, 0)
>>> pdf.pages[0].emplace(pdf.pages[1])
>>> pdf.pages[0].objgen
(3, 0)
>>> # Same object

Changed in version 2.11.1: Added the retain argument.

Parameters:
  • other (Object)

  • retain (collections.abc.Iterable[Name])

Return type:

None

extend(iter, /)

Extend a pikepdf.Array with an iterable of other pikepdf.Object.

Parameters:

iter (collections.abc.Iterable[Object])

Return type:

None

get(key: int | str | Name, /) → Object | None
get_bool(key: str | Name | NamePath, *, coerce: bool = False) → bool | None
get_bytes(key: str | Name | NamePath) → bytes | None
get_decimal(key: str | Name | NamePath, *, coerce: bool = False) → decimal.Decimal | None
get_dict(key: str | Name | NamePath) → _ObjectMapping | None
get_float(key: str | Name | NamePath, *, coerce: bool = False) → float | None
get_int(key: str | Name | NamePath, *, coerce: bool = False) → int | None
get_list(key: str | Name | NamePath) → _ObjectList | None
get_raw(key: str | Name, /) → Object | None
get_raw_stream_buffer()

Return a buffer protocol buffer describing the raw, encoded stream.

Return type:

Buffer

get_str(key: str | Name | NamePath) → str | None
get_stream_buffer(decode_level=...)

Return a buffer protocol buffer describing the decoded stream.

Parameters:

decode_level (StreamDecodeLevel)

Return type:

Buffer

property images: _ObjectMapping
Return type:

_ObjectMapping

index(value, /)

Return the index of the first item equal to value.

Parameters:

value (Any)

Return type:

int

insert(index, value, /)

Insert an object before the given index (Python list.insert semantics).

Parameters:
  • index (int)

  • value (Any)

Return type:

None

property is_indirect: bool

Returns True if the object is an indirect object.

Return type:

bool

is_owned_by(possible_owner)

Test if this object is owned by the indicated possible_owner.

Parameters:

possible_owner (Pdf)

Return type:

bool

property is_rectangle: bool

Returns True if the object is a rectangle (an array of 4 numbers).

Return type:

bool

is_same_object_as(other)

Test if this is the same object as other, not merely an equal one.

Two references to one indirect object are the same object: a change made through either is seen through the other. Two dictionaries with the same contents are equal (==) but are not the same object.

None of Python’s own tests answers this question. is compares the Python wrappers, and pikepdf creates a new wrapper each time an object is read, so pdf.Root is pdf.Root is False. == compares contents. Comparing objgen fails for direct objects, which all report (0, 0), and for objects in different pikepdf.Pdf, whose numbers often coincide.

other may be a pikepdf.Object or a helper such as pikepdf.Page, which counts as the object it wraps. Any other value is not the same object, including the Python numbers and booleans that pikepdf converts PDF scalars to. This test is meant for dictionaries, arrays and streams; for names, strings and numbers, compare values with ==.

To test one object against many, such as the objects already visited while following references, use pikepdf.ObjectSet.

Added in version 10.17.

Parameters:

other (object)

Return type:

bool

items()
Return type:

collections.abc.Iterable[tuple[str, Object]]

keys()

Get the keys of the object, if it is a Dictionary or Stream.

Return type:

set[str]

property objgen: tuple[int, int]

Return the object-generation number pair for this object.

If this is a direct object, then the returned value is (0, 0). By definition, if this is an indirect object, it has a “objgen”, and can be looked up using this in the cross-reference (xref) table. Direct objects cannot necessarily be looked up.

Do not use this value to decide whether two objects are the same object. All direct objects report (0, 0), and objects in different pikepdf.Pdf often have the same numbers. Use is_same_object_as() to compare two objects, and pikepdf.ObjectSet to keep track of objects already seen.

The generation number is usually 0, except for PDFs that have been incrementally updated. Incrementally updated PDFs are now uncommon, since it does not take too long for modern CPUs to reconstruct an entire PDF. pikepdf will consolidate all incremental updates when saving.

Return type:

tuple[int, int]

static parse(stream, description=...)

Parse PDF binary representation into PDF objects.

Parameters:
  • stream (bytes)

  • description (str)

Return type:

Object

pop(index=-1, /)

Remove and return the item at index (default last).

Parameters:

index (int)

Return type:

Object

read_bytes(decode_level=...)

Decode and read the content stream associated with this object.

Parameters:

decode_level (StreamDecodeLevel)

Return type:

bytes

read_raw_bytes()

Read the content stream associated with a Stream, without decoding.

Return type:

bytes

remove(value, /)

Remove the first item in the array equal to value.

Parameters:

value (Any)

Return type:

None

reverse()

Reverse the elements of the array in place.

Return type:

None

same_owner_as(other, /)

Test if two objects are owned by the same pikepdf.Pdf.

Parameters:

other (Object)

Return type:

bool

property stream_dict: Dictionary

Access the dictionary key-values for a pikepdf.Stream.

Return type:

Dictionary

to_json(dereference=..., schema_version=...)

Convert to a qpdf JSON representation of the object.

See the qpdf manual for a description of its JSON representation. https://qpdf.readthedocs.io/en/stable/json.html#qpdf-json-format

Not necessarily compatible with other PDF-JSON representations that exist in the wild.

  • Names are encoded as UTF-8 strings

  • Indirect references are encoded as strings containing obj gen R

  • Strings are encoded as UTF-8 strings with unrepresentable binary

    characters encoded as \uHHHH

  • Encoding streams just encodes the stream’s dictionary; the stream

    data is not represented

  • Object types that are only valid in content streams (inline

    image, operator) as well as “reserved” objects are not representable and will be serialized as null.

Parameters:
  • dereference (bool) – If True, dereference the object if this is an indirect object.

  • schema_version (int) – The version of the JSON schema. Defaults to 2.

Returns:

JSON bytestring of object. The object is UTF-8 encoded and may be decoded to a Python str that represents the binary values \x00-\xFF as U+0000 to U+00FF; that is, it may contain mojibake.

Return type:

bytes

Changed in version 6.0: Added schema_version.

unparse(resolved=...)

Convert PDF objects into their binary representation.

Set resolved=True to deference indirect objects where possible.

If you want to unparse content streams, which are a collection of objects that need special treatment, use pikepdf.unparse_content_stream() instead.

Returns bytes() that can be used with Object.parse() to reconstruct the pikepdf.Object. If reconstruction is not possible, a relative object reference is returned, such as 4 0 R.

Parameters:

resolved (bool) – If True, deference indirect objects where possible.

Return type:

bytes

update(other, /)

Update the dictionary with key/value pairs from another dictionary.

other may be a Python mapping or another pikepdf Dictionary.

Parameters:

other (collections.abc.Mapping[Any, Any] | Object)

Return type:

None

values()
Return type:

collections.abc.Iterable[Object]

with_same_owner_as(other, /)

Returns an object that is owned by the same Pdf that owns other object.

If the objects already have the same owner, this object is returned. If the other object has a different owner, then a copy is created that is owned by other’s owner. If this object is a direct object (no owner), then an indirect object is created that is owned by other. An exception is thrown if other is a direct object. As with pikepdf.Pdf.make_indirect(), a direct scalar is copied before it is made indirect, so this object is left unchanged.

This method may be convenient when a reference to the Pdf is not available.

Added in version 2.14.

Changed in version 10.14: Direct scalars are copied rather than made indirect in place.

Parameters:

other (Object)

Return type:

Object

wrap_in_array()

Return the object wrapped in an array if not already an array.

Return type:

Array

write(data, *, filter=..., decode_parms=..., type_check=...)

Replace stream object’s data with new (possibly compressed) data.

filter and decode_parms describe any compression that is already present on the input data. For example, if your data is already compressed with the Deflate algorithm, you would set filter=Name.FlateDecode.

When writing the PDF in pikepdf.Pdf.save(), pikepdf may change the compression or apply compression to data that was not compressed, depending on the parameters given to that function. It will never change lossless to lossy encoding.

PNG and TIFF images, even if compressed, cannot be directly inserted into a PDF and displayed as images.

Parameters:
  • data (bytes) – the new data to use for replacement

  • filter (Name | Array | list[Name] | None) – The filter(s) with which the data is (already) encoded

  • decode_parms (Dictionary | Array | None) – Parameters for the filters with which the object is encode

  • type_check (bool) – Check arguments; use False only if you want to intentionally create malformed PDFs.

Return type:

None

If only one filter is specified, it may be a name such as Name(‘/FlateDecode’). If there are multiple filters, then array of names should be given.

If there is only one filter, decode_parms is a Dictionary of parameters for that filter. If there are multiple filters, then decode_parms is an Array of Dictionary, where each array index is corresponds to the filter.

class pikepdf.Name

Construct a PDF Name object.

Names can be constructed with two notations:

  1. Name.Resources

  2. Name('/Resources')

The two are semantically equivalent. The former is preferred for names that are normally expected to be in a PDF. The latter is preferred for dynamic names and attributes.

__new__(name)
Parameters:

name (str | Name)

Return type:

Name

classmethod random(len_=16, prefix='')

Generate a cryptographically strong, random, valid PDF Name.

If you are inserting a new name into a PDF (for example, a name for a new image), you can use this function to generate a cryptographically strong random name that is almost certainly not already in the PDF, and not colliding with other existing names.

This function uses Python’s secrets.token_urlsafe, which returns a URL-safe encoded random number of the desired length. An optional prefix may be prepended. (The encoding is ultimately done with base64.urlsafe_b64encode().) Serendipitously, URL-safe is also PDF-safe.

When the length parameter is 16 (16 random bytes or 128 bits), the result is probably globally unique and can be treated as never colliding with other names.

The length of the returned string may vary because it is encoded, but will always have 8 * len_ random bits.

Parameters:
  • len – The length of the random string.

  • prefix (str) – A prefix to prepend to the random string.

  • len_ (int)

Return type:

Name

class pikepdf.NamePath

Path for accessing nested Dictionary/Stream values.

NamePath provides ergonomic access to deeply nested PDF structures with a single access operation and helpful error messages when keys are not found.

Usage examples:

# Shorthand syntax - most common
obj[NamePath.Resources.Font.F1]

# With array indices
obj[NamePath.Pages.Kids[0].MediaBox]

# Chained access - supports non Python-identifier names
NamePath['/A']('/B').C[0]  # equivalent to NamePath.A.B.C[0]

# Alternate syntax to support lists
obj[NamePath(Name.Resources, Name.Font)]

# Using string objects
obj[NamePath('/Resources', '/Weird-Name')]

# Empty path returns the object itself
obj[NamePath()]

# Setting nested values (all parents must exist)
obj[NamePath.Root.Info.Title] = pikepdf.String("Test")

# With default value
obj.get(NamePath.Root.Metadata, None)

When a key is not found, the KeyError message identifies the exact failure point, e.g.: “Key /C not found; traversed NamePath.A.B”

Added in version 10.1.

class pikepdf.String

Construct a PDF String object.

__new__(s)
Parameters:

s (str | bytes)

Return type:

String

class pikepdf.Array

Construct a PDF Array object.

__new__(a=None)
Parameters:

a (collections.abc.Iterable[Any] | Rectangle | Matrix | None)

Return type:

Array

class pikepdf.Dictionary

Construct a PDF Dictionary object.

Works from either a Python dict or keyword arguments.

These two examples are equivalent:

pikepdf.Dictionary({'/NameOne': 1, '/NameTwo': 'Two'})

pikepdf.Dictionary(NameOne=1, NameTwo='Two')

In either case, the keys must be strings, and the strings correspond to the desired Names in the PDF Dictionary. The values must all be convertible to pikepdf.Object.

__new__(d=None, **kwargs)
Parameters:
  • d (collections.abc.Mapping[str, Any] | None)

  • kwargs (Any)

Return type:

Dictionary

class pikepdf.Stream

Construct a PDF Stream object.

Streams stores arbitrary binary data and may or may not be compressed. It also may or may not be a page or Form XObject’s content stream.

A stream dictionary is like a pikepdf.Dictionary or Python dict, except it has a binary payload of data attached. The dictionary describes how the data is compressed or encoded.

The dictionary may be initialized just like pikepdf.Dictionary is initialized, using a mapping object or keyword arguments.

Parameters:
  • owner – The Pdf to which this stream shall be attached.

  • data – The data bytes for the stream.

  • d – An optional mapping object that will be used to construct the stream’s dictionary.

  • kwargs – Keyword arguments that will define the stream dictionary. Do not set /Length here as pikepdf will manage this value. Set /Filter if the data is already encoded in some format.

Examples

Using kwargs:
>>> pdf = pikepdf.Pdf.new()
>>> s1 = pikepdf.Stream(
...     pdf,
...     b"uncompressed image data",
...     BitsPerComponent=8,
...     ColorSpace=pikepdf.Name.DeviceRGB,
... )
Using dict:
>>> pdf = pikepdf.Pdf.new()
>>> d = pikepdf.Dictionary(Key1=1, Key2=2)
>>> s2 = pikepdf.Stream(
...     pdf,
...     b"data",
...     d
... )

Changed in version 2.2: Support creation of pikepdf.Stream from existing dictionary.

Changed in version 3.0: obj argument was removed; use data.

__new__(owner, data=None, d=None, **kwargs)
Parameters:
  • owner (Pdf)

  • data (bytes | None)

  • d (Any)

  • kwargs (Any)

Return type:

Stream

class pikepdf.Operator

Construct an operator for use in a content stream.

An Operator is one of a limited set of commands that can appear in PDF content streams (roughly the mini-language that draws objects, lines and text on a virtual PDF canvas). The commands parse_content_stream() and unparse_content_stream() create and expect Operators respectively, along with their operands.

pikepdf uses the special Operator “INLINE IMAGE” to denote an inline image in a content stream.

__new__(name)
Parameters:

name (str)

Return type:

Operator

class pikepdf.ObjectSet(objects=None)

The objects that a walk of a PDF’s object graph has already visited.

The objects of a PDF form a graph, not a tree. An object may be referenced from many places, and may refer back to one of its own ancestors, whether by design (a page and its /Parent), by the choice of the software that wrote the file (form XObjects that share one /Resources dictionary listing all of them), or by malice. Code that follows references must therefore remember where it has been. Limiting the depth of the walk is not enough: that stops an endless loop, but still visits a shared object once for every path that leads to it, and the number of paths grows exponentially with the depth.

add() reports whether an object is new, so a walk needs one line to be safe:

seen = pikepdf.ObjectSet()
pending = [pdf.Root.Outlines]
while pending:
    node = pending.pop()
    if not isinstance(node, pikepdf.Dictionary) or not seen.add(node):
        continue
    ...  # examine node
    pending.append(node.get(Name.Next))
    pending.append(node.get(Name.First))

Objects are told apart by identity, not by value: two dictionaries with the same contents are different objects, while every reference to one indirect object is the same object, as pikepdf.Object.is_same_object_as() tests. This is more reliable than a set of pikepdf.Object.objgen, which cannot tell direct objects apart, since they all report (0, 0), and confuses objects that have the same number in different pikepdf.Pdf.

Only pikepdf.Object and its helpers, such as pikepdf.Page, can be added. A helper counts as the object it wraps. Numbers, booleans and other values that pikepdf converts to Python types have no identity to track, and adding one raises TypeError.

The set keeps its objects alive in memory but does not keep their pikepdf.Pdf open. It cannot be iterated; it answers only whether an object has been seen.

Where pikepdf provides a walk, prefer it to writing one. In particular, pikepdf.Pdf.content_scopes() finds everything that pages draw and the resources they use, and needs no ObjectSet.

Parameters:

objects (collections.abc.Iterable[Object | ObjectHelper] | None) – Objects to add to the new set.

Added in version 10.17.

add(obj)

Add an object, and report whether it was new.

Returns:

True if the object was not in the set before this call, so the caller is visiting it for the first time. False if it was already present. Note that this differs from set.add(), which returns nothing.

Parameters:

obj (Object | ObjectHelper)

Return type:

bool

clear()

Remove every object.

Return type:

None

discard(obj)

Remove an object, if it is present.

Parameters:

obj (Object | ObjectHelper)

Return type:

None

Common PDF data structures

class pikepdf.Matrix

A 2D affine matrix for PDF transformations.

PDF uses matrices to transform document coordinates to screen/device coordinates.

PDF matrices are encoded as pikepdf.Array with exactly six numeric elements, ordered as a b c d e f. Such an array, for example a form XObject’s /Matrix, can be passed to the constructor.

\[\begin{split}\begin{bmatrix} a & b & 0 \\ c & d & 0 \\ e & f & 1 \\ \end{bmatrix}\end{split}\]

The approximate interpretation of these six parameters is documented below. The values (0, 0, 1) in the third column are fixed, so a general 3×3 matrix cannot be converted to a PDF matrix.

PDF transformation matrices are the transpose of most textbook treatments. In a textbook, typically A × vc is used to transform a column vector vc=(x, y, 1) by the affine matrix A. In PDF, the matrix is the transpose of that in the textbook, and vr × A' is used to transform a row vector vr=(x, y, 1).

Transformation matrices specify the transformation from the new (transformed) coordinate system to the original (untransformed) coordinate system. x’ and y’ are the coordinates in the untransformed coordinate system, and x and y are the coordinates in the transformed coordinate system.

PDF order:

\[\begin{split}\begin{equation} \begin{bmatrix} x' & y' & 1 \end{bmatrix} = \begin{bmatrix} x & y & 1 \end{bmatrix} \begin{bmatrix} a & b & 0 \\ c & d & 0 \\ e & f & 1 \end{bmatrix} \end{equation}\end{split}\]

To concatenate transformations, use the matrix multiple (@) operator to pre-multiply the next transformation onto existing transformations.

Alternatively, use the .translated(), .scaled(), and .rotated() methods to chain transformation operations.

Addition and other operations are not implemented because they’re not that meaningful in a PDF context.

Matrix objects are immutable. All transformation methods return new matrix objects.

Added in version 8.7.

__array__(dtype=None, copy=None)

Convert this matrix to a NumPy array of type dtype.

If copy is True, a copy is made. If copy is False, an exception is raised.

If numpy is not installed, this will throw an exception.

Parameters:
  • dtype (Any)

  • copy (bool | None)

Return type:

numpy.ndarray

__init__() → None
__matmul__(other, /)

Return the matrix product of two matrices.

Can be used to concatenate transformations. Transformations should be composed by pre-multiplying matrices. For example, to apply a scaling transform, one could do:

scale = pikepdf.Matrix(2, 0, 0, 2, 0, 0)
scaled = scale @ matrix
Parameters:

other (Matrix)

Return type:

Matrix

property a: float

a is the horizontal scaling factor.

Return type:

float

as_array()

Convert this matrix to a pikepdf.Array.

A Matrix cannot be inserted into a PDF directly. Use this function to convert a Matrix to a pikepdf.Array, which can be inserted.

Return type:

Array

property b: float

b is horizontal skewing.

Return type:

float

property c: float

c is vertical skewing.

Return type:

float

property d: float

d is the vertical scaling factor.

Return type:

float

property e: float

e is the horizontal translation.

Return type:

float

encode()

Encode matrix to bytes suitable for including in a PDF content stream.

Return type:

bytes

property f: float

f is the vertical translation.

Return type:

float

classmethod identity()

Construct an identity matrix.

More explicit than the constructor.

Added in version 9.7.0.

Return type:

Matrix

inverse()

Return the inverse of the matrix.

The inverse matrix reverses the transformation of the original matrix.

In rare situations, the inverse may not exist. In that case, an exception is thrown. The PDF will likely have rendering problems.

Return type:

Matrix

rotated(angle_degrees_ccw)

Return a rotated copy of this matrix.

Calculates Matrix(cos(angle), sin(angle), -sin(angle), cos(angle), 0, 0) @ self.

Parameters:

angle_degrees_ccw (float | decimal.Decimal) – angle in degrees counterclockwise

Return type:

Matrix

scaled(sx, sy, /)

Return a scaled copy of this matrix.

Calculates Matrix(sx, 0, 0, sy, 0, 0) @ self.

Parameters:
  • sx (float | decimal.Decimal) – horizontal scaling

  • sy (float | decimal.Decimal) – vertical scaling

Return type:

Matrix

property shorthand: tuple[float, float, float, float, float, float]

Return the 6-tuple (a,b,c,d,e,f) that describes this matrix.

Return type:

tuple[float, float, float, float, float, float]

transform(point: tuple[float, float]) → tuple[float, float]
translated(tx, ty, /)

Return a translated copy of this matrix.

Calculates Matrix(1, 0, 0, 1, tx, ty) @ self.

Parameters:
  • tx (float | decimal.Decimal) – horizontal translation

  • ty (float | decimal.Decimal) – vertical translation

Return type:

Matrix

class pikepdf.Rectangle(llx: float, lly: float, urx: float, ury: float, /)

A PDF rectangle.

Typically this will be a rectangle in PDF units (points, 1/72”). Unlike raster graphics, the rectangle is defined by the lower left and upper right points.

Rectangles in PDF are encoded as pikepdf.Array with exactly four numeric elements, ordered as llx lly urx ury. See {{ pdfrm }} section 7.9.5.

The rectangle may be considered degenerate if the lower left corner is not strictly less than the upper right corner.

Added in version 2.14.

Changed in version 8.5: Added operators to test whether rectangle a is contained in rectangle b (a <= b) and to calculate their intersection (a & b).

__and__(other, /)

Return the bounding Rectangle of the common area of self and other.

Parameters:

other (Rectangle)

Return type:

Rectangle

__init__(llx: float, lly: float, urx: float, ury: float, /) → None

Construct a new rectangle.

as_array()

Returns this rectangle as a pikepdf.Array.

Return type:

Array

property height: float

The height of the rectangle.

Return type:

float

llx: float = Ellipsis

The lower left corner on the x-axis.

lly: float = Ellipsis

The lower left corner on the y-axis.

property lower_left: tuple[float, float]

A point for the lower left corner.

Return type:

tuple[float, float]

property lower_right: tuple[float, float]

A point for the lower right corner.

Return type:

tuple[float, float]

to_bbox()

Returns the origin-centred bounding box that encloses this rectangle.

Create a new rectangle with the same width and height as this one, but located at the origin (0, 0).

Bounding boxes represent independent coordinate systems, such as for Form XObjects.

Return type:

Rectangle

property upper_left: tuple[float, float]

A point for the upper left corner.

Return type:

tuple[float, float]

property upper_right: tuple[float, float]

A point for the upper right corner.

Return type:

tuple[float, float]

urx: float = Ellipsis

The upper right corner on the x-axis.

ury: float = Ellipsis

The upper right corner on the y-axis.

property width: float

The width of the rectangle.

Return type:

float

Content stream elements

class pikepdf.ContentStreamInstruction(operands: _ObjectList, operator: Operator, /)

Represents one complete instruction inside a content stream.

property operands: _ObjectList

The operands (parameters) supplied to the operator.

Return type:

_ObjectList

property operator: Operator

The operator used in this instruction.

Return type:

Operator

class pikepdf.ContentStreamInlineImage

Represents an instruction to draw an inline image.

pikepdf consolidates the BI-ID-EI sequence of operators, as appears in a PDF to declare an inline image, and replaces them with a single virtual content stream instruction with the operator “INLINE IMAGE”.

property iimage: pikepdf.models.image.PdfInlineImage

Returns the inline image itself.

Return type:

pikepdf.models.image.PdfInlineImage

property operands: _ObjectList

Returns a list of operands, whose sole entry is the inline image.

Return type:

_ObjectList

property operator: Operator

Always return the fictitious operator ‘INLINE IMAGE’.

Return type:

Operator

Internal objects

These objects are returned by other pikepdf objects. They are part of the API, but not intended to be created explicitly.

class pikepdf._core.PageList

For accessing pages in a PDF.

A list-like object enumerating a range of pages in a pikepdf.Pdf. It may be all of the pages or a subset. Obtain using pikepdf.Pdf.pages.

See pikepdf.Page for accessing individual pages.

append(page, /)

Add another page to the end.

While this method copies pages from one document to another, it does not copy certain metadata such as annotations, form fields, bookmarks or structural tree elements. Copying these is a more complex, application specific operation.

Parameters:

page (Page)

Return type:

None

extend(other, /)

Extend the Pdf by adding pages from an iterable of pages.

While this method copies pages from one document to another, it does not copy certain metadata such as annotations, form fields, bookmarks or structural tree elements. Copying these is a more complex, application specific operation.

Parameters:

other (PageList | collections.abc.Iterable[Page])

Return type:

None

from_objgen(objgen: tuple[int, int], /) → Page

Given an objgen (object ID, generation), return the page.

Raises an exception if no page matches.

index(page, /)

Given a page, find the index.

That is, returns n such that pdf.pages[n] == this_page. A ValueError exception is thrown if the page does not belong to to this Pdf. The first page has index 0.

Parameters:

page (Page | Object)

Return type:

int

insert(index, obj, /)

Insert a page at the specified location.

Parameters:
  • index (int) – location at which to insert page, 0-based indexing

  • obj (Page) – page object to insert

Return type:

None

p(pnum, /)

Look up page number in ordinal numbering, where 1 is the first page.

This is provided for convenience in situations where ordinal numbering is more natural. It is equivalent to .pages[pnum - 1]. .p(0) is an error and negative indexing is not supported.

If the PDF defines custom page labels (such as labeling front matter with Roman numerals and the main body with Arabic numerals), this function does not account for that. Use pikepdf.Page.label to get the page label for a page.

Parameters:

pnum (int)

Return type:

Page

remove(page: Page, /) → None

Remove a page.

Parameters:
  • page – If page is not None, remove that page.

  • p – 1-based page number to remove, if page is None.

reverse()

Reverse the order of pages.

Return type:

None

class pikepdf._core._ObjectList

A list whose elements are always pikepdf.Object.

Values are encoded to pikepdf.Object on the way in, and numeric objects are decoded to int/bool/Decimal on the way out, so the methods below accept any value that pikepdf can encode. In all other respects, this object behaves like a standard Python list.

append(value, /)
Parameters:

value (Any)

Return type:

None

clear()
Return type:

None

count(value, /)
Parameters:

value (Any)

Return type:

int

extend(L: _ObjectList, /) → None
insert(index, value, /)
Parameters:
  • index (int)

  • value (Any)

Return type:

None

pop() → Object
remove(value, /)
Parameters:

value (Any)

Return type:

None

class pikepdf.ObjectType

Enumeration of PDF object types.

These values are used to implement pikepdf’s instance type checking. In the vast majority of cases it is more pythonic to use isinstance(obj, pikepdf.Stream) or issubclass.

These values are low-level and documented for completeness. They are exposed through pikepdf.Object._type_code.

array: ...

A PDF array, meaning the object is a pikepdf.Array.

boolean: ...

A PDF boolean. In most cases, booleans are automatically converted to bool, so this should not appear.

dictionary: ...

A PDF dictionary, meaning the object is a pikepdf.Dictionary.

inlineimage: ...

A PDF inline image, meaning the object is the data stream of an inline image. It would be necessary to combine this with the implicit dictionary to interpret the image correctly. pikepdf automatically packages inline images into a more useful class, so this will not generally appear.

integer: ...

A PDF integer. In most cases, integers are automatically converted to int, so this should not appear. Unlike Python integers, PDF integers are 32-bit signed integers.

name_: ...

A PDF name, meaning the object is a pikepdf.Name.

null: ...

A PDF null. In most cases, nulls are automatically converted to None, so this should not appear.

operator: ...

A PDF operator, meaning the object is a pikepdf.Operator.

real: ...

A PDF real. In most cases, reals are automatically convert to decimal.Decimal.

reserved: ...

A temporary object used in creating circular references. Should not appear in most cases.

stream: ...

A PDF stream, meaning the object is a pikepdf.Stream (and it also has a dictionary).

string: ...

A PDF string, meaning the object is a pikepdf.String.

uninitialized: ...

An uninitialized object. If this appears, it is probably a bug.

Jobs

class pikepdf.Job(json: str)

Provides access to the qpdf job interface.

All of the functionality of the qpdf command line program is now available to pikepdf through jobs.

For further details:

https://qpdf.readthedocs.io/en/stable/qpdf-job.html

EXIT_CORRECT_PASSWORD: ClassVar[int] = 3
EXIT_ERROR: ClassVar[int] = 2

Exit code for a job that had an error.

EXIT_IS_NOT_ENCRYPTED: ClassVar[int] = 2

Exit code for a job that provide a password when the input was not encrypted.

EXIT_WARNING: ClassVar[int] = 3

Exit code for a job that had a warning.

LATEST_JOB_JSON: ClassVar[int]

Version number of the most recent job-JSON schema.

LATEST_JSON: ClassVar[int]

Version number of the most recent qpdf-JSON schema.

__init__(json: str) → None

Create a Job from command line arguments to the qpdf program.

The first item in the args list is the program name, as in sys.argv.

Deprecated since version 10.14: The progname keyword argument is ignored and will be removed.

Example

job = Job([‘pikepdf’, ‘–check’, ‘input.pdf’]) job.run()

check_configuration()

Checks if the configuration is valid; raises an exception if not.

Return type:

None

create_pdf()

Executes the first stage of the job.

Return type:

Pdf

property creates_output: bool

Returns True if the Job will create some sort of output file.

Return type:

bool

property encryption_status: dict[str, bool]

Returns a Python dictionary describing the encryption status.

Return type:

dict[str, bool]

property exit_code: int

After run(), returns an integer exit code.

The meaning of exit code depends on the details of the Job that was run. Details are subject to change in libqpdf. Use properties has_warnings and encryption_status instead.

Return type:

int

property has_warnings: bool

After run(), returns True if there were warnings.

Return type:

bool

static job_json_schema(*, schema=...)

For reference, the qpdf job command line schema is built-in.

Parameters:

schema (int)

Return type:

str

static json_out_schema(*, schema=...)

For reference, the qpdf JSON output schema is built-in.

Parameters:

schema (int)

Return type:

str

property message_prefix: str

Allows manipulation of the prefix in front of all output messages.

Return type:

str

run()

Executes the job.

Return type:

None

write_pdf(pdf)

Executes the second stage of the job.

Parameters:

pdf (Pdf)

Return type:

None

class pikepdf.JobBuilder

Fluently assemble a qpdf job and run it.

Each method records part of the job specification and returns self so calls can be chained. List-valued sections (pages, attachments, overlay/underlay) use repeatable add_* methods. Terminal methods build(), run() and create_pdf() hand the assembled specification to pikepdf.Job.

The builder performs minimal local validation; qpdf is the source of truth and will raise pikepdf.JobUsageError (or RuntimeError for malformed JSON) for invalid configurations when the job is built.

add_attachment(file, *, key=None, filename=None, mimetype=None, description=None, creationdate=None, moddate=None, replace=False)

Attach (embed) a file in the output.

Parameters:
  • file (Any) – Path to the file to attach.

  • key (str | None) – Attachment key; defaults to the filename.

  • filename (str | None) – Displayed filename of the attachment.

  • mimetype (str | None) – MIME type, e.g. 'application/pdf'.

  • description (str | None) – Human-readable description.

  • creationdate (str | None) – Creation date (PDF date string).

  • moddate (str | None) – Modification date (PDF date string).

  • replace (bool) – Replace an existing attachment with the same key.

Return type:

JobBuilder

add_overlay(file, *, to=None, from_=None, repeat=None, password=None)

Overlay pages from another file on top of the output pages.

Parameters:
  • file (Any) – Source PDF for the overlay.

  • to (str | None) – Destination page range in the output.

  • from – Source page range in file.

  • repeat (str | None) – Source pages to repeat across remaining destination pages.

  • password (str | None) – Password for an encrypted source file.

  • from_ (str | None)

Return type:

JobBuilder

add_pages(file, page_range=None, *, password=None)

Append pages from a file to the page-selection (merge/split) operation.

Parameters:
  • file (Any) – Source PDF. Use '.' to refer to the primary input file.

  • page_range (str | None) – qpdf page range, e.g. '1-5' or 'z-1' (reversed). Omit to use all pages.

  • password (str | None) – Password for an encrypted source file.

Return type:

JobBuilder

add_underlay(file, *, to=None, from_=None, repeat=None, password=None)

Underlay pages from another file beneath the output pages.

See add_overlay() for argument descriptions.

Parameters:
  • file (Any)

  • to (str | None)

  • from_ (str | None)

  • repeat (str | None)

  • password (str | None)

Return type:

JobBuilder

allow_weak_crypto()

Permit writing files with weak (RC4) cryptography.

Return type:

JobBuilder

build()

Construct a pikepdf.Job from the specification.

The job is validated by qpdf during construction but not executed.

Raises:
  • pikepdf.JobUsageError – If the configuration is semantically invalid.

  • RuntimeError – If the JSON is malformed or contains unknown keys.

Return type:

Job

check(*, linearization=False)

Check the PDF for problems, reporting via the job’s output.

Parameters:

linearization (bool) – Also check the linearization (hint) tables.

Return type:

JobBuilder

coalesce_contents()

Combine a page’s multiple content streams into one.

Return type:

JobBuilder

collate(n=None)

Collate rather than concatenate the page selection.

Parameters:

n (int | None) – Number of pages to take from each file per round.

Return type:

JobBuilder

compress(*, compress_streams=None, object_streams=None, recompress_flate=False, compression_level=None, decode_level=None, stream_data=None)

Configure stream and object-stream compression.

Parameters:
  • compress_streams (bool | None) – Compress uncompressed streams.

  • object_streams (Literal['generate', 'preserve', 'disable'] | None) – Control use of object streams.

  • recompress_flate (bool) – Uncompress and recompress flate streams.

  • compression_level (int | None) – Flate compression level (1-9).

  • decode_level (Literal['none', 'generalized', 'specialized', 'all'] | None) – Which streams to uncompress before recompressing.

  • stream_data (Literal['compress', 'preserve', 'uncompress'] | None) – Legacy combined stream compression control.

Return type:

JobBuilder

copy_attachments_from(file, *, prefix=None, password=None)

Copy all attachments from another PDF.

Parameters:
  • file (Any) – Source PDF to copy attachments from.

  • prefix (str | None) – Prefix to disambiguate keys that collide with existing ones.

  • password (str | None) – Password for an encrypted source file.

Return type:

JobBuilder

create_pdf()

Build the job and run only its first stage, returning a pikepdf.Pdf.

This is the staged workflow: the returned PDF can be modified before calling pikepdf.Job.write_pdf() on the same job. Use build() to retain a reference to the job for the write stage.

Return type:

Pdf

decrypt()

Remove encryption from the input file.

Return type:

JobBuilder

deterministic_id()

Generate the document /ID from the output contents, not the clock.

Saving the same input the same way produces the same /ID, which is useful for reproducible builds and caching. Suitable for production. Cannot be combined with encryption. Equivalent to Pdf.save(..., deterministic_id=True).

Return type:

JobBuilder

empty()

Use an empty PDF as input instead of an input file.

Return type:

JobBuilder

encrypt(encryption=None, *, owner_password=None, user_password=None, bits=256, allow=None, metadata=True, aes=None, force_v4=False, allow_insecure=False, force_r5=False)

Encrypt the output.

Either pass a pikepdf.Encryption object positionally, or use the keyword arguments. The two forms are mutually exclusive.

Parameters:
  • encryption (pikepdf.models.encryption.Encryption | None) – A pikepdf.Encryption describing passwords, permissions and algorithm. If given, the keyword arguments must not be used.

  • owner_password (str | None) – Owner password (full access).

  • user_password (str | None) – User password (restricted access).

  • bits (Literal[40, 128, 256]) – Key length: 40, 128 or 256 (default). 40 and 128-bit RC4 are weak and require allow_weak_crypto().

  • allow (pikepdf.models.encryption.Permissions | None) – A pikepdf.Permissions describing what the user password is permitted to do. Permissions default to pikepdf.models.encryption.DEFAULT_PERMISSIONS.

  • metadata (bool) – If False, document metadata is left unencrypted (128/256-bit only).

  • aes (bool | None) – For 128-bit, request AES rather than RC4.

  • force_v4 (bool) – For 128-bit, force V=4 in the encryption dictionary.

  • allow_insecure (bool) – For 256-bit, allow an insecure empty owner password.

  • force_r5 (bool) – For 256-bit, use the deprecated R=5 algorithm.

Return type:

JobBuilder

externalize_inline_images(*, min_bytes=None)

Convert inline images to regular (external) images.

Parameters:

min_bytes (int | None) – Only externalize inline images at least this large.

Return type:

JobBuilder

flatten_annotations(mode='all')

Push annotations into page content streams.

Parameters:

mode (Literal['all', 'print', 'screen']) – Which annotations to flatten: 'all' (default), 'print' (only those marked for printing) or 'screen' (exclude those marked hidden on screen).

Return type:

JobBuilder

flatten_rotation()

Bake each page’s /Rotate value into its content stream.

Return type:

JobBuilder

force_version(version)

Force the output PDF version, even if features require a higher one.

Parameters:

version (str) – A PDF version such as '1.7', optionally with an extension level as '1.7:8'.

Return type:

JobBuilder

generate_appearances()

Generate appearance streams for form fields that lack them.

Return type:

JobBuilder

input(file, *, password=None)

Set the input file, optionally with a password.

Parameters:
  • file (Any) – Path to the input PDF.

  • password (str | None) – Password for an encrypted input file.

Return type:

JobBuilder

limits(*, no_default_limits=None, parser_max_container_size=None, parser_max_container_size_damaged=None, parser_max_errors=None, parser_max_nesting=None, max_stream_filters=None)

Set global parser limits (useful for hardening against malicious PDFs).

Parameters:
  • no_default_limits (bool | None) – Disable qpdf’s optional default limits.

  • parser_max_container_size (int | None) – Maximum container size while parsing.

  • parser_max_container_size_damaged (int | None) – Maximum container size while parsing damaged files.

  • parser_max_errors (int | None) – Maximum number of errors before giving up.

  • parser_max_nesting (int | None) – Maximum object nesting depth.

  • max_stream_filters (int | None) – Maximum number of filters when filtering a stream.

Return type:

JobBuilder

linearize()

Linearize (web-optimize) the output.

Return type:

JobBuilder

min_version(version)

Set the minimum PDF version of the output.

Parameters:

version (str) – A PDF version such as '1.7', optionally with an extension level as '1.7:8'.

Return type:

JobBuilder

normalize_content()

Normalize newlines in content streams (for readability/inspection).

Return type:

JobBuilder

optimize_images(*, min_area=None, min_width=None, min_height=None, keep_inline_images=False, jpeg_quality=None)

Recompress images using more efficient compression where possible.

Parameters:
  • min_area (int | None) – Skip images smaller than this many pixels in area.

  • min_width (int | None) – Skip images narrower than this many pixels.

  • min_height (int | None) – Skip images shorter than this many pixels.

  • keep_inline_images (bool) – Also consider inline images (excluded by default).

  • jpeg_quality (int | None) – JPEG quality level to use when recompressing.

Return type:

JobBuilder

output(file)

Set the output file.

Parameters:

file (Any) – Path to write. For split_pages(), include a %d placeholder for the page group number.

Return type:

JobBuilder

qdf()

Produce QDF output suitable for inspection in a text editor.

Return type:

JobBuilder

remove_acroform()

Remove the interactive form (AcroForm) dictionary.

Return type:

JobBuilder

remove_attachment(key)

Remove an embedded file by key.

Parameters:

key (str) – Attachment key to remove.

Return type:

JobBuilder

remove_info()

Remove the document information dictionary.

Return type:

JobBuilder

remove_metadata()

Remove the document’s XMP metadata stream.

Return type:

JobBuilder

remove_page_labels()

Remove explicit page labels (page numbering).

Return type:

JobBuilder

remove_restrictions()

Remove security restrictions, recovering the encryption key if needed.

Return type:

JobBuilder

remove_structure()

Remove the document’s structure (tagging) tree.

Return type:

JobBuilder

replace_input()

Overwrite the input file with the output (in place).

Return type:

JobBuilder

rotate(angle, page_range=None)

Rotate pages.

Parameters:
  • angle (int | str) – Rotation in degrees: 90, 180, 270; prefix with + or - to rotate relative to the current rotation.

  • page_range (str | None) – Page range to rotate. Omit to rotate all pages.

Return type:

JobBuilder

run(*, validate=True)

Build and run the job.

Parameters:

validate (bool) – If True (default), call check_configuration() before running to fail fast on invalid configurations.

Returns:

The pikepdf.Job after running, so callers can inspect exit_code, has_warnings and encryption_status.

Return type:

Job

set(**kwargs)

Set arbitrary scalar top-level options not covered by other methods.

Keyword names are snake_case Python aliases for qpdf’s camelCase job keys (e.g. no_warn -> noWarn). A boolean True enables a flag (emitted as an empty string); other values are stringified.

Parameters:

**kwargs (Any) – Option names and values.

Raises:

ValueError – If a keyword does not correspond to a known option.

Return type:

JobBuilder

set_page_labels(labels)

Set page labels (explicit page numbering) for the whole document.

Parameters:

labels (list[str]) – A list of qpdf label specs of the form first-page:[type][/start[/prefix]], e.g. ['1:r', '5:D/1'] to number the first four pages with lower-case Roman numerals and restart with Arabic numerals from page 5. The first spec must start at page 1.

Return type:

JobBuilder

split_pages(group=None)

Write pages to separate files.

Parameters:

group (int | None) – Number of pages per output file. The output filename should contain a %d placeholder.

Return type:

JobBuilder

static_id()

Use a fixed dummy document /ID, identical in every output file.

Warning

For testing and debugging only. Never use in production. Every file gets the same /ID, defeating its purpose as a unique document identifier. Use deterministic_id() for reproducible production output.

Equivalent to Pdf.save(..., static_id=True).

Return type:

JobBuilder

to_json()

Return a deep copy of the assembled job specification as a dict.

Return type:

dict[str, Any]

to_json_str()

Return the assembled job specification as a JSON string.

Return type:

str

qpdf JSON

class pikepdf.JSONStreamData

How stream data is represented when writing a PDF as qpdf JSON.

Used by pikepdf.Pdf.write_qpdf_json().

file: ...

Stream data is written to external files. Each stream is written to a file named {file_prefix}-{object_number}, where file_prefix is the argument given to pikepdf.Pdf.write_qpdf_json().

inline: ...

Stream data is included inline in the JSON, base64-encoded.

none: ...

Stream data is omitted from the JSON output.

class pikepdf.XrefEntry

Represents one entry in a PDF’s cross-reference (xref) table.

Returned by pikepdf.Pdf.get_xref_table(). The meaning of the other properties depends on type.

property obj_stream_index: int | None

Index of the object within its object stream; None unless type == 2.

Return type:

int | None

property obj_stream_number: int | None

Object number of the containing object stream; None unless type == 2.

Return type:

int | None

property offset: int | None

Byte offset of the object in the file, or None unless type == 1.

Return type:

int | None

property type: int

0 = free, 1 = uncompressed, 2 = compressed.

For type 1 (uncompressed), offset is meaningful. For type 2 (compressed, i.e. stored in an object stream), obj_stream_number and obj_stream_index are meaningful.

Type:

The entry type

Return type:

int