Skip to main content

pypdfium2

pypdfium2 is an ABI-level Python 3 binding to PDFium, a powerful and liberal-licensed library for PDF rendering, inspection, manipulation and creation.

It is built with ctypesgen and external PDFium binaries. The custom setup infrastructure provides a seamless packaging and installation process. A wide range of platforms is covered with pre-built packages. Check out our platform support page.

pypdfium2 includes helpers to simplify common use cases, while the raw PDFium API (ctypes) remains accessible as well.

Installation

python -m pip install -U pypdfium2

If available for your platform, this will use a pre-built wheel package, which is the easiest way of installing pypdfium2. Otherwise, setup code will run. If your platform is not covered with pre-built binaries, this will look for system pdfium, or attempt to build pdfium from source.

JavaScript/XFA builds

pdfium-binaries also offer V8 (JavaScript) / XFA enabled builds. If you need them, do e.g.:

PDFIUM_PLATFORM=auto-v8 pip install -v pypdfium2 --no-binary pypdfium2

This will bypass wheels and run setup, while requesting use of V8 builds through the PDFIUM_PLATFORM=auto-v8 environment setting. See below for more info.

Optional runtime dependencies

As of this writing, pypdfium2 does not require any mandatory runtime dependencies, apart from Python and PDFium itself (which is commonly bundled).

However, some optional support model / CLI features need additional packages:

  • Pillow (module PIL) is a popular imaging library for Python. pypdfium2 provides convenience adapters to translate between raw bitmap buffers and PIL images. It also uses PIL for some command-line functionality (e.g. image saving).
  • NumPy is a library for scientific computing. As with Pillow, pypdfium2 provides helpers to get a numpy array view of a raw bitmap.
  • opencv-python (module cv2) is an imaging library built around numpy arrays. It can be used in the rendering CLI to save with pypdfium2's numpy adapter.
  • If tabulate is installed, the CLI will give prettier output where tables are involved.

pypdfium2 tries to defer imports of optional dependencies until they are actually needed, so there should be no startup overhead if you don't use them.

From the repository / With setup

Note, unlike helpers, pypdfium2's setup is not bound by API stability promises, so it may change any time.

Get the code

git clone "https://github.com/pypdfium2-team/pypdfium2"
git clone "https://github.com/pypdfium2-team/ctypesgen" pypdfium2/deps/ctypesgen
cd pypdfium2/

Setup Dependencies

Python

  • ctypesgen (pypdfium2-team fork). This is a source-level dependency as shown above, as opposed to a package dependency. Setup will automatically clone ctypesgen at the latest revision if you don't.
  • setuptools
  • wheel, if setuptools is < v70.1.0

System

  • A C pre-processor (gcc or clang, or set $CPP to whatever pre-processor command you want to attempt), as a dependency of ctypesgen.
  • git (Used e.g. to determine the latest pdfium-binaries version, to get git describe info, or to check out pdfium on sourcebuild. Should be optional on default setup.)
  • gh >= 2.47.0 (optional; used to verify pdfium-binaries build attestations)

Python dependencies should be automatically installed, unless --no-build-isolation is passed to pip.

Default setup

# In the pypdfium2/ directory
python -m pip install -v .

This will invoke pypdfium2's setup.py. Typically, this means a binary will be downloaded from pdfium-binaries and bundled into pypdfium2, and ctypesgen will be called on pdfium headers to produce the bindings interface.

pdfium-binaries offer GitHub build provenance attestations, so it is highly recommended that you install the gh CLI for our setup to verify authenticity of the binaries.

If no pre-built binaries are available for your platform, setup will look for system pdfium, or attempt to build pdfium from source.

pip options of interest
  • -v: Verbose logging output. Useful for debugging.
  • -e: Install in editable mode, so the installation points to the source tree. This way, changes directly take effect without needing to re-install. Recommended for development.
  • --no-build-isolation: Do not isolate setup in a virtual env; use the main env instead. This renders pyproject.toml [build-system] inactive, so setup deps must be prepared by caller. Useful to install custom versions of setup deps, or as speedup when installing repeatedly.
  • --no-binary pypdfium2: Do not use binary wheels when installing from PyPI – instead, use the sdist and run setup. Note, this option is improperly named, as pypdfium2's setup will attempt to use binaries all the same. If you want to prevent that, set e.g. PDFIUM_PLATFORM=fallback to achieve the same behavior as if there were no pdfium-binaries for the host. Or if you just want to package a source distribution, set PDFIUM_PLATFORM=sdist.
  • --pre to install a beta release, if available.

With system pdfium

PDFIUM_PLATFORM="system-search" python -m pip install -v .

Look for a system-provided pdfium shared library, and bind against it.

Standard, portable ctypes.util.find_library() means will be used to probe for system pdfium at setup time, and the result will be hardcoded into the bindings. Alternatively, set $PDFIUM_BINARY to the path of the out-of-tree DLL to use.

Assuming system pdfium was found, we will look for pdfium headers from which to generate the bindings (e.g. in /usr/include). If the headers are in a location not recognized by our code, set $PDFIUM_HEADERS to the directory in question.

Also, we try to determine the pdfium version, either from the library filename itself, or via pkg-config.1 Where this does not work, you can pass the version alongside the setup target, e.g. PDFIUM_PLATFORM=system-search:XXXX, where XXXX is the pdfium build version. If the version is not known in the end, NaN placeholders will be set.

If the version is known but no headers were found, they will be downloaded from upstream. If neither headers nor version are known, the reference bindings will be used as a last resort. This is ABI-unsafe and thus discouraged.

In case find_library() failed to find pdfium, we may do additional, custom search, such as checking for a pdfium shared library included with LibreOffice, and – if available – determining its version.
Our search heuristics currently expect a Linux-like filesystem hierarchy (e.g. /usr), but contributions for other systems are welcome.

With self-built pdfium

You can also install pypdfium2 with a self-compiled pdfium shared library, by placing it in data/sourcebuild/ along with a bindings interface and version info, and setting the PDFIUM_PLATFORM="sourcebuild" directive to use these files on setup.

This project comes with two scripts to automate the build process: build_toolchained.py and build_native.py (in setupsrc/).

  • build_toolchained is based on the build instructions in pdfium's Readme, and uses Google's toolchain (this means foreign binaries and sysroots). This results in a heavy checkout process that may take a lot of time and space. Dependency libraries are vendored. An advantage of the toolchain is its powerful cross-compilation support (including symbol reversioning).
  • build_native is an attempt to address some shortcomings of the toolchained build. It performs a lean, self-managed checkout, and is tailored towards native compilation. It uses system dependencies (compiler/gn/ninja), which must be installed by the caller beforehand. This script should theoretically work on arbitrary Linux architectures. As a drawback, this process is not supported or even documented upstream, so it might be hard to maintain.

The native sourcebuild can either use system libraries, or pdfium's vendored libraries. When invoked directly, by default, system libraries will be used. However, when invoked through fallback setup, vendored libraries are used instead. Use the --vendor ... and --no-vendor ... options to control vendoring on a per-library basis. See build_native.py --help for details.

You can also set PDFIUM_PLATFORM to sourcebuild-native or sourcebuild-toolchained to trigger either build script through setup, and pass command-line flags with $BUILD_PARAMS. However, for simplicity, both scripts/subtargets share just sourcebuild as staging directory.

Dependencies:

  • When building with system libraries, the following packages need to be installed (including development headers): freetype, icu-uc, lcms2, libjpeg, libopenjp2, libpng, libtiff, zlib, harfbuzz (and maybe glib to satisfy the build system).
  • You might also want to know that pdfium bundles agg, abseil, fast_float, simdutf.
  • When building with system tools, gn (generate-ninja), ninja, and a compiler are needed. If available, the compiler defaults to GCC, but Clang should also work if you set up some symlinks, and make sure you have the libclang_rt builtins or pass --no-libclang-rt.

To do the toolchained build, you'd run something like:

# call build script with --help to list options
python ./setupsrc/build_toolchained.py
PDFIUM_PLATFORM="sourcebuild" python -m pip install -v .

