Skip to main content

pixindex

pixindex looks through your pictures and writes down the useful facts about each one: size, camera, date, and whether the photo has a GPS location.

You run it in the terminal. It does not start a website, a queue, or a background service.

It works on a folder on your computer, or on pictures in an Amazon S3 bucket.

What it does today

Point it at a folder. It finds .jpg, .jpeg, .png, and .webp files.

For each picture it saves:

  • the full path
  • file size
  • width and height
  • camera make and model, if the file has that data
  • when the photo was taken, if the file has that data
  • GPS coordinates, if the file has them

That list is stored in a single SQLite file on your machine. Think of it as a notebook, not a photo library. pixindex does not move, copy, or change your pictures.

Hidden files (names that start with .) and folders that start with . are skipped.

Install

You need Python 3.12 or newer.

On Ubuntu, if python3.12 -m venv fails, run sudo apt install python3.12-venv first.

python3.12 -m venv .venv
source .venv/bin/activate
pip install -e .
pixindex --help

Use it

Index a folder and keep the notebook in the current directory:

pixindex --db ./catalog.sqlite index ./photos

Or index one picture:

pixindex --db ./catalog.sqlite index ./photos/beach.jpg

Or an S3 prefix. pixindex uses your normal AWS credentials (AWS_PROFILE or AWS_ACCESS_KEY_ID). It does not change objects in the bucket.

pixindex --db ./catalog.sqlite index s3://my-bucket/photos/2024/

JPEG files on S3 are read from the start of the object only, enough to get the metadata. PNG and WebP are downloaded in full. The next run skips objects whose ETag has not changed.

When it finishes you will see something like:

Indexed 12, skipped 0, failed 0.
  • indexed — new or changed pictures written to the notebook
  • skipped — already in the notebook, and the file has not changed
  • failed — not a readable image; pixindex prints the path and continues

If you press Ctrl+C, it stops. Pictures it already saved stay in the notebook. Run the same command again to continue. Unchanged files are skipped.

If you leave out --db, the notebook is stored at:

~/.local/share/pixindex/index.sqlite

Run it again

Same folder, same --db:

pixindex --db ./catalog.sqlite index ./photos

pixindex only re-reads a file if the size or the last-modified time changed. A large folder is slow the first time. Later runs are mostly a quick check.

See a summary

Use the same --db as when you indexed:

pixindex --db ./catalog.sqlite stat

You get a short report: how many pictures, how much space they take, the date range, how many have GPS, and which cameras showed up.

To summarize only one folder you already indexed:

pixindex --db ./catalog.sqlite stat --source ./photos

If you have not indexed anything yet, stat tells you that and exits.

Search prints one file path per line. Use the same --db as when you indexed.

pixindex --db ./catalog.sqlite search --camera Nikon --has-gps
pixindex --db ./catalog.sqlite search --after 2024-06-01 --before 2024-08-31
pixindex --db ./catalog.sqlite search --ext jpg --min-size 5mb
pixindex --db ./catalog.sqlite search --source ./photos --no-gps

You can combine flags. A picture must match all of them.

  • --camera — make or model contains this text (Nikon matches Nikon or NIKON Z8)
  • --after / --before — date the photo was taken, YYYY-MM-DD. Both ends are included. Pictures with no date are left out.
  • --has-gps / --no-gps — has a location, or does not
  • --ext — file type, for example jpg or png. jpg also matches .jpeg
  • --min-size — smallest file size, for example 5mb or 200kb
  • --source — only pictures from one folder you already indexed

No matches means no output. That is normal.

If a date or size does not look right, pixindex says so and exits.

Export

Export writes the same matches as search, as a table. It prints to the terminal. Redirect it to a file if you want to keep it.

pixindex --db ./catalog.sqlite export csv > inventory.csv
pixindex --db ./catalog.sqlite export json > inventory.json
pixindex --db ./catalog.sqlite export csv --camera Nikon --has-gps > nikon-gps.csv

csv is for a spreadsheet. json is for a script. The columns are path, folder, size, width, height, date taken, camera, and GPS.

Export accepts the same filters as search. An empty result is still a valid file: CSV has only the header row, JSON is [].

Anything other than csv or json is an error.

--source also works with an S3 prefix you already indexed:

pixindex --db ./catalog.sqlite search --source s3://my-bucket/photos/2024
pixindex --db ./catalog.sqlite stat --source s3://my-bucket/photos/2024

If AWS credentials are missing, or the bucket cannot be listed, pixindex says so and exits. A single unreadable object is one error line; the rest continue.

Tests

source .venv/bin/activate
pip install -e ".[dev]"
pytest

Metadata

Release files for pixindex 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pixindex 0.1.0
File Size Uploaded
pixindex-0.1.0.tar.gz 15.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pixindex 0.1.0
File Interpreter ABI Platform
pixindex-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 30.9 kB

Release files / pixindex-0.1.0.tar.gz

Download URL pixindex-0.1.0.tar.gz
Size 15.4 kB
Tags Source
SHA-256 checksum
How to use checksums
d0f3de85e94ecd0295f8a0138847ea58fbf59a14482f146ac54e2dc064e7bd6c
BLAKE2b-256 checksum
How to use checksums
6a6488d2aae54834de35a660c2cba12ccf4b87c205eb0cc014731b51b392080b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / pixindex-0.1.0-py3-none-any.whl

Download URL pixindex-0.1.0-py3-none-any.whl
Size 15.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a021bc0f3592428deab0312666424840f708f6f6b39ed64d7fa05b03d86e6bcb
BLAKE2b-256 checksum
How to use checksums
98a219b312f9acfc2122e1c126bbf62fdb2d90759560f4adf41dd9b4337ab47f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

This release

0.1.0 This release

2 release 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