Registry / serialization / pdfrw
library0.4pypypi✓ verified 25d ago

pdfrw is a pure Python library for reading and writing PDF files. It's designed for efficiency, offering capabilities for operations such as subsetting, merging, rotating, and modifying PDF metadata. The current version, 0.4, primarily focused on enhancing Python 3 compatibility and proper Unicode support. While still functional, its release cadence has been sporadic, and some sources suggest development has ceased.

pip install pdfrw
INSTALL
IMPORT
SIG · PDFRW
P
pdfrw
serializationpythonv0.4
Install
1.6s avg
Import
36ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v0.4 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.038s · 18.2MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.6s · import 0.034s · 19MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

PdfReader
from pdfrw import PdfReader
PdfWriter
from pdfrw import PdfWriter
PageMerge
from pdfrw import PageMerge
*
from pdfrw import *
While 'from pdfrw import *' was fixed in v0.3 to work properly, explicit imports are generally recommended for clarity and avoiding namespace pollution.

This quickstart demonstrates how to read an existing PDF file and write its contents to a new PDF file, effectively creating a copy. It also includes a basic step to create a dummy `input.pdf` for a runnable example.

from pdfrw import PdfReader, PdfWriter, PageMerge # Create a dummy input PDF for the example # In a real scenario, 'input.pdf' would already exist. writer = PdfWriter() writer.addpages([PageMerge().add_text("Hello World").render()]) writer.write("input.pdf") # Read an existing PDF reader = PdfReader("input.pdf") # Create a new PdfWriter object writer = PdfWriter() # Add all pages from the reader to the writer writer.addpages(reader.pages) # Write the content to a new PDF file (e.g., creating a copy) writer.write("output_copy.pdf") print("PDF 'input.pdf' read and copied to 'output_copy.pdf'")
Debug
Known issues
gotchapdfrw has limited support for compression and no built-in support for encryption in PDF files. For such files, users might need to pre-process them with external tools like `pdftk` to uncompress or decrypt before `pdfrw` can process them reliably.
fix
Use external tools (e.g., `pdftk`) to uncompress or decrypt PDFs before feeding them to pdfrw, or use another Python PDF library with more comprehensive compression/encryption support.
affects: <=0.4
deprecatedThe library's development seems to have ceased, with the last release (v0.4) in 2017. While it remains functional for many tasks, users should be aware of the lack of ongoing maintenance and potential for unaddressed bugs or compatibility issues with newer Python versions or PDF specifications. Some sources explicitly state it is 'not maintained anymore'.
fix
Evaluate whether pdfrw meets your long-term project needs given the maintenance status. Consider alternative libraries for actively developed features or if encountering unresolvable issues.
affects: 0.4 and potentially future Python versions
breakingInitial versions of pdfrw (prior to v0.2) only supported Python 2. Support for Python 3 was introduced in v0.2. Older Python 2 codebases might require adaptation for Python 3 environments, particularly regarding string handling.
fix
Ensure you are using pdfrw v0.2 or later for Python 3 compatibility. Review and update code for Python 2-to-3 string and byte handling if migrating.
affects: <0.2 (Python 2 only)
gotchaProper Unicode support for text strings in PDFs was added in v0.4. Earlier versions might exhibit issues when handling or embedding non-ASCII or international characters, which could lead to corrupted text or errors.
fix
Upgrade to pdfrw v0.4 for improved Unicode handling. If using older versions, be cautious with non-ASCII text and consider pre-processing or alternative methods for text injection.
affects: <0.4
gotchaWhen merging or manipulating PDFs, pdfrw might not preserve certain PDF features like bookmarks (outlines) as it often reconstructs page display information. This can result in a loss of navigation elements in the output PDF.
fix
Be aware that bookmarks may not be preserved during operations like page merging or concatenation. If bookmark preservation is critical, consider using `pdftk` or `PyPDF2` (which generally supports more features) in conjunction with pdfrw or as an alternative.
affects: <=0.4
gotchaVersion 0.3 included fixes for several `PageMerge` bugs, specifically related to multiple program runs and state save/restore. Prior to these fixes, `PageMerge` operations could be unreliable or lead to unexpected behavior.
fix
Upgrade to pdfrw v0.3 or later to benefit from critical `PageMerge` bug fixes, ensuring more stable and predictable merging operations.
affects: <0.3
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'pdfrw'
The 'pdfrw' library is not installed in the Python environment where the code is being executed, or there is a mismatch between the installation environment and the runtime environment (e.g., different Python interpreters or virtual environments).
fix
Install the library using `pip` or `conda` for the correct Python environment:
```python
pip install pdfrw
# or if using Anaconda
conda install pdfrw
```
TypeError: 'module' object is not callable (when attempting `pdfrw.pdfreader(...)`)
The user is trying to call `pdfrw.pdfreader` as a function, but `pdfreader` is a module within the `pdfrw` package, not a callable class. The correct class for reading PDFs is `PdfReader`.
fix
Import the `PdfReader` class explicitly and use it to instantiate the reader object:
```python
from pdfrw import PdfReader

pdf_file = PdfReader('your_document.pdf')
```
UnicodeEncodeError: 'latin-1' codec can't encode characters in position X-Y: ordinal not in range(256)
pdfrw internally uses 'latin-1' encoding for certain operations, which is unable to handle non-ASCII or wide Unicode characters (such as those found in many non-English languages) present in the PDF or being added to it.
fix
This is a known limitation for `pdfrw` regarding full Unicode support in all contexts. For text strings, try to ensure they are ASCII compatible if possible for direct manipulation. If dealing with annotations containing Unicode characters, it often requires embedding a subset CID font, which `pdfrw` may not fully support. Developers sometimes resort to converting non-ASCII text to images or using other PDF libraries that offer better Unicode handling for specific use cases.
pdfrw.errors.PdfParseError: Expected "xref" keyword (or similar PdfParseError)
The PDF file being processed is malformed, corrupted, or has an unusual internal structure that `pdfrw`'s parser cannot interpret, specifically failing to locate the expected cross-reference table or other core PDF components.
fix
No direct code fix exists within `pdfrw` itself for invalid PDFs. A common approach is to pre-process or 'repair' the PDF using another robust PDF tool before `pdfrw` attempts to read it. This can involve using command-line utilities like `pdftk` or Python libraries like `PyMuPDF` to clean the PDF structure. For example, using `PyMuPDF` to create a 'cleaned' version:
```python
import sys
from io import BytesIO
from pdfrw import PdfReader
import pymupdf

def tolerant_reader(fname, password=None):
    idata = open(fname, "rb").read()
    ibuffer = BytesIO(idata)
    try:
        return PdfReader(ibuffer) # Try pdfrw first
    except Exception: # pdfrw failed, attempt repair with PyMuPDF
        doc = pymupdf.open("pdf", ibuffer)
        if password is not None:
            rc = doc.authenticate(password)
            if not rc > 0:
                raise ValueError("wrong password")
        c = doc.tobytes(garbage=3, deflate=True) # Clean and deflate
        del doc
        return PdfReader(BytesIO(c)) # Let pdfrw retry with cleaned data

# Usage example:
pdf = tolerant_reader("your_corrupt.pdf")
```
AttributeError: 'NoneType' object has no attribute 'Length' (or 'update', 'inheritable' etc. when accessing PdfReader/PdfDict attributes)
This error occurs when the code attempts to access an attribute (e.g., `Length`, `update`) on a PDF dictionary or object that is `None`. This typically indicates that a specific PDF structure (like an encryption dictionary, the `Info` dictionary, or certain page properties) expected by the code is either missing or not properly defined in the input PDF.
fix
Implement checks to ensure the PDF object or its attribute exists and is not `None` before attempting to access it. If dealing with potentially encrypted PDFs, ensure `pdfrw`'s `decrypt=True` option is used, and gracefully handle cases where encryption information might be absent or malformed.
```python
from pdfrw import PdfReader

try:
    reader = PdfReader('your_document.pdf', decrypt=True) # Try with decrypt
    if reader.Info is not None and hasattr(reader.Info, 'Length'):
        # Safely access reader.Info.Length
        print(f"Document Length: {reader.Info.Length}")
    else:
        print("PDF Info dictionary or 'Length' attribute not found or is None.")
except Exception as e:
    print(f"An error occurred while reading the PDF: {e}")
```
Upgrade
Version history
0.4latest on PyPI · released Sep 18, 2017
Audit
Dependencies

No dependency data recorded yet.

Agent activity
9 hits · last 30 days
node
8
Resources
pdfrw — pip install pdfrw · libregistry