Skip to main content

renamr

Python License PyPI CI

AI-powered CLI that renames files based on their content.

What it does

Scanned documents, downloads, and exported files often arrive with useless names like scan_001.pdf or IMG_5847.jpg. renamr reads each file — running local OCR on images and scans first, falling back to vision models only when OCR fails — sends the extracted text to an LLM, and renames the file to a structured format based on the content it actually finds.

scan_001.pdf          ->  240115_ACME_Invoice.pdf
IMG_5847.jpg          ->  241203_PostOffice_DeliveryNotice.jpg
invoice_download.pdf  ->  250110_Amazon_OrderConfirmation.pdf

Only the filename changes. Files are never modified.

Features

  • Content-aware renaming via any LiteLLM-supported provider (OpenAI, OpenRouter, Anthropic, Ollama, local models)
  • Local OCR-first extraction: images and scans are OCR'd locally before hitting the LLM
  • Optional vision fallback with configurable model for OCR failures
  • Per-inbox configuration: different templates, languages, and prompts per folder
  • iCloud evicted file handling — auto-downloads stubs via brctl before processing (macOS only)
  • Multi-inbox support — configure one or more folders in a single config
  • Configurable output language — extracted metadata returned in any language
  • Dry-run mode to preview renames without touching files
  • Undo the last run with a single command
  • Optional in-place PDF compression after renaming

Quick Start

# One-time global install
uv tool install renamr   # or: pip install renamr

# First-run setup — creates ~/.config/renamr/config.toml
renamr init

# Set your API key (for cloud providers)
export OPENAI_API_KEY="your-key"

# Preview renames
renamr run --dry-run

# Rename files
renamr run

# Undo last run
renamr undo

Override the inbox without editing config:

renamr run --inbox ~/Documents/inbox --dry-run

Configuration

renamr init creates ~/.config/renamr/config.toml by default. On Linux, XDG_CONFIG_HOME is respected, so the actual path becomes $XDG_CONFIG_HOME/renamr/config.toml when set.

New [[inbox]] Format

The config uses TOML array-of-tables syntax for per-inbox settings:

# Global defaults (used when not overridden per inbox)
language = "en"
filename_template = "{date}_{sender}_{subject}"

[[inbox]]
path = "/Users/you/Documents/Invoices"

[[inbox]]
path = "/Users/you/Documents/Scans"
filename_template = "{date}_{subject}"
language = "de"
rename_prompt = "Extract only date and subject. Ignore sender."

[llm]
model = "gpt-4o-mini"

[compress]
enabled = false
dpi = 150
jpeg_quality = 80

[logging]
level = "WARNING"
json_logs = false

Each [[inbox]] section represents one folder. Missing fields fall back to global defaults:

  • filename_template — optional override
  • language — optional override
  • rename_prompt — optional override

file_extensions and recursive remain global (no per-inbox override).

Legacy Format

The old inbox_paths = ["/path/one", "/path/two"] format is still supported but deprecated:

# DEPRECATED - still works but will be removed in a future version
inbox_paths = ["/path/to/folder"]
language = "en"
filename_template = "{date}_{sender}_{subject}"

Ollama Setup

Run renamr completely offline with a local Ollama instance.

1. Install Ollama

# macOS
brew install ollama

# Or download from https://ollama.com

2. Pull a model

ollama pull gemma4:e2b

3. Configure renamr

[llm]
model = "ollama/gemma4:e2b"
api_base = "http://localhost:11434"
temperature = 0.2

That's it. Files are processed locally with no external API calls.

Note: Ollama must be running (ollama serve) before you run renamr.

Cloud Providers

Change model and set api_base. For OpenRouter:

[llm]
model = "openrouter/openai/gpt-4o-mini"
api_base = "https://openrouter.ai/api/v1"

Then set OPENROUTER_API_KEY instead of OPENAI_API_KEY. Any provider supported by LiteLLM works without code changes.

Vision Fallback Model

For most files, local OCR extracts text without hitting the LLM at all. When OCR fails (low confidence, too few characters), renamr falls back to a vision model. By default it uses the same model configured in [llm]. To use a separate, cheaper, or local model for vision:

[llm]
model = "openai/gpt-4o-mini"            # text extraction (most files never reach this)
vision_model = "ollama/gemma4:e2b"       # vision fallback (only when OCR fails)
vision_api_base = "http://localhost:11434"

Both models can also be overridden per inbox:

[[inbox]]
path = "/Users/you/Documents/Scans"
model = "openai/gpt-4o"
vision_model = "openai/gpt-4o"

Custom Prompt

The default system prompt extracts sender, subject, and date from documents and handles German and English. To override, add a rename_prompt field to your config (globally or per-inbox):

[[inbox]]
path = "/Users/you/Documents/Receipts"
rename_prompt = """
Extract only the total amount and date from this receipt.
Return JSON: {"sender":"Store Name","subject":"Receipt $AMOUNT","date":"YYYY-MM-DD"}
"""

The full default prompt is in src/renamr/models.py.

CLI Reference

renamr init [--config PATH]     Create a config file interactively
renamr run [--config PATH]      Process files and rename them
  --dry-run                     Preview without renaming
  --inbox PATH                  Override inbox folder
  --recursive / --no-recursive  Override recursive setting
  --compress / --no-compress    Override compression setting
  --verbose                     Enable debug logging
renamr undo [--config PATH]     Undo the last successful run
renamr version                  Print version

undo.json is stored next to the config file. With the default setup, that means ~/.config/renamr/undo.json.

Privacy & Security

[!WARNING] renamr sends file content to an LLM API.

Depending on your configuration, this includes:

  • Extracted text from PDF and .txt files
  • OCR-extracted text from images and scans (processed locally first)
  • Vision model payloads — only sent when local OCR fails to extract sufficient text
  • Original filenames and file timestamps

When using cloud providers, this data is transmitted to remote servers. Do not run renamr on sensitive or confidential files unless you have reviewed and accepted your provider's data handling policy.

Tip: Set vision_model to a local Ollama model so that even OCR fallback stays on your machine.

[!NOTE] Local models (Ollama) process files entirely on your machine.

When configured with a local Ollama instance, no file content leaves your computer. This is the recommended setup for sensitive documents.

Additional notes:

  • Always use an https:// endpoint for api_base. An http:// URL sends file content unencrypted.
  • Keep ~/.config/renamr/undo.json private on shared systems — it contains the file paths from the last run.
  • Avoid sharing verbose log output publicly; failed auth responses may include API key fragments.

Maintenance

This tool is maintained for personal use and published as-is. Bug reports welcome via Issues. No guaranteed response time. PRs accepted if they align with the project's scope.

See CONTRIBUTING.md for development setup.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

renamr-1.4.0.tar.gz (215.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

renamr-1.4.0-py3-none-any.whl (25.7 kB view details)

Uploaded Python 3

File details

Details for the file renamr-1.4.0.tar.gz.

File metadata

  • Download URL: renamr-1.4.0.tar.gz
  • Upload date:
  • Size: 215.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for renamr-1.4.0.tar.gz
Algorithm Hash digest
SHA256 3b998c91b9c4d1a61f1175e94a6a74e2e5f9fa88acb316b9c3945f71deeca5c1
MD5 857936d2cbca8510c5db019867b377f6
BLAKE2b-256 f799b4ee2541471d99fe3cb80e4f11e2be118c67650075e726b991a417e4af0a

See more details on using hashes here.

Provenance

The following attestation bundles were made for renamr-1.4.0.tar.gz:

Publisher: release.yml on spignotti/renamr

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file renamr-1.4.0-py3-none-any.whl.

File metadata

  • Download URL: renamr-1.4.0-py3-none-any.whl
  • Upload date:
  • Size: 25.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for renamr-1.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 be2c48a8c4c978819e1e7ec7e45491520f398de76a5eed9bb7e6220d477d5e14
MD5 fe0a090d52d84b98cae06d8fb37cabae
BLAKE2b-256 9d72bd7683b12a68dc1376b75071e403b9ee031f65f626904cec74aa1a11e716

See more details on using hashes here.

Provenance

The following attestation bundles were made for renamr-1.4.0-py3-none-any.whl:

Publisher: release.yml on spignotti/renamr

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.4.0 This release

2 files

1.3.1

2 files

1.3.0

2 files

1.2.0

2 files

1.1.1

2 files

1.1.0

2 files

1.0.1

2 files

1.0.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page