Or for the native build, on Ubuntu 24.04, you could do e.g.:

# Install dependencies
python -m pip install --group gn  # see above
sudo apt-get install ninja-build libfreetype-dev liblcms2-dev libjpeg-dev libopenjp2-7-dev libpng-dev libtiff-dev zlib1g-dev libicu-dev libglib2.0-dev libharfbuzz-dev  # generate-ninja
# Build with GCC
python ./setupsrc/build_native.py --compiler gcc
# Alternatively, build with Clang
sudo apt-get install llvm lld
VERSION=18
ARCH=$(uname -m)
sudo ln -s "/usr/lib/clang/$VERSION/lib/linux" "/usr/lib/clang/$VERSION/lib/$ARCH-unknown-linux-gnu"
sudo ln -s "/usr/lib/clang/$VERSION/lib/linux/libclang_rt.builtins-$ARCH.a" "/usr/lib/clang/$VERSION/lib/linux/libclang_rt.builtins.a"
python ./setupsrc/build_native.py --compiler clang
# Install
PDFIUM_PLATFORM="sourcebuild" python -m pip install -v .

The native sourcebuild currently supports Linux (or similar environments). macOS and Windows are not handled, as we do not have access to these systems, and working over CI did not turn out feasible – use the toolchain-based build for now. Community help / pull requests to extend platform support would be welcome.

cibuildwheel

Sourcebuild can be run through cibuildwheel. For targets configured in our pyproject.toml, the basic invocation is as simple as p.ex.

CIBW_BUILD="cp314-manylinux_x86_64" cibuildwheel

A more involved use case could look like this:

CIBW_BUILD="cp314-musllinux_s390x" CIBW_ARCHS=s390x CIBW_CONTAINER_ENGINE=podman TEST_PDFIUM=1 cibuildwheel

See also our cibuildwheel workflow. For more options, consult the comprehensive upstream documentation.

On Linux, this will use the native sourcebuild with vendored dependency libraries. On Windows and macOS, the toolchained sourcebuild is used.

Bear in mind that cibuildwheel copies the project directory into a container, not taking .gitignore rules into account. Thus, it is advisable to make a fresh checkout of pypdfium2 before running cibuildwheel. In particular, a toolchained checkout of pdfium within pypdfium2 is problematic, and will cause a halt on the Copying project into container... step. For development, make sure the fresh checkout is in sync with the working copy.

Concerning Linux, cibuildwheel requires either Docker or Podman. On the author's version of Fedora, Docker can be installed as follows:

sudo dnf in moby-engine  # this provides the docker command
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER
# then reboot (re-login might also suffice)

For other ways of installing Docker, refer to the cibuildwheel docs (Setup, Platforms) and the links therein.

With caller-provided data files

pypdfium2 is like any other Python project in essentials, except that it needs some data files: a pdfium DLL (either bundled or out-of-tree), a bindings interface (generated via ctypesgen), and pdfium version info (JSON).

The main point of pypdfium2's custom setup is to automate deployment of these files, in a way that suits end users/contributors as well as our PyPI packaging.

However, if you want to (or have to) forego this automation (e.g. to avoid setup-time web requests), you can also just supply these files yourself, as shown below. This allows to largely sidestep pypdfium2's own setup code.
The idea is basically to put your data files in a staging directory, data/sourcebuild or data/system (depending on whether you want to bundle or use system pdfium), and set the matching $PDFIUM_PLATFORM target to consume from that directory on setup.

# First, ask yourself: Do you want to bundle pdfium (in-tree), or use system
# pdfium (out-of-tree)? For bundling, set "sourcebuild", else set "system".
TARGET="sourcebuild"  # or "system"
STAGING_DIR="data/$TARGET"

# If you have decided for bundling, copy over the pdfium DLL in question.
# Otherwise, skip this step.
cp "$MY_BINARY_PATH" "$STAGING_DIR/libpdfium.so"

# Now, we will call ctypesgen to generate the bindings interface.
# Reminder: You'll want to use the pypdfium2-team fork of ctypesgen.
# It generates much cleaner bindings, and it's what our source expects
# (there may be subtle API differences in terms of output).
# How exactly you do this is down to you.
# See ctypesgen --help or base.py::run_ctypesgen() for further options.
ctypesgen --library pdfium --rt-libpaths $MY_RT_LIBPATHS --ct-libpaths $MY_CT_LIBPATHS \
--headers $MY_INCLUDE_DIR/fpdf*.h -o $STAGING_DIR/bindings.py [-D $MY_RAW_FLAGS]

# Then write the version file (fill the placeholders).
# Note, this is not a mature interface yet and might change any time!
# See also https://pypdfium2.readthedocs.io/en/stable/python_api.html#pypdfium2.version.PDFIUM_INFO
# major/minor/build/patch: integers forming the pdfium version being packaged
# n_commits/hash: git describe like post-tag info (0/null for release commit)
# origin: a string to identify the build
# flags: a comma-delimited list of pdfium feature flag strings
#        (e.g. "V8", "XFA") - may be empty for default build
cat > "$STAGING_DIR/version.json" <<END
{
  "major": $PDFIUM_MAJOR,
  "minor": $PDFIUM_MINOR,
  "build": $PDFIUM_BUILD,
  "patch": $PDFIUM_PATCH,
  "n_commits": $POST_TAG_COMMIT_COUNT,
  "hash": $POST_TAG_HASH,
  "origin": "$TARGET-$MY_ORIGIN",
  "flags": [$MY_SHORT_FLAGS]
}
END

# Finally, run setup (through pip, pyproject-build or whatever).
# The PDFIUM_PLATFORM value will instruct pypdfium2's setup to use the files
# we supplied, rather than to generate its own.
PDFIUM_PLATFORM=$TARGET python -m pip install --no-build-isolation -v .

Note though, if you bring your own files, that's your own responsibility, and it is quite possible your version of pypdfium2 may turn out subtly different than ours.

If this option still isn't good enough for you, by all means remove pypdfium2's setup.py and bring your own. In either case, please do not expect us to help with that process, let alone support the result.

Further setup info (formal summary)

This is a somewhat formal description of pypdfium2's setup capabilities. It is meant to sum up and complement the above documentation on specific sub-targets.

As it is hard to keep up with constantly evolving setup code, it is possible this documentation may be outdated/incomplete. Also keep in mind that these APIs could change any time, and are mainly of internal interest.

  • Binaries are stored in platform-specific sub-directories of data/, along with bindings and version information.

  • $PDFIUM_PLATFORM defines which binary to include on setup.

    • Format spec: [$PLATFORM][-v8][:$VERSION] ([] = segments, $CAPS = variables).
    • Examples: auto, auto:7269 auto-v8:7269 (auto may be substituted by an explicit platform name, e.g. linux_x64).
    • V8: If given, use the V8 (JavaScript) and XFA enabled pdfium binaries. Otherwise, use the regular (non-V8) binaries.
    • Version: If given, use the specified pdfium-binaries release. Otherwise, use the default version currently set in the codebase. Set pinned to request that behavior explicitly. Or set latest to use the newest pdfium-binaries release instead.
    • Platform:
      • If unset or auto, the host platform is detected and a corresponding binary will be selected.
      • If an explicit platform identifier (e.g. linux_x64, darwin_arm64, ...), binaries for the requested platform will be used.3
      • If system-search, look for and bind against system-provided pdfium instead of embedding a binary. If just system, consume existing bindings from data/system/.
      • If sourcebuild, binary and bindings will be taken from data/sourcebuild/, assuming a prior run of the native or toolchained build scripts. sourcebuild-native or sourcebuild-toolchained can also be used to trigger either build through setup (use $BUILD_PARAMS to pass custom options).
      • If sdist, no platform-specific files will be included, so as to create a source distribution.
  • $PDFIUM_BINDINGS=reference allows to override ctypesgen and use the reference bindings file autorelease/bindings.py instead.

    • This is a convenience option to get pypdfium2 installed from source even if a working ctypesgen / C pre-processor is not available in the install env. May be automatically enabled under given circumstances.
    • Warning: This may not be ABI-safe. Please make sure binary/bindings build headers match to avoid ABI issues.

