Python CLI tools for photography workflows
Project description
Python Photo Tools
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 git+https://github.com/aga87/python-photo-tools.git
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
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>
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-raws
- Move RAW files to
raws-to-delete/if no matching JPG (same prefix) exists - Matching is based on filename prefix (e.g.
abcd.RAFmatchesabcd_edit.jpg) - Files are moved (not deleted), making the operation reversible
photo-tools clean-raws <RAW_DIR> <JPG_DIR>
optimise
- Resize images to a maximum width of
2500px - Choose the highest quality that results in a file size ≤
500 KB(never below70%) - 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
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 photo_tools_cli-0.1.0.tar.gz.
File metadata
- Download URL: photo_tools_cli-0.1.0.tar.gz
- Upload date:
- Size: 12.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c6224a6f88d7bfe70bb5afa72ae8c95506dc535856193061dbddd1e325e5e9f
|
|
| MD5 |
fc6273bb58cb2e2b4392d93852389178
|
|
| BLAKE2b-256 |
e80729cf7765da3f916e2a44e530aba82d22f0a4aa953f872de4017fa7876e75
|
File details
Details for the file photo_tools_cli-0.1.0-py3-none-any.whl.
File metadata
- Download URL: photo_tools_cli-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64c2ecd41be093dbee1921e3776bf0e6ee09e0d61934b24c2fc7776099175de0
|
|
| MD5 |
498ac3ff3e1d5409404b02399e61cbd2
|
|
| BLAKE2b-256 |
0c232fa61b3940b289c32d399d49867da81c6d1d33019ea81f5ade2c2803a6b3
|