A modern CLI tool to recursively remove passwords from PDF files.
- Recursive processing: Processes all PDFs in a directory tree
- Structure preservation: Maintains folder hierarchy in output
- Multiple password strategies: Empty password, preset password, or interactive prompt
- Atomic writes: Safe file writing prevents corruption
- Rich CLI: Progress bars and colored output
- Input validation: Pydantic-validated configuration
# Clone or download, then:
uv sync
# Or install dependencies directly:
uv add typer rich pydantic 'pypdf[crypto]'uv run pdf_password_remover.py --input ./encrypted --output ./decrypteduv run pdf_password_remover.py -i ./pdfs -o ./output --password "secret123"uv run pdf_password_remover.py -i ./pdfs -o ./output --allow-empty-passworduv run pdf_password_remover.py -i ./pdfs -o ./output --forceuv run pdf_password_remover.py \
--input ~/Documents/encrypted \
--output ~/Documents/decrypted \
--allow-empty-password \
--password "backup-password" \
--force| Option | Short | Description |
|---|---|---|
--input |
-i |
Input directory containing PDF files (required) |
--output |
-o |
Output directory for decrypted PDFs (required) |
--allow-empty-password |
-e |
Try empty password before prompting |
--password |
-p |
Password to try for all encrypted PDFs |
--force |
-f |
Overwrite existing output files |
--help |
Show help message |
- Discovery: Recursively finds all
.pdffiles in the input directory - Decryption: For each encrypted PDF:
- Tries empty password (if
--allow-empty-password) - Tries preset password (if
--passwordprovided) - Prompts interactively (up to 3 attempts)
- Tries empty password (if
- Output: Writes decrypted PDFs atomically to preserve data integrity
- Metadata: Preserves PDF metadata when possible
- Python 3.12+
- typer
- rich
- pydantic
- pypdf[crypto]
0: All files processed successfully1: One or more files failed to process