Skip to main content

Python CLI tools for photography workflows

Project description

CI

Photo Tools CLI

Command-line tools for organising photos by date, managing RAW/JPG pairs, and optimising images.

Supported formats

  • RAW: .raf
  • JPG: .jpg, .jpeg

Prerequisites - System Tools

This project depends on external system tools in addition to Python.

ExifTool

Used for extracting image metadata (including RAW formats).

  • Supports all major image formats, including RAW
  • Provides consistent metadata fields across formats
  • More reliable than Python-only EXIF libraries

If exiftool is not installed, the CLI will fail with a clear error message and exit code 1.

Install (macOS)

brew install exiftool

On Linux, install via your package manager (e.g. apt install exiftool).

Installation

Using pipx (recommended)

pipx install photo-tools-cli

Installs the CLI in an isolated environment and makes photo-tools available globally, avoiding dependency conflicts.

Using pip (if pipx not available)

pip install photo-tools-cli

Local development

Clone the repository and install:

pip install -e .
pip install --group dev -e .

Usage

List available commands:

photo-tools --help

Each command provides detailed usage, including arguments and options:

photo-tools <command> --help

Note: All commands currently process files in the top-level input directory only.

Global flags

All commands support:

  • --dry-run — preview changes without modifying files
  • --verbose / -v — show per-file output

Flags can be combined:

photo-tools <command> ... --dry-run --verbose

Organise by date (by-date)

  • Organise images into date-based folders (YYYY-MM-DD, optional suffix)
  • Files are moved (not copied) into the output directory
  • If a destination file already exists, it is skipped (no overwrite)
photo-tools by-date <INPUT_DIR> <OUTPUT_DIR>
photo-tools by-date <INPUT_DIR> <OUTPUT_DIR> --suffix <SUFFIX>

Separate RAW files (raws)

  • Move RAW images into a raws/ subfolder within the input directory
  • Non-RAW files are left unchanged
  • Files are moved (not copied) in place
  • If a destination file already exists, it is skipped (no overwrite)
photo-tools raws <INPUT_DIR>

Clean unpaired RAW files (clean-raws)

  • Move RAW files to raws-to-delete/ if no matching JPG (same prefix) exists
  • Matching is based on filename prefix (e.g. abcd.RAF matches abcd_edit.jpg)
  • Files are moved (not deleted), making the operation reversible
photo-tools clean-raws <RAW_DIR> <JPG_DIR>

Optimise images (optimise)

  • Resize images to a maximum width of 2500px
  • Choose the highest quality that results in a file size ≤ 500 KB (never below 70%)
  • Saves optimised images with prefix lq_ in the same directory (overwrites existing files)
photo-tools optimise <INPUT_DIR>

Local Development Setup

Data

For convenience during development, you can create a local structure:

mkdir -p data/input data/output

Place test photos in:

data/input/

Running the CLI

You can run the CLI module directly for testing:

python -m photo_tools.cli by-date ./data/input ./data/output

Running tests

This project uses pytest:

pytest

Makefile

Common development tasks are available via the Makefile.

Project details


Download files

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

Source Distribution

photo_tools_cli-0.1.1.tar.gz (12.5 kB view details)

Uploaded Source

Built Distribution

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

photo_tools_cli-0.1.1-py3-none-any.whl (13.2 kB view details)

Uploaded Python 3

File details

Details for the file photo_tools_cli-0.1.1.tar.gz.

File metadata

  • Download URL: photo_tools_cli-0.1.1.tar.gz
  • Upload date:
  • Size: 12.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for photo_tools_cli-0.1.1.tar.gz
Algorithm Hash digest
SHA256 02778e7b402cd3b06fa17fbdc3f8888d41570b54a4828c59038bb306a72ec28f
MD5 49be189d4446d952b843a148c4287d88
BLAKE2b-256 77a23e0e6a33b343eb2019e7a96e5527508ccb365c4607c0b41e001c1e61e1c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for photo_tools_cli-0.1.1.tar.gz:

Publisher: publish.yml on aga87/python-photo-tools

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

File details

Details for the file photo_tools_cli-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for photo_tools_cli-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 88b9dff4cc17fc95951f292f599a92eadde339e57ed7ee91cd4d3e7e7acf01f8
MD5 12b295290b1b5306aced8553c8353ed1
BLAKE2b-256 ee7b01cb2eee3de651bd0f6ef709495da6be90073ae03b467facb529267595ca

See more details on using hashes here.

Provenance

The following attestation bundles were made for photo_tools_cli-0.1.1-py3-none-any.whl:

Publisher: publish.yml on aga87/python-photo-tools

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page