Skip to main content

pdf4me

PyPI Python versions License

Python client for the PDF4me API. Convert, optimize, merge, split, stamp, and extract content from documents with async functions and typed results.

Requires Python 3.11 or newer and a PDF4me API key.

Upgrading from 0.8.x? Version 1.0 is a rewrite and nothing from 0.8.x keeps working. See Migrating from 0.8.x.

Installation

python -m pip install pdf4me

To install from a source checkout, run python -m pip install . in this package directory. The import name is pdf4me.

Quick start

Set your API key in the environment:

export PDF4ME_API_KEY="your-api-key"

Save this as optimize_pdf.py and put an input.pdf in the same working directory. The example uploads the PDF for optimization and saves the result as optimized.pdf.

import asyncio
import os
from pathlib import Path

from pdf4me import Pdf4meClient
from pdf4me.optimize import optimize


async def main() -> None:
    api_key = os.environ.get("PDF4ME_API_KEY")
    if not api_key:
        raise SystemExit("Set PDF4ME_API_KEY before running this example.")

    source = Path("input.pdf")
    async with Pdf4meClient(api_key) as client:
        result = await optimize(
            client, source.read_bytes(), doc_name=source.name
        )
    Path("optimized.pdf").write_bytes(result)
    print("Saved optimized.pdf")


if __name__ == "__main__":
    asyncio.run(main())

Run it with:

python optimize_pdf.py

Using actions

Import actions from their module. Pass the client first, document content next, and action options as keyword arguments. Reuse one client for multiple calls; the async context manager closes its connections when finished.

For example, inside an async function with an open client:

from pdf4me.pdf import get_pdf_metadata
from pdf4me.edit import StampAlignX, stamp

metadata = await get_pdf_metadata(client, data, doc_name="input.pdf")
print(metadata.page_count)

stamped = await stamp(client, data, text="DRAFT", align_x=StampAlignX.Center)
Path("stamped.pdf").write_bytes(stamped)

Here, data contains the PDF bytes, for example Path("input.pdf").read_bytes(). Enums such as OptimizeProfile and StampAlignX are exported by the action's module.

Source documents accept bytes, base64 strings, pdf4meblobid://<id> references, or HTTPS URLs. Bytes are encoded automatically. File actions return bytes; JSON actions return typed models, such as DocMetadata or SplitPdfRes. Queued jobs are polled automatically until the result is available.

Every action accepts extra, a dictionary of additional API request fields. Use the API's field names for these values.

Client configuration and errors

async with Pdf4meClient(
    api_key,
    base_url="https://api.pdf4me.com",
    timeout=100,
    max_wait=300,
) as client:
    result = await optimize(client, data)

Durations are in seconds. timeout controls the HTTP request timeout; max_wait limits waiting for a queued job.

OCR actions (convert_ocr_pdf, image_extract_text) wait at least 10 minutes (DEFAULT_OCR_MAX_WAIT), or longer if the client's max_wait is higher. Pass max_wait= to an OCR call to override it for that call.

API failures raise Pdf4meException, importable from pdf4me, with the status code, API message, and trace ID. A queued job exceeding max_wait raises TimeoutError.

Available modules

The client provides 106 actions across 18 modules.

Module Docs section Actions
pdf4me.ai_document_extraction AI Document Extraction 14
pdf4me.barcode Barcode 7
pdf4me.convert Convert 13
pdf4me.edit Edit 7
pdf4me.excel Excel 1
pdf4me.extract Extract 8
pdf4me.find_search Find Search 2
pdf4me.forms Forms 2
pdf4me.generate Generate 6
pdf4me.image Image 13
pdf4me.merge_split Merge & Split 5
pdf4me.optimize Optimize 1
pdf4me.organize Organize 5
pdf4me.pdf PDF 16
pdf4me.pdf4me PDF4me 1
pdf4me.security Security 2
pdf4me.word Word 2
pdf4me.zugferd ZUGFeRD 1

Migrating from 0.8.x

Version 1.0 replaces the whole surface of the library. Upgrading will not be a drop-in change; the four things that break every 0.8.x program are:

  • Calls are async. Every action is a coroutine and must be awaited from inside an event loop.
  • The client classes are gone. MergeClient, OptimizeClient, SplitClient and the rest are replaced by plain functions, imported from the module for their API section, that take the client as their first argument.
  • config.properties is no longer read. Pass the API key to Pdf4meClient yourself. jprops, requests and keyring are no longer dependencies.
  • Python 2.7 and 3.6 are no longer supported. The minimum is 3.11.

