Skip to main content

Export everything out of Immich — files plus albums, people, tags, descriptions — into a redundant, human-readable local folder tree.

Project description

immich-export

Pull everything out of Immich — the files and the metadata that only lives in its database (albums, people, tags, descriptions, favorites, geo) — into a redundant, human-readable local folder tree.

This is the media escape hatch that makes "Immich = source of truth" reversible: if Immich vanished tomorrow, the export is a plain tree you can browse, grep, or import anywhere else.

immich-export/
  library/2024/03/IMG_1234.jpg          # primary tree (self-contained mode)
  library/2024/03/IMG_1234.jpg.xmp      # sidecar: tags, people, albums, description, geo, favorite
  albums/Japan-2019/IMG_1234.jpg        # → symlink into library/
  people/Anna/IMG_1234.jpg              # → symlink into library/
  manifest.jsonl                        # one line per asset: id, checksum, path, all metadata
  manifest.csv                          # the same, human-readable
  export-report.txt                     # counts, warnings, errors, timing

Install

pipx install immich-export
# or
brew install fileworks/tap/immich-export

(Not yet published — first release pending; until then: uv run immich-export from a checkout.)

Usage

export IMMICH_SERVER=https://immich.local:2283
export IMMICH_API_KEY=...   # Immich → Account Settings → API Keys

# full portable export (copies originals)
immich-export --out ./immich-export

# incremental re-run: only new/changed assets are downloaded
immich-export --out ./immich-export

# sidecar mode: you already have the Storage-Template tree mounted —
# only write .xmp sidecars + album/people views next to it
immich-export --mode sidecar --library-root /volume1/photos --out /volume1/photos

# custom primary tree
immich-export --layout "{year}/{album}" --out ./export

Key flags (see immich-export --help for all):

Flag Default Meaning
--mode self-contained self-contained copies originals; sidecar only writes XMP + views next to an existing tree
--layout {year}/{month} primary tree; tokens {year} {month} {day} {album} {type}; {album} falls back to Unsorted
--album-view / --people-view on build albums/ and people/ symlink views
--sidecars xmp xmp or none
--since only assets taken on/after this date
--resume on skip assets already exported with an unchanged checksum (from manifest.jsonl)
--include-hidden off also export hidden + locked-folder assets

Guarantees

  • Read-only against Immich. Never writes back.
  • Best-effort. One bad asset logs an error and the run continues; the report lists every failure.
  • Idempotent / resumable. The manifest records each asset's checksum; re-runs download only new or changed files, and refresh sidecars when only metadata (albums/tags/people) changed.
  • Verifiable. Every download is checked against Immich's SHA-1; manifest.jsonl lets you diff export-vs-server (or vs. a restore) any time.
  • Streams. Assets are paged and downloaded with bounded concurrency — a 100k-asset library never sits in memory.

Exit codes

Code Meaning
0 success (including an empty library)
2 bad configuration or authentication failure
3 server unreachable
4 output directory unwritable / out of space
1 unexpected error (re-run with --verbose for the traceback)

Sidecar format

Standard XMP wherever a standard slot exists — dc:subject (tags), Iptc4xmpExt:PersonInImage (people), dc:description, photoshop:DateCreated, exif:GPSLatitude/Longitude, xmp:Rating (favorite → 5) — so digiKam, Lightroom and exiftool can read them. Album membership and Immich ids live in a custom immich: namespace in the same file.

Immich API compatibility

Built against the Immich v3 API (spec version 3.0.1). Instead of a generated client, the exact API slice used is declared in src/immich_export/api_contract.py and checked in CI against a vendored, pruned copy of the official OpenAPI spec. To check a new Immich release:

uv run python scripts/refresh_api_spec.py --ref v3.1.0
uv run pytest tests/test_contract.py

A removed endpoint or field fails the tests before it breaks at runtime.

Development

uv sync --all-extras --dev
uv run ruff check . && uv run ruff format --check .   # lint
uv run mypy                                           # strict types
uv run pytest                                         # tests (mock Immich API)
uv build                                              # sdist + wheel

Conventional Commits drive releases (python-semantic-release): merge to main → version bump + changelog + GitHub Release + PyPI publish (OIDC) + Homebrew formula bump.

License

MIT

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

immich_export-0.0.3.tar.gz (65.6 kB view details)

Uploaded Source

Built Distribution

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

immich_export-0.0.3-py3-none-any.whl (23.5 kB view details)

Uploaded Python 3

File details

Details for the file immich_export-0.0.3.tar.gz.

File metadata

  • Download URL: immich_export-0.0.3.tar.gz
  • Upload date:
  • Size: 65.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for immich_export-0.0.3.tar.gz
Algorithm Hash digest
SHA256 caa6d7b0f8e20f46f867f81faf8cba30c47d9c9b0d8fe4a8cba5e08b412de824
MD5 0bf0feb95f1941f9e6ccee946c96942c
BLAKE2b-256 2e6ef3d3ff9b92ecefe8dab872b9e712f06debcb033680497f7185d30b1182db

See more details on using hashes here.

Provenance

The following attestation bundles were made for immich_export-0.0.3.tar.gz:

Publisher: release.yml on fileworks/immich-export

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

File details

Details for the file immich_export-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: immich_export-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 23.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for immich_export-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 31536753bdab01d7eb6f72b71e3feb14905ab7ebdb61e12bd3fad012c30a6f0e
MD5 fdfbc66c633f45cb4a4aa5bc9044c993
BLAKE2b-256 c67856e6c622af994647f993898ef502cd9e43ef9523092aab0e04c95e1928ae

See more details on using hashes here.

Provenance

The following attestation bundles were made for immich_export-0.0.3-py3-none-any.whl:

Publisher: release.yml on fileworks/immich-export

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