# silentprior/paperless-paddle-ocr architecture

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

- Interactive diagram: https://gitdiagram.com/silentprior/paperless-paddle-ocr
- Repository: https://github.com/silentprior/paperless-paddle-ocr
- Video tour (about a minute): https://gitdiagram.com/silentprior/paperless-paddle-ocr/video

## Overview

paperless-paddle-ocr is a configurable sidecar that finds tagged paperless-ngx documents, claims and downloads them, extracts text with PaddleOCR, then updates content and workflow tags. Its main user-to-result path runs from document tagging through polling, OCR, and API update; daemon/one-shot and dry-run modes alter how that work runs. Runtime behavior is concentrated in the single sampled source file, so several nodes share its path. Unshown implementation details are omitted; documented capabilities are included where supported.

Main entry points: [`ocr_worker.py`](https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py) (Environment config)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Worker runtime"]
  node_config["Environment config<br/>[ocr_worker.py]"]
  node_worker["Worker entrypoint<br/>[ocr_worker.py]"]
  node_run_control["Run control<br/>[ocr_worker.py]"]
  node_readiness["API readiness<br/>[ocr_worker.py]"]
  node_health["Health endpoint<br/>[ocr_worker.py]"]
end

subgraph group_paperless["Paperless workflow"]
  node_poll["Document polling<br/>[ocr_worker.py]"]
  node_tag_rules["Tag filtering<br/>[ocr_worker.py]"]
  node_claim["Processing claim<br/>[ocr_worker.py]"]
  node_download["Document download<br/>[ocr_worker.py]"]
  node_tag_lookup["Tag lookup<br/>[ocr_worker.py]"]
  node_writeback["Content and tags<br/>[ocr_worker.py]"]
  node_failure["Failure tagging<br/>[ocr_worker.py]"]
end

subgraph group_ocr["Document OCR"]
  node_format["PDF rendering<br/>[ocr_worker.py]"]
  node_extract["Text extraction<br/>[ocr_worker.py]"]
end

node_operator(("Document tagger"))
node_paperless_api["Paperless API"]
node_paddle["PaddleOCR"]
node_pymupdf["PyMuPDF"]

node_operator -->|"tags documents"| node_paperless_api
node_worker -->|"loads settings"| node_config
node_worker -->|"checks availability"| node_readiness
node_worker -->|"starts mode"| node_run_control
node_run_control -->|"polls documents"| node_poll
node_poll -->|"lists documents"| node_paperless_api
node_poll -->|"filters results"| node_tag_rules
node_tag_rules -->|"resolves tags"| node_tag_lookup
node_tag_lookup -->|"reads or creates tags"| node_paperless_api
node_poll -->|"dispatches documents"| node_claim
node_claim -->|"sets processing tag"| node_paperless_api
node_claim -->|"continues processing"| node_download
node_download -->|"downloads document"| node_paperless_api
node_download -->|"provides file"| node_format
node_format -->|"renders PDF pages"| node_pymupdf
node_format -->|"provides images"| node_extract
node_extract -->|"runs prediction"| node_paddle
node_extract -->|"returns text"| node_writeback
node_writeback -->|"patches content and tags"| node_paperless_api
node_writeback -->|"handles update errors"| node_failure
node_failure -->|"clears claim or tags error"| node_paperless_api
node_worker -->|"serves health status"| node_health
node_config -->|"sets run and dry-run behavior"| node_run_control
node_config -->|"sets OCR options"| node_extract
node_config -->|"sets tag criteria"| node_poll
node_config -.->|"selects engine"| node_paddle

click node_config "https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py"
click node_worker "https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py"
click node_run_control "https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py"
click node_readiness "https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py"
click node_health "https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py"
click node_poll "https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py"
click node_tag_rules "https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py"
click node_claim "https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py"
click node_download "https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py"
click node_tag_lookup "https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py"
click node_format "https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py"
click node_extract "https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py"
click node_writeback "https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py"
click node_failure "https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.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_config,node_worker,node_run_control,node_readiness,node_health toneBlue
class node_poll,node_tag_rules,node_claim,node_download,node_tag_lookup,node_writeback,node_failure toneAmber
class node_format,node_extract,node_paperless_api toneMint
class node_operator,node_paddle,node_pymupdf toneIndigo
```

## Components

### Worker runtime

- [Environment config](https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py): `ocr_worker.py`
- [Worker entrypoint](https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py): `ocr_worker.py`
- [Run control](https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py): `ocr_worker.py`
- [API readiness](https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py): `ocr_worker.py`
- [Health endpoint](https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py): `ocr_worker.py`

### Paperless workflow

- [Document polling](https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py): `ocr_worker.py`
- [Tag filtering](https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py): `ocr_worker.py`
- [Processing claim](https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py): `ocr_worker.py`
- [Document download](https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py): `ocr_worker.py`
- [Tag lookup](https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py): `ocr_worker.py`
- [Content and tags](https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py): `ocr_worker.py`
- [Failure tagging](https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py): `ocr_worker.py`

### Document OCR

- [PDF rendering](https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py): `ocr_worker.py`
- [Text extraction](https://github.com/silentprior/paperless-paddle-ocr/blob/main/ocr_worker.py): `ocr_worker.py`

### Other components

- **Document tagger**
- **Paperless API**
- **PaddleOCR**
- **PyMuPDF**

## Connections

- Document tagger → Paperless API: tags documents
- Worker entrypoint → Environment config: loads settings
- Worker entrypoint → API readiness: checks availability
- Worker entrypoint → Run control: starts mode
- Run control → Document polling: polls documents
- Document polling → Paperless API: lists documents
- Document polling → Tag filtering: filters results
- Tag filtering → Tag lookup: resolves tags
- Tag lookup → Paperless API: reads or creates tags
- Document polling → Processing claim: dispatches documents
- Processing claim → Paperless API: sets processing tag
- Processing claim → Document download: continues processing
- Document download → Paperless API: downloads document
- Document download → PDF rendering: provides file
- PDF rendering → PyMuPDF: renders PDF pages
- PDF rendering → Text extraction: provides images
- Text extraction → PaddleOCR: runs prediction
- Text extraction → Content and tags: returns text
- Content and tags → Paperless API: patches content and tags
- Content and tags → Failure tagging: handles update errors
- Failure tagging → Paperless API: clears claim or tags error
- Worker entrypoint → Health endpoint: serves health status
- Environment config → Run control: sets run and dry-run behavior
- Environment config → Text extraction: sets OCR options
- Environment config → Document polling: sets tag criteria
- Environment config → PaddleOCR: selects engine