Files are passed as bytes rather than as the file handles FileReader().get_file_handler(...) used to return, so Path(...).read_bytes() replaces it. Actions that produce a document return bytes; actions that answer with data return a typed model.

0.8.x 1.0
Pdf4meClient(token=token) Pdf4meClient(api_key)
MergeClient(c).merge_2_pdfs(f1, f2) await merge(client, [a, b])
OptimizeClient(c).optimize_by_profile(profile, f) await optimize(client, data, profile=...)
SplitClient(c).split_by_page_nr(n, f) await split_pdf(client, data, split_action_number=n)
ExtractClient(c).extract_pages(page_nrs, f) await extract_pages(client, data, page_numbers=...)
StampClient(c).text_stamp(text, pages, ax, ay, f) await stamp(client, data, text=..., pages=...)
BarcodeClient(c).read_barcodes_by_type(t, f) await read_barcodes(client, data, barcode_type=[t])

The table covers the common calls; the module table above says where to import everything else from, and each action's docstring links its documentation page.

Contributing

Issues and pull requests are welcome on GitHub.

src/pdf4me/_generated/ is generated from the PDF4me OpenAPI description. Edits made there are overwritten the next time the client is regenerated, so please open an issue for anything wrong in that tree - a missing field, a wrong type - rather than patching it. The client and the action modules around it are hand-written and are the right place for a pull request.

The tests run against a fake transport, so they need no API key and make no network calls:

uv run pytest

Releasing

Releases are published to PyPI by the release workflow when a version tag is pushed.

  1. Bump the version. uv version sets it in pyproject.toml and updates uv.lock. Commit the change on master:

    uv version 1.0.3
    git commit -am "chore: release 1.0.3"
    git push origin master
    
  2. Tag that commit with the same version, prefixed with v, and push the tag:

    git tag v1.0.3
    git push origin v1.0.3
    

The workflow runs the tests on Python 3.11 to 3.14 and checks that the tag matches the pyproject.toml version, stopping before anything ships if they differ. It then builds the distributions, publishes them to PyPI and creates the GitHub release with generated notes. Push only the tag; don't create the GitHub release by hand, because the workflow creates it.

Publishing uses PyPI trusted publishing, so no token is stored in the repository. This repository, release.yml and the pypi environment must be registered as a trusted publisher of the pdf4me project on PyPI.

Support

Quote the trace_id from a Pdf4meException when reporting an API failure.

Looking for the PDF4me online tools rather than the API? See pdf4me.com.

License

Released under the MIT License.

Metadata

Release files for pdf4me 1.1.0

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

Source distribution (sdist)

Source distribution for pdf4me 1.1.0
File Size Uploaded
pdf4me-1.1.0.tar.gz 143.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pdf4me 1.1.0
File Interpreter ABI Platform
pdf4me-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 637.0 kB

Release files / pdf4me-1.1.0.tar.gz

Download URL pdf4me-1.1.0.tar.gz
Size 143.0 kB
Tags Source
SHA-256 checksum
How to use checksums
c260e9d5ec2683a37a8e958ffe62ebcb0c82ad0c11a09063b7890560b039f5fb
BLAKE2b-256 checksum
How to use checksums
2fde760c68c1b3444066d77d1cbe0c496cc6fd9256e4bc3e59af506146e1533a
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 Oct 8, 2026.

Transparency log

Release files / pdf4me-1.1.0-py3-none-any.whl

Download URL pdf4me-1.1.0-py3-none-any.whl
Size 494.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ecb6cd7068c7fc1f6b9cb8dd63aeb29d7f1807f063c32ef17555c83e4da185f7
BLAKE2b-256 checksum
How to use checksums
2637270752b7552d1a7fd0edeb024f3845756b855c38264cd28dab27ee3d8849
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 Oct 8, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.8.24

1 release file

0.8.23

1 release file

0.8.22

1 release file

0.8.21

1 release file

0.8.20

1 release file

0.8.19

1 release file

0.8.18

1 release file

0.8.17

1 release file

0.8.16

1 release file

0.8.15

1 release file

0.8.14

1 release file

0.8.13

1 release file

0.8.12

1 release file

0.8.11

1 release file

0.8.10

1 release file

0.8.9

1 release file

0.8.8

1 release file

0.8.7

1 release file

0.8.6

1 release file

0.8.5

1 release file

0.8.4

1 release file

0.8.3

1 release file

0.8.1

1 release file

0.8.0

1 release file

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