mathias2784 0d6272b4c3
Tests / test_and_lint (push) Successful in 49s
E2e workflow (#21)
Reviewed-on: #21
Co-authored-by: Mathias Scheider <mathias2784@web.de>
2026-10-18 12:02:18 +00:00
2026-10-18 12:02:18 +00:00
2026-09-30 21:01:20 +00:00
2026-10-18 12:02:18 +00:00
2026-10-18 12:02:18 +00:00
2026-10-18 12:02:18 +00:00
2026-10-03 08:24:17 +00:00
2026-09-29 06:03:18 +02:00
2026-10-18 12:02:18 +00:00
2026-10-18 12:02:18 +00:00
2026-10-18 12:02:18 +00:00
2026-10-18 12:02:18 +00:00

PhotoTools3

PhotoTools3 uses an OpenAI-compatible vision API to generate photo captions and keywords, then writes the results to photo metadata. It can also assess photo quality.

Setup

Install the Python dependencies with uv and make sure ExifTool is installed and available on PATH (it is a system dependency, not a Python package):

uv sync

Create a .env file in the project root with the LLM connection details and the prefix used to identify metadata written by PhotoTools3:

llm_api_base_url=http://localhost:1234/v1
llm_api_key=your-api-key
llm_default_temperature=0.2
metadata_prefix=photools3:
LOG_LEVEL=DEBUG
LLM_REQUEST_TIMEOUT_SECONDS=10
LLM_MAX_COMPLETION_TOKENS=1024
LLM_MAX_RETRIES=5
LLM_MAX_KEYWORDS=15

Keyword suggestions are restricted to the vocabulary in config/keywords.txt. LOG_LEVEL=DEBUG enables detailed per-request and per-photo timings. LLM_MAX_RETRIES controls retries for malformed or structurally invalid responses; 5 means up to 6 requests for a photo. A valid response with unsupported keywords gets at most one targeted correction retry, then remaining invalid keywords are discarded. Each request is limited by LLM_REQUEST_TIMEOUT_SECONDS; a timeout reloads the LM Studio model before retrying. LLM_MAX_COMPLETION_TOKENS caps the generated response length. When all retries are exhausted, the model is reloaded before the failed photo is reported. LLM_MAX_KEYWORDS sets the maximum number of distinct keywords requested and stored per photo; excess keywords are discarded.

Generate metadata

The metadata-magic command accepts one or more image paths and/or directories. The default mode is both, which generates and writes a caption and keywords:

uv run photools3 metadata-magic photo.dng

Choose a mode with --mode:

# Generate only keywords
uv run photools3 metadata-magic photo.dng --mode keywords

# Generate only a caption
uv run photools3 metadata-magic photo.dng --mode captions

# Explicitly request both (the default)
uv run photools3 metadata-magic photo.dng --mode both

Pass multiple files to process them sequentially as a batch:

uv run photools3 metadata-magic photo1.dng photo2.jpg --mode both

Directories are scanned at the top level by default. Add --recursive to include supported images in subdirectories. You can combine directories and individual file paths:

uv run photools3 metadata-magic ./photos --recursive --mode keywords
uv run photools3 metadata-magic ./photos photo-to-include.dng --mode captions

The command reports each processed file and exits with a non-zero status if any file fails. In a batch, it continues processing the remaining files after an individual failure. Generated metadata is written using ExifTool and XMP sidecars.

Assess photo quality

The quality command reports an assessment without changing photo metadata:

uv run photools3 quality photo.dng

Help

Show the available commands and options with:

uv run photools3 --help
uv run photools3 metadata-magic --help
uv run photools3 quality --help
S
Description
Tools für Fotographie: Hilfestellugnen im RAW Workflow
Readme
26 MiB
Languages
Python 100%