pdfredact
Redact text in a PDF (true redaction, not just a visual overlay) using PyMuPDF. Finds occurrences of the specified text/pattern, applies a redaction annotation, and "burns" it into the page content, physically removing the underlying text (not recoverable via copy-paste or text extraction).
Installation
Requires Python 3.9 or later. Dependencies are PyMuPDF and PyYAML (for --config), both of
which publish prebuilt wheels for Linux, Windows, and macOS (no compiler required).
The package is published on PyPI as pdfredactcli
(the installed command is pdfredact).
With pip
pip install pdfredactcli
or, from a local clone of the repository:
pip install .
or, for development (editable install with test dependencies):
pip install -e .[test]
With pipx (recommended for a command-line tool)
pipx installs the tool in an isolated virtual environment and
exposes only the pdfredact command on PATH, without touching the system Python.
Linux/macOS:
python3 -m pip install --user pipx
python3 -m pipx ensurepath
pipx install pdfredactcli
Or, from a local clone of the repository, replace the last line with pipx install . (run
from the root of the repository).
Windows:
On Windows it's convenient to install pipx via Scoop, which also
manages updating Python itself if needed:
# If Scoop isn't already installed:
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
scoop install pipx
pipx ensurepath
Then, in a new terminal (so ensurepath takes effect):
pipx install pdfredactcli
Or, from a local clone of the repository, run pipx install . from the repository folder
instead.
In both cases, after installation the pdfredact command is available directly in a new
terminal.
Usage
pdfredact input.pdf output.pdf -t "Mario Rossi" -t "CF: ABCDEF"
pdfredact input.pdf output.pdf -r "\bMCNP-\d{4}\b"
pdfredact input.pdf output.pdf -t "Confidential" --case-sensitive
pdfredact input.pdf output.pdf -t "foo" --pages 1,2,5-7
pdfredact input.pdf output.pdf --box "1:56,700,300,730"
pdfredact input.pdf output.pdf -t "foo" --fill-color "#ff0000"
pdfredact input.pdf -t "Mario Rossi" # writes input_redacted.pdf
pdfredact --config job.yaml
pdfredact input.pdf output.pdf --config rules.yaml -t "extra one-off term"
pdfredact --version
The output path is optional: if omitted, it defaults to <input>_redacted.pdf next to the
input file.
Equivalent without installing, from the root of the repository:
python -m pdfredact input.pdf output.pdf -t "Mario Rossi"
Rectangle coordinates (--box)
Format: PAGE:x0,y0,x1,y1
PAGEis 1-based (page 1 = first page)x0,y0,x1,y1in PDF points (72 pt = 1 inch), origin at the top-left (same coordinate system returned bypage.search_for())- Corner order doesn't matter: the rectangle is normalized.
- A box that falls entirely outside the page redacts nothing: it's reported on stderr and not counted as a redacted occurrence, so a typo'd coordinate can't look like a success.
Config file (--config)
Any option can also be set in a YAML file instead of retyped on every invocation:
# job.yaml
input: input.pdf # optional if given positionally on the command line
output: output.pdf # optional; defaults to <input>_redacted.pdf if unset everywhere
text: # literal terms to redact (like repeated -t)
- "Mario Rossi"
- "CF: ABCDEF"
regex: # regex patterns to redact (like repeated -r)
- '\bMCNP-\d{4}\b'
boxes: # explicit rectangles, same "PAGE:x0,y0,x1,y1" format as --box
- "1:56,700,300,730"
case_sensitive: false # like --case-sensitive
pages: "1,2,5-7" # like --pages
fill_color: "#000000" # like --fill-color
All keys are optional, and pdfredact --config job.yaml alone is a valid invocation if input
is set in the file. Values from the config file and the command line are merged:
text,regex, andboxesfrom the command line are added to the config file's lists.input,output,pages,fill_color, andcase-sensitivefrom the command line override the config file's value when explicitly passed. To override a config file'scase_sensitive: trueback tofalse, pass--no-case-sensitive(plain--case-sensitivecan only set it totrue).
Each key is validated the same way as its CLI equivalent (same --box/--pages/--fill-color
formats); an unknown key or a value of the wrong type/shape fails immediately with exit code 2
rather than being silently ignored.
Exit codes
0 = success, 2 = input/usage error.
Known limitations
- Only PDF input is accepted. PyMuPDF can also open TXT, EPUB, SVG, CBZ and image files, but redaction annotations are PDF-only, so those inputs are rejected with exit code 2; convert them to PDF first.
- Document metadata (Author, Title, XMP) and annotation/comment content are not handled,
since they don't appear in
get_text(). - A term split across multiple lines in the PDF layout might not be found.
- Scanned PDFs (image-only, with no extractable text) require OCR upstream: the tool finds nothing to redact in that case.
Always verify the output with pdftotext and pdfinfo -meta before distribution.
Windows compatibility
The project is tested in CI on Linux, Windows, and macOS (see .github/workflows/tests.yml)
and is compatible with Windows without modifications: it only uses os.path (no hardcoded
separators), no POSIX-only calls, and os.path.samefile has worked correctly on Windows
since Python 3.2.
Development
pip install -e .[test]
pytest
pytest tests/test_core.py::test_redact_pdf_literal_term # single test
AI-assisted development
This project's code, tests, and documentation were developed with the assistance of AI tools (Claude Code). Every change was reviewed before being published; please report any issues you find via the project's issue tracker.
License
MPL-2.0. The repository is REUSE compliant; to verify:
pipx run reuse lint.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pdfredactcli-0.2.0.tar.gz.
File metadata
- Download URL: pdfredactcli-0.2.0.tar.gz
- Upload date:
- Size: 37.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ced70773cbde411a29b18b4e118a2626554e1ebfdd3c96ecb16d052dd422f226
|
|
| MD5 |
7e0055d7e1a0a9f83bf15114fd05ccbc
|
|
| BLAKE2b-256 |
ccb91314a4a2497b1fff9abe6ad6dc263459d6242ee044221d86ece1b1671e24
|
Provenance
The following attestation bundles were made for pdfredactcli-0.2.0.tar.gz:
Publisher:
pypi.yml on alberto743/pdfredact
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pdfredactcli-0.2.0.tar.gz -
Subject digest:
ced70773cbde411a29b18b4e118a2626554e1ebfdd3c96ecb16d052dd422f226 - Sigstore transparency entry: 2477698188
- Sigstore integration time:
-
Permalink:
alberto743/pdfredact@0ec79f9a558eb6f35098c5185cfbf809d3632da6 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/alberto743
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@0ec79f9a558eb6f35098c5185cfbf809d3632da6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pdfredactcli-0.2.0-py3-none-any.whl.
File metadata
- Download URL: pdfredactcli-0.2.0-py3-none-any.whl
- Upload date:
- Size: 18.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e412ea4295991d5288fd65d47030253811723eb74424528c22816cce5f472e84
|
|
| MD5 |
fa4faab2ff2286f1e8733593ab8bc937
|
|
| BLAKE2b-256 |
85244ff256811e13324b9da8418784e8ab20cd319fee6ac995ca2d086d062494
|
Provenance
The following attestation bundles were made for pdfredactcli-0.2.0-py3-none-any.whl:
Publisher:
pypi.yml on alberto743/pdfredact
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pdfredactcli-0.2.0-py3-none-any.whl -
Subject digest:
e412ea4295991d5288fd65d47030253811723eb74424528c22816cce5f472e84 - Sigstore transparency entry: 2477698349
- Sigstore integration time:
-
Permalink:
alberto743/pdfredact@0ec79f9a558eb6f35098c5185cfbf809d3632da6 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/alberto743
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@0ec79f9a558eb6f35098c5185cfbf809d3632da6 -
Trigger Event:
push
-
Statement type: