Skip to main content

Madify

CI Release Python 3.12+ License: MIT Coverage Discussions Sponsor uv Ruff

Madify is a local CLI that catalogues photo, PSD, and video files in SQLite, lets you set titles/descriptions/tags, and renames files from those titles. On tag, it also writes an XMP sidecar next to the media file (catalog stays source of truth). The core never touches the filesystem, database, or clock directly — those are injected ports so unit tests stay deterministic.

Features

  • Recursive scan into SQLite (images, Photoshop .psd/.psb, common video)
  • Tag by id or path — tags merge by default; --replace-tags replaces the set
  • XMP sidecar write-back on tag (--no-sidecar to skip)
  • List / search the catalog
  • Rename from sanitized titles (Clip One → Clip_One.jpg), collisions → _2, _3, …
  • Zero runtime dependencies (stdlib only)
  • Injectable Clock / FileSystem / CatalogStore / MetadataWriter ports

Install

Requires Python ≥ 3.12 and uv.

git clone https://github.com/sgm-audio/Madify.git
cd Madify
uv sync --group dev
uv run madify
Madify 0.2.1

After PyPI trusted publishing is configured (see below):

uv tool install madify
# or: pip install madify

Quickstart

Keep the catalog outside the media folder so the .sqlite file is not skipped as unsupported media.

# PowerShell demo layout
$demo = Join-Path $env:TEMP "madify-demo"
$dbdir = Join-Path $env:TEMP "madify-db"
New-Item -ItemType Directory -Path $demo, $dbdir -Force | Out-Null
Set-Content "$demo\a.jpg" "x"
Set-Content "$demo\b.psd" "x"
Set-Content "$demo\c.mp4" "x"
Set-Content "$demo\readme.txt" "skip"
$db = Join-Path $dbdir "catalog.sqlite"
uv run madify --db $db scan $demo
uv run madify --db $db tag --id 1 --title "Clip One" --tag demo --tag photo
uv run madify --db $db list
uv run madify --db $db search --query clip
uv run madify --db $db rename --id 1

Commands

Command Purpose
madify scan <dir> Upsert supported media under <dir>
madify tag --id N | --path P Set title/description/tags (+ XMP sidecar)
madify rename [--id N] Rename from titles
madify list List all assets
madify search [--query Q] [--tag T] Filter assets

Global: --db PATH (default madify.sqlite).

Architecture

Module Role
cli.py Argparse wiring
models.py / errors.py Domain types and errors
media_kinds.py Extension → image / PSD / video
tagging.py Normalize/validate; tag merge/replace
naming.py Title → filename + collisions
ports.py Clock / FS / Catalog / MetadataWriter protocols
scan.py / tag_asset.py / rename_assets.py Use cases
query.py List / search filters
xmp_sidecar.py XMP sidecar writer
sqlite_catalog.py / local_fs.py / system_clock.py Adapters

Development

uv sync --group dev
uv run pre-commit install
uv build
uv run ruff check .
uv run ruff format --check .
uv run pytest -q --cov=madify --cov-report=term-missing
uv run pdoc madify -d google -o docs/api

API HTML lands in docs/api/ (gitignored).

See CHANGELOG.md, SECURITY.md, and CODE_OF_CONDUCT.md.

PyPI trusted publishing (one-time, manual)

  1. Create a PyPI project named madify (or claim the name).
  2. On PyPI → Publishing → add a trusted publisher:
    • Owner: sgm-audio
    • Repository: Madify
    • Workflow: publish.yml
    • Environment: pypi
  3. On GitHub → Settings → Environments → create pypi (optional protection rules).
  4. Publish a GitHub Release — the Publish workflow uploads wheels via OIDC (no API token).

License

MIT — see LICENSE. Copyright (c) 2026 Scott Mills.

Appendix: Supported extensions

Classification is extension-only (case-insensitive). Anything else is skipped on scan.

Kind Extensions
Image .jpg, .jpeg, .png, .gif, .webp, .tif, .tiff, .bmp, .heic, .heif, .raw, .cr2, .nef, .arw, .dng, .orf, .rw2
Photoshop .psd, .psb
Video .mp4, .mov, .mkv, .avi, .webm, .m4v, .wmv, .mpg, .mpeg, .3gp

Metadata

Release files for madify 0.2.1

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

Source distribution (sdist)

Source distribution for madify 0.2.1
File Size Uploaded
madify-0.2.1.tar.gz 17.4 kB Details

Built distribution (wheel)

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

Total release size: 41.5 kB

Release files / madify-0.2.1.tar.gz

Download URL madify-0.2.1.tar.gz
Size 17.4 kB
Tags Source
SHA-256 checksum
How to use checksums
fd9a712aaa6cfa072b3610b14309f12f00948f3ea85a7ecebd5592faa71de6c4
BLAKE2b-256 checksum
How to use checksums
3a95e816ba7fa6cded29aee0935e1cbf49d66df0ddb09dfdcc70c52929f23064
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 22, 2026.

Transparency log

Release files / madify-0.2.1-py3-none-any.whl

Download URL madify-0.2.1-py3-none-any.whl
Size 24.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
80cc96ed420d77de8e0201c9358a9ed70550dffb8c5565fe90670c46eba92fc0
BLAKE2b-256 checksum
How to use checksums
77e7a7f854756b1eae21a19800a272a9c9cbba7b95fcbdf119a594879dad1c78
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 22, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

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