Unofficial packages

The authors of this project have no control over and are not responsible for possible third-party builds of pypdfium2, and we do not support them. If you have an issue with a third-party build, please contact your distributor – not us.

With third-party package recipes, there is always a risk they might be poor quality. The schemes of downstream distributors do not necessarily align with those of upstream authors.

Please do not expect us to add/change code for downstream-specific setup tasks, though. Related issues or PRs may be closed without further notice if we don't see fit for upstream. Enhancements of general value that are maintainable and align well with the idea of our setup code are welcome, though.

Usage

Support model

Here are some examples of using the support model API.

  • Import the library

    import pypdfium2 as pdfium
    import pypdfium2.raw as pdfium_c
    
  • Open a PDF using the helper class PdfDocument (supports file paths as string or pathlib.Path, or file content as bytes or byte stream)

    pdf = pdfium.PdfDocument("./path/to/document.pdf")
    version = pdf.get_version()  # get the PDF standard version
    n_pages = len(pdf)  # get the number of pages in the document
    page = pdf[0]  # load a page
    
  • Render the page

    bitmap = page.render(
        scale = 1,    # 72dpi resolution
        rotation = 0, # no additional rotation
        # ... further rendering options
    )
    pil_image = bitmap.to_pil()
    pil_image.show()
    

    Note, with the PIL adapter, it might be advantageous to use force_bitmap_format=pdfium_c.FPDFBitmap_BGRA, rev_byteorder=True or perhaps prefer_bgrx=True, maybe_alpha=True, rev_byteorder=True, to achieve a pixel format supported natively by PIL, and avoid rendering with transparency to a non-alpha bitmap, which can slow down pdfium.

    With .to_numpy(), all formats are zero-copy, but passing either maybe_alpha=True (if dynamic pixel format is acceptable) or force_bitmap_format=pdfium_c.FPDFBitmap_BGRA is also recommended for the transparency problem.

  • Try some page methods

    # Get page dimensions in PDF canvas units (1pt->1/72in by default)
    width, height = page.get_size()
    # Set the absolute page rotation to 90° clockwise
    page.set_rotation(90)
    
    # Locate objects on the page
    for obj in page.get_objects():
        print(obj.level, obj.type, obj.get_bounds())
    
  • Extract and search text

    # Load a text page helper
    textpage = page.get_textpage()
    
    # Extract text from the whole page
    text_all = textpage.get_text_bounded()
    # Extract text from a specific rectangular area
    text_rect = textpage.get_text_bounded(left=50, bottom=100, right=width-50, top=height-100)
    # Extract text from a specific char range
    text_span = textpage.get_text_range(index=10, count=15)
    
    # Locate text on the page
    searcher = textpage.search("something", match_case=False, match_whole_word=False)
    # This returns the next occurrence as (char_index, char_count), or None if not found
    match = searcher.get_next()
    
  • Read the table of contents

    import pypdfium2.internal as pdfium_i
    
    for bm in pdf.get_toc(max_depth=15):
        count, dest = bm.get_count(), bm.get_dest()
        out = "    " * bm.level
        out += "[%s] %s -> " % (
            f"{count:+}" if count != 0 else "*",
            bm.get_title(),
        )
        if dest:
            index, (view_mode, view_pos) = dest.get_index(), dest.get_view()
            out += "%s  # %s %s" % (
                index+1 if index != None else "?",
                pdfium_i.ViewmodeToStr.get(view_mode),
                round(view_pos, 3),
            )
        else:
            out += "_"
        print(out)
    
  • Create a new PDF with an empty A4 sized page

    pdf = pdfium.PdfDocument.new()
    width, height = (595, 842)
    page_a = pdf.new_page(width, height)
    
  • Include a JPEG image in a PDF

    pdf = pdfium.PdfDocument.new()
    
    image = pdfium.PdfImage.new(pdf)
    image.load_jpeg("./tests/resources/mona_lisa.jpg")
    width, height = image.get_px_size()
    
    matrix = pdfium.PdfMatrix().scale(width, height)
    image.set_matrix(matrix)
    
    page = pdf.new_page(width, height)
    page.insert_obj(image)
    page.gen_content()
    
  • Save the document

    # PDF 1.7 standard
    pdf.save("output.pdf", version=17)
    

Raw PDFium API

While helper classes conveniently wrap the raw PDFium API, it may still be accessed directly and is available in the namespace pypdfium2.raw. Lower-level utilities that may aid with using the raw API are provided in pypdfium2.internal.

import pypdfium2.raw as pdfium_c
import pypdfium2.internal as pdfium_i

Since PDFium is a large library, many components are not covered by helpers yet. However, as helpers expose their underlying raw objects, you may seamlessly integrate raw APIs while using helpers as available. When passed as ctypes function parameter, helpers automatically resolve to the raw object handle (but you may still access it explicitly if desired):

permission_flags = pdfium_c.FPDF_GetDocPermission(pdf.raw)  # explicit
permission_flags = pdfium_c.FPDF_GetDocPermission(pdf)      # implicit

