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
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 (NikonmatchesNikonorNIKON 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 examplejpgorpng.jpgalso matches.jpeg--min-size— smallest file size, for example5mbor200kb--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)
| File | Size | Uploaded | |
|---|---|---|---|
| pixindex-0.1.0.tar.gz | 15.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|