# py-pdf/pypdf architecture

> Architecture diagram of the GitHub repository py-pdf/pypdf, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/py-pdf/pypdf
- Repository: https://github.com/py-pdf/pypdf

## Overview

pypdf is a Python PDF library. The principal workflow opens a PDF with PdfReader, exposes pages and document objects, then supports page-level inspection such as text extraction; PdfWriter creates or modifies PDFs for output. The README also documents merging, splitting, page transformations, metadata, annotations, and encryption. The tree and excerpts establish the main modules, but most reader/writer wiring is unsampled, so uncertain internal links are omitted.

Main entry points: [`pypdf/_writer.py`](https://github.com/py-pdf/pypdf/blob/main/pypdf/_writer.py) (PdfWriter), [`pypdf/_reader.py`](https://github.com/py-pdf/pypdf/blob/main/pypdf/_reader.py) (PdfReader), [`pypdf/_text_extraction/_text_extractor.py`](https://github.com/py-pdf/pypdf/blob/main/pypdf/_text_extraction/_text_extractor.py) (Text extraction), [`pypdf/_encryption.py`](https://github.com/py-pdf/pypdf/blob/main/pypdf/_encryption.py) (Encryption)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_reading["PDF reading"]
  node_reader["PdfReader<br/>[_reader.py]"]
  node_page["Page operations<br/>[_page.py]"]
  node_extract["Text extraction<br/>[_text_extractor.py]"]
  node_layout["Layout extraction"]
end

subgraph group_editing["PDF editing"]
  node_writer["PdfWriter<br/>[_writer.py]"]
  node_pagerange["Page selection<br/>[pagerange.py]"]
end

subgraph group_representation["PDF representation"]
  node_generic["PDF objects"]
  node_filters["Stream filters<br/>[filters.py]"]
end

subgraph group_features["Document features"]
  node_encryption["Encryption<br/>[_encryption.py]"]
  node_crypt["Crypto providers<br/>[_base.py]"]
  node_metadata["XMP metadata<br/>[xmp.py]"]
  node_annotations["Annotations<br/>[_base.py]"]
  node_actions["PDF actions<br/>[_actions.py]"]
end

node_user(("PDF user"))

node_user -->|"opens PDF"| node_reader
node_reader -->|"exposes pages"| node_page
node_user -->|"requests text"| node_extract
node_page -->|"extracts text"| node_extract
node_extract -->|"tracks text state"| node_layout
node_user -->|"creates or edits"| node_writer
node_user -->|"selects pages"| node_pagerange
node_reader -->|"parses objects"| node_generic
node_writer -->|"serializes objects"| node_generic
node_reader -->|"decodes streams"| node_filters
node_writer -->|"encodes streams"| node_filters
node_reader -->|"decrypts PDF"| node_encryption
node_writer -->|"encrypts PDF"| node_encryption
node_encryption -->|"uses provider"| node_crypt
node_reader -->|"reads metadata"| node_metadata
node_writer -->|"writes metadata"| node_metadata
node_writer -->|"adds annotations"| node_annotations
node_writer -->|"adds actions"| node_actions

click node_reader "https://github.com/py-pdf/pypdf/blob/main/pypdf/_reader.py"
click node_page "https://github.com/py-pdf/pypdf/blob/main/pypdf/_page.py"
click node_extract "https://github.com/py-pdf/pypdf/blob/main/pypdf/_text_extraction/_text_extractor.py"
click node_layout "https://github.com/py-pdf/pypdf/blob/main/pypdf/_text_extraction/_layout_mode/_text_state_manager.py"
click node_writer "https://github.com/py-pdf/pypdf/blob/main/pypdf/_writer.py"
click node_pagerange "https://github.com/py-pdf/pypdf/blob/main/pypdf/pagerange.py"
click node_generic "https://github.com/py-pdf/pypdf/blob/main/pypdf/generic/_data_structures.py"
click node_filters "https://github.com/py-pdf/pypdf/blob/main/pypdf/filters.py"
click node_encryption "https://github.com/py-pdf/pypdf/blob/main/pypdf/_encryption.py"
click node_crypt "https://github.com/py-pdf/pypdf/blob/main/pypdf/_crypt_providers/_base.py"
click node_metadata "https://github.com/py-pdf/pypdf/blob/main/pypdf/xmp.py"
click node_annotations "https://github.com/py-pdf/pypdf/blob/main/pypdf/annotations/_base.py"
click node_actions "https://github.com/py-pdf/pypdf/blob/main/pypdf/actions/_actions.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_reader,node_page,node_extract,node_layout,node_user toneBlue
class node_writer,node_pagerange toneAmber
class node_generic,node_filters toneMint
class node_encryption,node_crypt,node_metadata,node_annotations,node_actions toneRose
```

## Components

### PDF reading

- [PdfReader](https://github.com/py-pdf/pypdf/blob/main/pypdf/_reader.py): `pypdf/_reader.py`
- [Page operations](https://github.com/py-pdf/pypdf/blob/main/pypdf/_page.py): `pypdf/_page.py`
- [Text extraction](https://github.com/py-pdf/pypdf/blob/main/pypdf/_text_extraction/_text_extractor.py): `pypdf/_text_extraction/_text_extractor.py`
- [Layout extraction](https://github.com/py-pdf/pypdf/blob/main/pypdf/_text_extraction/_layout_mode/_text_state_manager.py): `pypdf/_text_extraction/_layout_mode/_text_state_manager.py`

### PDF editing

- [PdfWriter](https://github.com/py-pdf/pypdf/blob/main/pypdf/_writer.py): `pypdf/_writer.py`
- [Page selection](https://github.com/py-pdf/pypdf/blob/main/pypdf/pagerange.py): `pypdf/pagerange.py`

### PDF representation

- [PDF objects](https://github.com/py-pdf/pypdf/blob/main/pypdf/generic/_data_structures.py): `pypdf/generic/_data_structures.py`
- [Stream filters](https://github.com/py-pdf/pypdf/blob/main/pypdf/filters.py): `pypdf/filters.py`

### Document features

- [Encryption](https://github.com/py-pdf/pypdf/blob/main/pypdf/_encryption.py): `pypdf/_encryption.py`
- [Crypto providers](https://github.com/py-pdf/pypdf/blob/main/pypdf/_crypt_providers/_base.py): `pypdf/_crypt_providers/_base.py`
- [XMP metadata](https://github.com/py-pdf/pypdf/blob/main/pypdf/xmp.py): `pypdf/xmp.py`
- [Annotations](https://github.com/py-pdf/pypdf/blob/main/pypdf/annotations/_base.py): `pypdf/annotations/_base.py`
- [PDF actions](https://github.com/py-pdf/pypdf/blob/main/pypdf/actions/_actions.py): `pypdf/actions/_actions.py`

### Other components

- **PDF user**

## Connections

- PDF user → PdfReader: opens PDF
- PdfReader → Page operations: exposes pages
- PDF user → Text extraction: requests text
- Page operations → Text extraction: extracts text
- Text extraction → Layout extraction: tracks text state
- PDF user → PdfWriter: creates or edits
- PDF user → Page selection: selects pages
- PdfReader → PDF objects: parses objects
- PdfWriter → PDF objects: serializes objects
- PdfReader → Stream filters: decodes streams
- PdfWriter → Stream filters: encodes streams
- PdfReader → Encryption: decrypts PDF
- PdfWriter → Encryption: encrypts PDF
- Encryption → Crypto providers: uses provider
- PdfReader → XMP metadata: reads metadata
- PdfWriter → XMP metadata: writes metadata
- PdfWriter → Annotations: adds annotations
- PdfWriter → PDF actions: adds actions