For PDFium docs, please look at the comments in its public header files.4 A variety of examples on how to interface with the raw API using ctypes is already provided with support model source code. Nonetheless, the following guide may be helpful to get started with the raw API, if you are not familiar with ctypes yet.

  • In general, PDFium functions can be called just like normal Python functions. However, parameters may only be passed positionally, i.e. it is not possible to use keyword arguments. There are no defaults, so you always need to provide a value for each argument.
    # arguments: filepath (bytes), password (bytes|None)
    # NUL-terminate filepath and encode as UTF-8
    pdf = pdfium_c.FPDF_LoadDocument((filepath+"\x00").encode("utf-8"), None)
    
    This is the underlying bindings declaration,5 which loads the function from the binary and contains the information required to convert Python types to their C equivalents.
    if hasattr(_libs['pdfium'], 'FPDF_LoadDocument'):
        FPDF_LoadDocument = _libs['pdfium']['FPDF_LoadDocument']
        FPDF_LoadDocument.argtypes = (FPDF_STRING, FPDF_BYTESTRING)
        FPDF_LoadDocument.restype = FPDF_DOCUMENT
    
    Python bytes are converted to FPDF_STRING by ctypes autoconversion. This works because FPDF_STRING is actually an alias to POINTER(c_char) (i.e. char*), which is a primitive pointer type. When passing a string to a C function, it must always be NUL-terminated, as the function merely receives a pointer to the first item and then continues to read memory until it finds a NUL terminator.
  • First of all, function parameters are not only used for input, but also for output:

    # Initialise an integer object (defaults to 0)
    c_version = ctypes.c_int()
    # Let the function assign a value to the c_int object, and capture its return code (True for success, False for failure)
    ok = pdfium_c.FPDF_GetFileVersion(pdf, c_version)
    # If successful, get the Python int by accessing the `value` attribute of the c_int object
    # Otherwise, set the variable to None (in other cases, it may be desired to raise an exception instead)
    version = c_version.value if ok else None
    
  • If an array is required as output parameter, you can initialise one like this (in general terms):

    # long form
    array_type = (c_type * array_length)
    array_object = array_type()
    # short form
    array_object = (c_type * array_length)()
    

    Example: Getting view mode and target position from a destination object returned by some other function.

    # (Assuming `dest` is an FPDF_DEST)
    n_params = ctypes.c_ulong()
    # Create a C array to store up to four coordinates
    view_pos = (pdfium_c.FS_FLOAT * 4)()
    view_mode = pdfium_c.FPDFDest_GetView(dest, n_params, view_pos)
    # Slice the array to the actual number of coordinates. This implicitly converts the C array to a Python list.
    view_pos = view_pos[:n_params.value]
    
  • For string output parameters, callers needs to provide a sufficiently long, pre-allocated buffer. This may work differently depending on what type the function requires, which encoding is used, whether the number of bytes or units is returned, and whether space for a NUL terminator is included or not. Carefully review the documentation of the function in question to fulfill its requirements.

    There are many different ways of handling output strings; this section describes the strategy used by pypdfium2's helpers.

    We will first import the codecs.decode() function which can be used on generic memory (whereas the .decode() method is only available on bytes or bytearrays):

    from codecs import decode
    

    Example A: Getting the title string of a bookmark.

    # (Assuming `bookmark` is an FPDF_BOOKMARK)
    # First call to get the required number of bytes (not units!), including space for a NUL terminator
    n_bytes = pdfium_c.FPDFBookmark_GetTitle(bookmark, None, 0)
    # Initialise the output buffer
    buffer = ctypes.create_string_buffer(n_bytes)
    # Second call with the actual buffer
    pdfium_c.FPDFBookmark_GetTitle(bookmark, buffer, n_bytes)
    # Decode to string, cutting off the NUL terminator (encoding: UTF-16LE)
    title = decode(memoryview(buffer)[:n_bytes-2], "utf-16-le")
    

    Example B: Extracting text in given boundaries.

    # (Assuming `textpage` is an FPDF_TEXTPAGE and the boundary variables are set)
    # Store common arguments for the two calls
    args = (textpage, left, top, right, bottom)
    # First call to get the required number of units (not bytes!).
    # A possible NUL terminator is not included.
    n_units = pdfium_c.FPDFText_GetBoundedText(*args, None, 0)
    # If no characters were found, return an empty string
    if n_units <= 0:
        return ""
    # Create the buffer. This particular API does not insist on space for a NUL terminator.
    # Skip so we don't need to cut it off later.
    buffer = (ctypes.c_ushort * n_units)()
    # Second call with the actual buffer
    pdfium_c.FPDFText_GetBoundedText(*args, buffer, n_units)
    # Decode to string (You may want to pass errors="ignore" to skip possible errors in the PDF's encoding)
    text = decode(buffer, "utf-16-le")
    

    There are also APIs that return the number of bytes but expect a multi-byte type, e.g. FPDF_WCHAR. In that case, you can calculate the number of units via -(n_bytes // -ctypes.sizeof(pdfium_c.FPDF_WCHAR)) (this does a ceil division).

  • Not only are there different ways of string output that need to be handled according to the requirements of the function in question. String input, too, can work differently depending on encoding and type. We have already discussed FPDF_LoadDocument(), which takes a UTF-8 encoded string as char*. A different examples is FPDFText_FindStart(), which needs a UTF-16LE encoded string, given as unsigned short*:

    # (Assuming `text` is a str and `textpage` an FPDF_TEXTPAGE)
    # Add the NUL terminator and encode as UTF-16LE
    enc_text = (text + "\x00").encode("utf-16-le")
    # cast `enc_text` to a c_ushort pointer
    text_ptr = ctypes.cast(enc_text, ctypes.POINTER(ctypes.c_ushort))
    search = pdfium_c.FPDFText_FindStart(textpage, text_ptr, 0, 0)
    
  • Leaving strings, let's suppose you have a C memory buffer allocated by PDFium and wish to read its data. PDFium will provide you with a pointer to the first item of the byte array. To access the data, you'll want to re-interpret the pointer as an array view with .from_address():

    # (Assuming `bitmap` is an FPDF_BITMAP and `size` is the expected number of bytes in the buffer)
    # FPDFBitmap_GetBuffer() has c_void_p as restype, which ctypes will auto-resolve to int or None
    buffer_ptrval = pdfium_c.FPDFBitmap_GetBuffer(bitmap)
    assert buffer_ptrval  # make sure it's non-null
    # Get an actual pointer object so we can access .contents
    buffer_ptr = ctypes.cast(buffer_ptrval, ctypes.POINTER(ctypes.c_ubyte))
    # Buffer as ctypes array (a view of the original buffer, will be unavailable as soon as the bitmap is destroyed)
    c_buffer = (ctypes.c_ubyte * size).from_address( ctypes.addressof(buffer_ptr.contents) )
    # Buffer as Python bytes (independent copy)
    py_buffer = bytes(c_buffer)
    

    Note that you can achieve the same result with ctypes.cast(ptr, POINTER(type * size)).contents, but this is somewhat problematic since ctypes used to cache pointer types eternally with Python < 3.14 (as size may vary, this can lead to memory leak like scenarios with long-running applications).

  • Writing data from Python into a C buffer works in a similar fashion:

    # (Assuming `buffer_ptr` is a pointer to the first item of a C buffer to write into,
    #  `size` the number of bytes it can store, and `py_buffer` a Python byte buffer)
    buffer = (ctypes.c_ubyte * size).from_address( ctypes.addressof(buffer_ptr.contents) )
    # Read from the Python buffer, starting at its current position, directly into the C buffer
    # (until the target is full or the end of the source is reached)
    n_bytes = py_buffer.readinto(buffer)  # returns the number of bytes read
    
  • If you wish to check whether two objects returned by PDFium are the same, the is operator won't help because ctypes does not have original object return (OOR), i.e. new, equivalent Python objects are created each time, although they might represent one and the same C object.6 That's why you'll want to use ctypes.addressof() to get the memory addresses of the underlying C object. For instance, this is used to avoid infinite loops on circular bookmark references when iterating through the document outline:

    # (Assuming `pdf` is an FPDF_DOCUMENT)
    seen = set()
    bookmark = pdfium_c.FPDFBookmark_GetFirstChild(pdf, None)
    while bookmark:
        # bookmark is a pointer, so we need to use its `contents` attribute to get the object the pointer refers to
        # (otherwise we'd only get the memory address of the pointer itself, which would result in random behaviour)
        address = ctypes.addressof(bookmark.contents)
        if address in seen:
            break  # circular reference detected
        else:
            seen.add(address)
        bookmark = pdfium_c.FPDFBookmark_GetNextSibling(pdf, bookmark)
    
  • In many situations, callback functions come in handy.7 Thanks to ctypes, it is seamlessly possible to use callbacks across Python/C language boundaries.

    Example: Loading a document from a Python buffer. This way, file access can be controlled in Python while the data does not need to be in memory at once.

    import os
    
    # Factory class to create callable objects holding a reference to a Python buffer
    class _reader_class:
      
      def __init__(self, py_buffer):
          self.py_buffer = py_buffer
      
      def __call__(self, _, position, buffer_ptr, size):
          # Write data from Python buffer into C buffer, as explained before
          c_buffer = (ctypes.c_ubyte * size).from_address( ctypes.addressof(buffer_ptr.contents) )
          self.py_buffer.seek(position)
          self.py_buffer.readinto(c_buffer)
          return 1  # non-zero return code for success
    
    # (Assuming py_buffer is a Python file buffer, e. g. io.BufferedReader)
    # Get the length of the buffer
    py_buffer.seek(0, os.SEEK_END)
    file_len = py_buffer.tell()
    py_buffer.seek(0)
    
    # Set up an interface structure for custom file access
    fileaccess = pdfium_c.FPDF_FILEACCESS()
    fileaccess.m_FileLen = file_len
    
    # Assign the callback, wrapped in its CFUNCTYPE
    fileaccess.m_GetBlock = type(fileaccess.m_GetBlock)( _reader_class(py_buffer) )
    
    # Finally, load the document
    pdf = pdfium_c.FPDF_LoadCustomDocument(fileaccess, None)
    
  • When using the raw API, special care needs to be taken regarding object lifetime, considering that Python may garbage collect objects as soon as their reference count reaches zero. However, the interpreter has no way of magically knowing how long the underlying resources of a Python object might still be needed on the C side, so measures need to be taken to keep such objects referenced until PDFium does not depend on them anymore.

    If resources need to remain valid after the time of a function call, PDFium docs usually indicate this clearly. Ignoring requirements on object lifetime will lead to memory corruption (commonly resulting in a segfault sooner or later).

    For instance, the docs on FPDF_LoadCustomDocument() state that

    The application must keep the file resources |pFileAccess| points to valid until the returned FPDF_DOCUMENT is closed. |pFileAccess| itself does not need to outlive the FPDF_DOCUMENT.

    This means that the callback function and the Python buffer need to be kept alive as long as the FPDF_DOCUMENT is used. This can be achieved by referencing these objects in an accompanying class, e. g.

    class PdfDataHolder:
        
        def __init__(self, buffer, function):
            self.buffer = buffer
            self.function = function
        
        def close(self):
            # Make sure both objects remain available until this function is called
            # No-op id() call to denote that the object needs to stay in memory up to this point
            id(self.function)
            self.buffer.close()
    
    # ... set up an FPDF_FILEACCESS structure
    
    # (Assuming `py_buffer` is the buffer and `fileaccess` the FPDF_FILEACCESS interface)
    data_holder = PdfDataHolder(py_buffer, fileaccess.m_GetBlock)
    pdf = pdfium_c.FPDF_LoadCustomDocument(fileaccess, None)
    
    # ... work with the pdf
    
    # Close the PDF to free resources
    pdfium_c.FPDF_CloseDocument(pdf)
    # Close the data holder, to keep the object itself and thereby the objects it
    # references alive up to this point, as well as to release the buffer
    data_holder.close()
    
  • Finally, let's finish this guide with an example how to render the first page of a document to a PIL image in RGBA color format.

    import math
    import ctypes
    import os.path
    import PIL.Image
    import pypdfium2.raw as pdfium_c
    
    # Load the document
    filepath = os.path.abspath("tests/resources/render.pdf")
    pdf = pdfium_c.FPDF_LoadDocument((filepath+"\x00").encode("utf-8"), None)
    
    # Check page count to make sure it was loaded correctly
    page_count = pdfium_c.FPDF_GetPageCount(pdf)
    assert page_count >= 1
    
    # Load the first page and get its dimensions
    page = pdfium_c.FPDF_LoadPage(pdf, 0)
    width  = math.ceil(pdfium_c.FPDF_GetPageWidthF(page))
    height = math.ceil(pdfium_c.FPDF_GetPageHeightF(page))
    
    # Create a bitmap
    # (Note, pdfium is faster at rendering transparency if we use BGRA rather than BGRx)
    use_alpha = pdfium_c.FPDFPage_HasTransparency(page)
    bitmap = pdfium_c.FPDFBitmap_Create(width, height, int(use_alpha))
    # Fill the whole bitmap with a white background
    # The color is given as a 32-bit integer in ARGB format (8 bits per channel)
    pdfium_c.FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 0xFFFFFFFF)
    
    # Store common rendering arguments
    render_args = (
        bitmap,  # the bitmap
        page,    # the page
        # positions and sizes are to be given in pixels and may exceed the bitmap
        0,       # left start position
        0,       # top start position
        width,   # horizontal size
        height,  # vertical size
        0,       # rotation (as constant, not in degrees!)
        pdfium_c.FPDF_LCD_TEXT | pdfium_c.FPDF_ANNOT,  # rendering flags, combined with binary or
    )
    
    # Render the page
    pdfium_c.FPDF_RenderPageBitmap(*render_args)
    
    # Get the value of a pointer to the first item of the buffer
    buffer_ptrval = pdfium_c.FPDFBitmap_GetBuffer(bitmap)
    assert buffer_ptrval, "buffer pointer value must be non-null"
    # Cast the pointer value to an actual pointer object so we can access .contents
    buffer_ptr = ctypes.cast(buffer_ptrval, ctypes.POINTER(ctypes.c_ubyte))
    # Re-interpret as array
    buffer = (ctypes.c_ubyte * (width * height * 4)).from_address(ctypes.addressof(buffer_ptr.contents))
    
    # Create a PIL image from the buffer contents
    img = PIL.Image.frombuffer("RGBA", (width, height), buffer, "raw", "BGRA", 0, 1)
    # Save it as file
    img.save("out.png")
    
    # Free resources
    pdfium_c.FPDFBitmap_Destroy(bitmap)
    pdfium_c.FPDF_ClosePage(page)
    pdfium_c.FPDF_CloseDocument(pdf)
    

