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.2.tar.gz (65.1 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.2-py3-none-any.whl (23.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: immich_export-0.0.2.tar.gz
  • Upload date:
  • Size: 65.1 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.2.tar.gz
Algorithm Hash digest
SHA256 42970f4d13bd0e3f07d5f6cf776454eac019b157e90dcc0cd923d71ebe741ed5
MD5 ed27aca0ad6809348614405675387d60
BLAKE2b-256 00ecd8a66b58f5bb5c532c38d0594bbc21b87aa10399d58e76b466b299d1f715

See more details on using hashes here.

Provenance

The following attestation bundles were made for immich_export-0.0.2.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.2-py3-none-any.whl.

File metadata

  • Download URL: immich_export-0.0.2-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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 740542f24c54b5645b2c12d6fbe98a575ac59cc694b2558ca1866ac8d9d40a97
MD5 f7bf134ba92e770d543e34fd4eaf70d0
BLAKE2b-256 5f0eabee5f7bf9b3fea05528ba6158a8ae054904ad1aeb9ed40bc0bca59948aa

See more details on using hashes here.

Provenance

The following attestation bundles were made for immich_export-0.0.2-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