Command-line Interface

pypdfium2 also ships with a simple command-line interface, providing access to key features of the support model in a shell environment (e. g. rendering, content extraction, document inspection, page rearranging, ...).

The primary motivation behind this is to have a nice testing interface, but it may be helpful in a variety of other situations as well. Usage should be largely self-explanatory, assuming some familiarity with the command-line. See pypdfium2 --help or pypdfium2 $SUBCOMMAND --help for available commands and options.

If you wish to call pypdfium2's CLI through python -m, note that the module name is pypdfium2_cli (not just pypdfium2), unlike the entrypoint script.

Licensing

pypdfium2 itself is available by the terms and conditions of Apache-2.0 / BSD-3-Clause. Documentation and examples of pypdfium2 are licensed under CC-BY-4.0. pypdfium2 includes SPDX headers in source files. License information for data files is provided in REUSE.toml as per the reuse standard.

PDFium is available under "a BSD-style license that can be found in [its] LICENSE file".
Various other open-source licenses apply to dependencies included with PDFium. PDFium's license as well as dependency licenses have to be shipped with binary distributions.
See the BUILD_LICENSES/ directory, or the licenses shipped with our wheel builds.

PDFium's dependencies might change over time. Please notify us if you think a relevant license is missing.

To the author's knowledge, pypdfium2 is one of the rare Python libraries capable of PDF rendering while not being covered by strong-copyleft licenses.8

Note that the exact licensing situation depends on the build config/environment used.
In particular, a subset of pypdfium2 builds may link with the libgcc runtime library. Check the builds you use and, if affected, libgcc's license to evaluate if that's OK for your use.

Issues / Contributions

While using pypdfium2, you might encounter bugs or missing features. In this case, feel free to open an issue or discussion thread. If applicable, include details such as tracebacks, OS and CPU type, as well as the versions of pypdfium2 and used dependencies.

Roadmap:

  • pypdfium2
    • Issues panel: Initial bug reports and feature requests. May need to be transferred to dependencies.
    • Discussions page: General questions and suggestions.
  • PDFium
    • Bug tracker: Issues in PDFium. Beware: The bridge between Python and C increases the probability of integration issues or API misuse. The symptoms can often make it look like a PDFium bug while it is not.
    • Mailing list: Questions regarding PDFium usage.
  • pdfium-binaries: Binary builder.
  • ctypesgen: Bindings generator (fork). See also upstream.

Policy

Given this is a volunteer open-source project, it is possible you may not get a response to your issue, or it may be closed without much feedback. Conversations may be locked if we feel like our attention is getting DDOSed. We may not have time to provide much usage support.

The same applies to Pull Requests. We will accept contributions only if we find them suitable. Do not reach out with a strong expectation to get your change merged; it is solely up to the repository owner to decide if and when a PR will be merged, and PRs that we consider unsuitable may be rejected without further ado. If the code owner decides a change is inappropriate, that's it, and further discussion will not be accepted. Any attempts to pressure us to merge a PR will not be tolerated, and may result in the offender being blocked.

No AI issues and PRs

AI issues and PRs are banned from this project.

Any issues or PRs that exhibit the typical characteristics of low-quality generative AI will be labelled as spam / ai and closed/locked immediately, no matter how important they may claim to be.

Our issue and PR templates make it quite plain that AI is not allowed, so users who violate this policy should not be surprised to find themselves blocked.

This announcement offers some more background as to why this decision was reached.

Known limitations

Incompatibility with Threading

PDFium is inherently not thread-safe. See the API docs for more information.

Risk of unknown object lifetime violations

As outlined in the raw API section, it is essential that Python-managed resources remain available as long as they are needed by PDFium.

The problem is that the Python interpreter may garbage collect objects with reference count zero at any time, so it can happen that an unreferenced but still required object by chance stays around long enough before it is garbage collected. However, it could also disappear too soon and cause breakage. Such dangling objects result in non-deterministic memory issues that are hard to debug. If the timeframe between reaching reference count zero and removal is sufficiently large and roughly consistent across different runs, it is even possible that mistakes regarding object lifetime remain unnoticed for a long time.

Although we intend to develop helpers carefully, it cannot be fully excluded that unknown object lifetime violations might still be lurking around somewhere, especially if unexpected requirements were not documented by the time the code was written.

Missing raw PDF access

As of this writing, PDFium's public interface does not provide access to the raw PDF data structure (see issue 1694). It does not expose APIs to read/write PDF dictionaries, streams, name/number trees, etc. Instead, it merely offers a predefined set of abstracted functions. This considerably limits the library's potential, compared to other products such as pikepdf.

Limitations of ABI bindings

PDFium's non-public backend would provide extended capabilities, including raw access, but it is written in C++, which (unlike pure C) does not result in a stable ABI, so we cannot use it with ctypes. This means it's out of scope for this project.

Also, while ABI bindings tend to be more convenient, they have some technical drawbacks compared to API bindings (see e.g. 1, 2)

Development

Long lines

We do not hard wrap long lines. It is recommended to set up automatic word wrap in your text editor, e.g. VS Code:

editor.wordWrap = bounded
editor.wordWrapColumn = 100

Command recipes

We use the just command runner, which can be seen as a modern, flexible alternative to make. In particular, there's no good way to pass through positional arguments with make.

Run just -l (or open the justfile) to view the available commands.

Docs

pypdfium2 has API documentation built with Sphinx, which can be rendered to various formats, including HTML:

sphinx-build -b html ./docs/source ./docs/build/html/
just docs-build  # short alias

Docs are primarily hosted on readthedocs.org. It may be configured using a .readthedocs.yaml file (see instructions), and the administration page on the web interface. RTD theoretically supports hosting multiple versions, but currently, we only host one build for the latest release through the stable branch. New builds are automatically triggered by a webhook whenever a linked branch is pushed.

Additionally, one doc build can also be hosted on GitHub Pages. It is implemented with a CI workflow, which is supposed to be triggered automatically on release. This provides us with full control over build env and used commands, whereas RTD may be less liberal in this regard.

Testing

pypdfium2 contains a small test suite to verify the library's functionality. It is written with pytest:

python -m pytest tests/  # or `just test`

Pass -sv to get more detailed output. Environment variables used by the CLI are also honored in the test suite: PYPDFIUM_LOGLEVEL, DEBUG_AUTOCLOSE, DEBUG_SYSFONTS, DEBUG_UNSUPPORTED. See pypdfium2 --help for description.

To get code coverage statistics, you may call

just coverage

Sometimes, it can also be helpful to test code on many PDFs.9 In this case, the command-line interface and find come in handy:

# Example A: Analyse PDF images (in the current working directory)
find . -name '*.pdf' -exec bash -c "echo \"{}\" && pypdfium2 pageobjects \"{}\" --filter image" \;
# Example B: Parse PDF table of contents
find . -name '*.pdf' -exec bash -c "echo \"{}\" && pypdfium2 toc \"{}\"" \;

Dependents & supply chain considerations

As of 2026, pypdfium2 is being relied on by some fairly popular dependents, including ocrmypdf.

This results in pypdfium2 being part of a large dependency tree and having rather high monthly download count.

This causes us to prioritize stability and take some caution with new releases. This translates to a slowed-down release schedule and more interest in consolidation & code quality improvement than new features which add maintenance burden.

We also highly recommend the use of lockfiles and dependency cooldowns, since the main thing to be concerned about is an actual supply chain attack (in the sense of a project being compromised). Edge-case memory inaccuracies might get assigned CVEs with absurdly high scores, but a memory bug isn't an exploit of its own – it still takes malicious input to that. Since there is no way to ever be sure to be free of memory bugs in a large C(++) codebase, this is just something you have to calculate with. Conversely, malicious input might well be able to abuse a yet-unknown issue ("zero-day exploit"), so touching a malicious source is always an extremely high risk of its own accord. Therefore, make sure you don't work with untrusted, potentially malicious data, and/or use a sandboxed environment.

Thanks to10

  • Benoît Blanchon: Author/Maintainer of PDFium binaries and patches.
  • Yinlin Hu: pypdfium prototype and kuafu PDF viewer.
  • Mike Kroutikov: Examples on how to use PDFium from Python in redstork, redstork-ui and pdfbrain.
  • Matthieu Darbois: Provider of static clang images – native performance builds in otherwise qemu-driven containers. Help with bypassing libclang_rt dependency.
  • wojiushixiaobai: Helpful pointers and draft workflow for cibuildwheel. Supporting extra Linux architectures via emulated containers.
  • Christian Heimes: RPM packaging for pdfium. Showing how to build pdfium natively without Google's toolchain. Big-endian fixes.
  • Marvin Gießing: Investigation on building PDFium for a then unhandled Linux architecture (ppc64le).
  • Adam Huganir: Help with maintenance and development decisions since the beginning of the project.
  • Tim Head: Original idea for Python bindings to PDFium with ctypesgen in wowpng.
  • kobaltcore: Bug fix for PdfDocument.save().
  • Anderson Bravalheri: Help with PEP 517/518 compliance. Hint to use an environment variable rather than separate setup files.
  • Bastian Germann: Help with inclusion of licenses for third-party components of PDFium.

... and further code contributors (GitHub stats).

If you have contributed to this project but are not mentioned here yet, please let us know.

History

PDFium

The PDFium code base was originally developed as part of the commercial Foxit SDK, before being acquired and open-sourced by Google, who maintain PDFium independently ever since, while Foxit continue to develop their SDK closed-source.

pypdfium2

pypdfium2 is the successor of pypdfium and pypdfium-reboot.

Inspired by wowpng, the first known proof of concept Python binding to PDFium using ctypesgen, the initial pypdfium package was created. It had to be updated manually, which did not happen frequently. There were no platform-specific wheels, but only a single wheel that contained binaries for 64-bit Linux, Windows and macOS.

pypdfium-reboot then added a script to automate binary deployment and bindings generation to simplify regular updates. However, it was still not platform specific.

pypdfium2 is a full rewrite of pypdfium-reboot to build platform-specific wheels and consolidate the setup scripts. Further additions include ...

  • A CI workflow to automatically release new wheels at a defined schedule
  • Convenience support models that wrap the raw PDFium/ctypes API
  • Test code
  • A script to build PDFium from source
  1. If this did not reveal the full version, setup will try to resolve it with a git web request. Set GIVEN_FULLVER=$major.$minor.$build.$patch or IGNORE_FULLVER=1 to override that behavior. ↩

  2. Luckily, upstream tend to be careful not to change the ABI of existing stable APIs, but they don't mind ABI-breaking changes to APIs that have not been promoted to stable tier yet, and pypdfium2 uses many of them, so it is still prudent to care about downstream ABI safety as well (it always is). You can read more about upstream's policy here. ↩

  3. Intended for packaging, so that wheels can be crafted for any platform without access to a native host. ↩

  4. Unfortunately, no recent HTML-rendered docs are available for PDFium at the moment. ↩

  5. From the auto-generated bindings file. We maintain a reference copy at autorelease/bindings.py. Or if you have an editable install, there will also be src/pypdfium2_raw/bindings.py. ↩

  6. Confer the ctypes documentation on Pointers. ↩

  7. e. g. incremental read/write, management of progressive tasks, ... ↩

  8. Other mature, liberal-licensed PDF rendering libraries include pdf.js (JavaScript) and Apache PDFBox (Java). They can be accessed from Python in principle, as demonstrated in gists (pdfbox, pdfjs), but there don't seem to be through, pythonic bindings beyond that. Lately, some new options have surfaced, e.g. docling-parse. Also, there is a flood of AI/vibe-coded "projects" (for want of a better term), but we strongly recommend against their use. Don't fall for AI crap. You really wanna stick with mature, high-quality codebases that have been around well before the AI boom and are genuinely human authored and understood. ↩

  9. For instance, one could use the testing corpora of open-source PDF libraries (pdfium, pikepdf/ocrmypdf, mupdf/ghostscript, tika/pdfbox, pdfjs, ...) ↩

  10. People listed in this section may not necessarily have contributed any copyrightable code to the repository. Many have rather helped with ideas, or contributions to dependencies of pypdfium2. ↩

Metadata

Release files for pypdfium2 5.15.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pypdfium2 5.15.1
File Size Uploaded Provenance Actions
pypdfium2-5.15.1.tar.gz 696.1 kB With provenance Details for pypdfium2-5.15.1.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for pypdfium2 5.15.1
File Actions
pypdfium2-5.15.1-py3-none-win_arm64.whl Python 3 none Windows ARM64 Details for pypdfium2-5.15.1-py3-none-win_arm64.whl
pypdfium2-5.15.1-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details for pypdfium2-5.15.1-py3-none-win_amd64.whl
pypdfium2-5.15.1-py3-none-win32.whl Python 3 none Windows x86-32 Details for pypdfium2-5.15.1-py3-none-win32.whl
pypdfium2-5.15.1-py3-none-pyemscripten_2026_0_wasm32.whl Python 3 none PyEmscripten 2026.0+ WebAssembly Details for pypdfium2-5.15.1-py3-none-pyemscripten_2026_0_wasm32.whl
pypdfium2-5.15.1-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details for pypdfium2-5.15.1-py3-none-musllinux_1_2_x86_64.whl
pypdfium2-5.15.1-py3-none-musllinux_1_2_s390x.whl Python 3 none Linux musl 1.2+ IBM System/390x Details for pypdfium2-5.15.1-py3-none-musllinux_1_2_s390x.whl
pypdfium2-5.15.1-py3-none-musllinux_1_2_riscv64.whl Python 3 none Linux musl 1.2+ RISC-V 64 Details for pypdfium2-5.15.1-py3-none-musllinux_1_2_riscv64.whl
pypdfium2-5.15.1-py3-none-musllinux_1_2_ppc64le.whl Python 3 none Linux musl 1.2+ PowerPC 64-le Details for pypdfium2-5.15.1-py3-none-musllinux_1_2_ppc64le.whl
pypdfium2-5.15.1-py3-none-musllinux_1_2_i686.whl Python 3 none Linux musl 1.2+ x86-32 Details for pypdfium2-5.15.1-py3-none-musllinux_1_2_i686.whl
pypdfium2-5.15.1-py3-none-musllinux_1_2_armv7l.whl Python 3 none Linux musl 1.2+ ARMv7l Details for pypdfium2-5.15.1-py3-none-musllinux_1_2_armv7l.whl
pypdfium2-5.15.1-py3-none-musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64 Details for pypdfium2-5.15.1-py3-none-musllinux_1_2_aarch64.whl
pypdfium2-5.15.1-py3-none-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl Python 3 none Linux glibc 2.39+ RISC-V 64, Linux glibc 2.34+ RISC-V 64 Details for pypdfium2-5.15.1-py3-none-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl
pypdfium2-5.15.1-py3-none-manylinux_2_27_s390x.manylinux_2_28_s390x.whl Python 3 none Linux glibc 2.28+ IBM System/390x, Linux glibc 2.27+ IBM System/390x Details for pypdfium2-5.15.1-py3-none-manylinux_2_27_s390x.manylinux_2_28_s390x.whl
pypdfium2-5.15.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details for pypdfium2-5.15.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
pypdfium2-5.15.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl Python 3 none Linux glibc 2.17+ PowerPC 64-le Details for pypdfium2-5.15.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
pypdfium2-5.15.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl Python 3 none Linux glibc 2.17+ x86-32 Details for pypdfium2-5.15.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl
pypdfium2-5.15.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl Python 3 none Linux glibc 2.17+ ARMv7l Details for pypdfium2-5.15.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
pypdfium2-5.15.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details for pypdfium2-5.15.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
pypdfium2-5.15.1-py3-none-macosx_13_0_x86_64.whl Python 3 none macOS 13.0+ x86-64 Details for pypdfium2-5.15.1-py3-none-macosx_13_0_x86_64.whl
pypdfium2-5.15.1-py3-none-macosx_13_0_arm64.whl Python 3 none macOS 13.0+ ARM64 Details for pypdfium2-5.15.1-py3-none-macosx_13_0_arm64.whl
pypdfium2-5.15.1-py3-none-android_23_armeabi_v7a.whl Python 3 none Android API level 23+ ARM EABI v7a Details for pypdfium2-5.15.1-py3-none-android_23_armeabi_v7a.whl
pypdfium2-5.15.1-py3-none-android_23_arm64_v8a.whl Python 3 none Android API level 23+ ARM64 v8a Details for pypdfium2-5.15.1-py3-none-android_23_arm64_v8a.whl

Total release size: 93.7 MB

Release files / pypdfium2-5.15.1.tar.gz

Download URL pypdfium2-5.15.1.tar.gz
Size 696.1 kB
Tags Source
SHA-256 checksum
How to use checksums
b4656a0efce21be7f2429038ce3fbb417644565fc50858e65aaed23801f33d42
BLAKE2b-256 checksum
How to use checksums
7c175845ffd945c8b2783b04d16000daf83658e37a8efb91d692cb6e3c99b040
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-win_arm64.whl

Download URL pypdfium2-5.15.1-py3-none-win_arm64.whl
Size 3.9 MB
Tags Python 3 Windows ARM64
SHA-256 checksum
How to use checksums
f711092ba714959c6bc04eb747cbf9d188875b842e1fe8ecd3aa61b201572737
BLAKE2b-256 checksum
How to use checksums
986382fbff983c077ef0f97932e3cfbdbcf1bf71ec0933358959ef69fcf9f797
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-win_amd64.whl

Download URL pypdfium2-5.15.1-py3-none-win_amd64.whl
Size 4.2 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
9cf0fda610da25ef9c1e1234a85020a3275645ab95f7f74f67840bb5f8de10f7
BLAKE2b-256 checksum
How to use checksums
a88242aa61264fcc9fec241b34e93caffd95bcdabe9b1960bfce6258374b55fa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-win32.whl

Download URL pypdfium2-5.15.1-py3-none-win32.whl
Size 4.0 MB
Tags Python 3 Windows x86-32
SHA-256 checksum
How to use checksums
597260e1ec323da93ecdba54aec1fe10181657a8c6a98fa74812293b8dfc7b0b
BLAKE2b-256 checksum
How to use checksums
737f7fb7901e104ac4dfbbc42f14067a60d6f25c1fa0b673f9138bec37a7487d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-pyemscripten_2026_0_wasm32.whl

Download URL pypdfium2-5.15.1-py3-none-pyemscripten_2026_0_wasm32.whl
Size 2.7 MB
Tags PyEmscripten 2026.0+ WebAssembly Python 3
SHA-256 checksum
How to use checksums
c9adfded14ba72d10e6cfc399fbf657b2738bfb9d1540266e1a4c61caba7a033
BLAKE2b-256 checksum
How to use checksums
17335d1f9796d61fb2a82183349c7c36717ce84c98a5ff931ed594b57f39590d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-musllinux_1_2_x86_64.whl

Download URL pypdfium2-5.15.1-py3-none-musllinux_1_2_x86_64.whl
Size 5.2 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
b69b8b8edcc490ce5a9fba10d3aedd0a45f017f1c0e05651c6e9ead6f153256b
BLAKE2b-256 checksum
How to use checksums
1fbafee881eff06b3ab8ecc5cb1b0ae779083ec7d3450b7d14e79314b2fd7b77
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-musllinux_1_2_s390x.whl

Download URL pypdfium2-5.15.1-py3-none-musllinux_1_2_s390x.whl
Size 5.2 MB
Tags Linux musl 1.2+ IBM System/390x Python 3
SHA-256 checksum
How to use checksums
f024cc6ccbc7cf94216856c3be6a63ea9e2b2a4c4e50653334ed6aa4d0ebab1d
BLAKE2b-256 checksum
How to use checksums
0739ced95e20717564d31584ced4273167bb1accf369463ef29c0e4d206b3b7d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-musllinux_1_2_riscv64.whl

Download URL pypdfium2-5.15.1-py3-none-musllinux_1_2_riscv64.whl
Size 4.7 MB
Tags Linux musl 1.2+ RISC-V 64 Python 3
SHA-256 checksum
How to use checksums
bffc1f1e01d32cabc76510cc770080113a42975a98d8ac0de78e58c292df81e8
BLAKE2b-256 checksum
How to use checksums
4750c01bf260c07c12be2cfc0b3ed82cc80516caf99e71556df73de150a88b62
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-musllinux_1_2_ppc64le.whl

Download URL pypdfium2-5.15.1-py3-none-musllinux_1_2_ppc64le.whl
Size 5.3 MB
Tags Linux musl 1.2+ PowerPC 64-le Python 3
SHA-256 checksum
How to use checksums
1ea50ab4636a89807f872f322016c669662f3f5a90f99015fbce62d079a850a8
BLAKE2b-256 checksum
How to use checksums
342b0e4a40a597afa3ef4a943f4bb8c3c044c329beb57fc2e31f4dda8e4d28a6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-musllinux_1_2_i686.whl

Download URL pypdfium2-5.15.1-py3-none-musllinux_1_2_i686.whl
Size 5.4 MB
Tags Linux musl 1.2+ x86-32 Python 3
SHA-256 checksum
How to use checksums
60f449808c13acefbec679f24fef3bb72a71d73a851b6da56639919367c1690a
BLAKE2b-256 checksum
How to use checksums
e5458d860481c0891f6168a732ac8d963096ef179346a99cbbf09c62ca8d7f40
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-musllinux_1_2_armv7l.whl

Download URL pypdfium2-5.15.1-py3-none-musllinux_1_2_armv7l.whl
Size 4.6 MB
Tags Linux musl 1.2+ ARMv7l Python 3
SHA-256 checksum
How to use checksums
74760230b998b62c0b39a9008211e295759fe493699b1634a3191b3b0ec05cf6
BLAKE2b-256 checksum
How to use checksums
650f7b77814bc32316684c5af4b22dcb81616572dd04af7ff9116bae5433dc4f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-musllinux_1_2_aarch64.whl

Download URL pypdfium2-5.15.1-py3-none-musllinux_1_2_aarch64.whl
Size 5.1 MB
Tags Linux musl 1.2+ ARM64 Python 3
SHA-256 checksum
How to use checksums
8031a4550fb492999bb935cbe44ff9e63ddc4f2f3eaa68764d06fa6c1da28b0e
BLAKE2b-256 checksum
How to use checksums
4f425f4c6372a7c2b9ebfa96ea3dc67f8eea7662b70da9b37a9337433d396649
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl

Download URL pypdfium2-5.15.1-py3-none-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl
Size 4.1 MB
Tags Linux glibc 2.34+ RISC-V 64 Linux glibc 2.39+ RISC-V 64 Python 3
SHA-256 checksum
How to use checksums
b0aa166a3df7e49db91e34603879a1da2505eed9ed5d036ccef844a4cfa61e43
BLAKE2b-256 checksum
How to use checksums
d611327f00ef1154f873978ccebcc70a5d2465add6d277b682ec3891a1b485a6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-manylinux_2_27_s390x.manylinux_2_28_s390x.whl

Download URL pypdfium2-5.15.1-py3-none-manylinux_2_27_s390x.manylinux_2_28_s390x.whl
Size 4.2 MB
Tags Linux glibc 2.27+ IBM System/390x Linux glibc 2.28+ IBM System/390x Python 3
SHA-256 checksum
How to use checksums
9834b5d5e569c72bafa0f8c9ab81fa4357aa47d83d23bb0afa4a59aae99cce28
BLAKE2b-256 checksum
How to use checksums
641b55ff818880c60feb8a8fe42a4172f69c9316ac27aa73c43083e6f1b98ccc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL pypdfium2-5.15.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 4.0 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
e479df7f9260865554f301889bf1afcdf9aaf5e2ad98c69797a2ebaa1c5e3a3b
BLAKE2b-256 checksum
How to use checksums
132dce96360c120a1c20213deef6c8df127aaead5e86360aa370d148bd3514df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl

Download URL pypdfium2-5.15.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Size 4.5 MB
Tags Linux glibc 2.17+ PowerPC 64-le Python 3
SHA-256 checksum
How to use checksums
9488aac518ab8161116dbec2dde323818c3d873c61f32b354c08cfe49ecb259a
BLAKE2b-256 checksum
How to use checksums
c6d1cd01a034770e32f8061849ffc5a284a575b97887101333f958ca5d06cc8f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl

Download URL pypdfium2-5.15.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl
Size 4.1 MB
Tags Linux glibc 2.17+ x86-32 Python 3
SHA-256 checksum
How to use checksums
ccfb3e777e7eeec0d4e8c5ca82af4908b725df5a3417fc4b34ac44ae34f61b19
BLAKE2b-256 checksum
How to use checksums
013c5001d614abf7741a36e849cd305e00fc81b56b9040d746268bbb70f13602
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl

Download URL pypdfium2-5.15.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Size 3.6 MB
Tags Linux glibc 2.17+ ARMv7l Python 3
SHA-256 checksum
How to use checksums
701418fd3e75f8a8e60a68833aa1590feb78be37d73ac69818ee6b1ede902001
BLAKE2b-256 checksum
How to use checksums
6424dc6fd68ce47c146c538dae2b8dc96fc9903f4ac5c0e9f2ed3e88dd84b0cb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL pypdfium2-5.15.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 3.9 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
633050b79987ad8aba13294a0ca500f75727e8f2d9be32896d7cb27e0e0a50e6
BLAKE2b-256 checksum
How to use checksums
b65b2b02d9a2027463a997082ca90d6f01a03f4d468563369a712238af88c9d7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-macosx_13_0_x86_64.whl

Download URL pypdfium2-5.15.1-py3-none-macosx_13_0_x86_64.whl
Size 3.9 MB
Tags Python 3 macOS 13.0+ x86-64
SHA-256 checksum
How to use checksums
d3086b72825c3b976d38fa6ca015703e26e615c1de7d6f48e26448268fe1d7aa
BLAKE2b-256 checksum
How to use checksums
3e887d2f8c158f8ff9ad975e01908942283e465fbde80a7756944fd29360d64b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-macosx_13_0_arm64.whl

Download URL pypdfium2-5.15.1-py3-none-macosx_13_0_arm64.whl
Size 3.7 MB
Tags Python 3 macOS 13.0+ ARM64
SHA-256 checksum
How to use checksums
8cb84f21ed36428ecf483e136ccbe71fc258ee730eae87d69baa3e178e56c8d6
BLAKE2b-256 checksum
How to use checksums
33c69d118ffda2612d65471ccc598c1a0fc4c17222c751fba47f0351d5ba580c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-android_23_armeabi_v7a.whl

Download URL pypdfium2-5.15.1-py3-none-android_23_armeabi_v7a.whl
Size 3.0 MB
Tags Android API level 23+ ARM EABI v7a Python 3
SHA-256 checksum
How to use checksums
0369e796ce18863df3530caf3dc3034ccd7064007a18df39e6cfd8304dea7f9a
BLAKE2b-256 checksum
How to use checksums
27837b8e356f48313e8cc9d9fb7834007a03adecf8dfba7a0094bf9f76d8d1ee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / pypdfium2-5.15.1-py3-none-android_23_arm64_v8a.whl

Download URL pypdfium2-5.15.1-py3-none-android_23_arm64_v8a.whl
Size 3.6 MB
Tags Android API level 23+ ARM64 v8a Python 3
SHA-256 checksum
How to use checksums
203e658ba7aaca003f80e40f30728cc9880a0ba49131330a69477e925205d02c
BLAKE2b-256 checksum
How to use checksums
83763f880bd1514bb933bc662cf55e60878bb19384c375b213024f51937ab8c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Security for pypdfium2 5.15.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 23 files in this release have been uploaded with provenance metadata.

Select from 23 files

Attestation for pypdfium2-5.15.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

5.15.1 This release

23 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page