Build and push server image / build-and-push (push) Failing after 2m33s
GET /api/albums/{id} was assumed to return an "assets" array alongside
the album metadata (that's what the original plan/prior art expected),
but on Immich 3.0.3 AlbumResponseDto only has assetCount -- no assets
field at all. Confirmed against the OpenAPI spec served at
/api/spec.json and by testing directly against a real instance: the
assumption was simply wrong for this API version, not a permissions
issue (the album metadata call succeeds fine with a valid 200).
Assets for an album now come from POST /api/search/metadata with an
albumIds filter, which returns them under assets.items. Verified
end-to-end against the real Immich instance and album -- /frame/image
now returns a proper 200 with exactly 192,000 bytes, spread across all
six panel colors (not a degenerate all-white/black response).
Only fetches the first page of search results; fine for a photo frame
cycling through an album, but would need nextPage handling for anyone
pointing this at a very large album.
45 lines
1.5 KiB
Python
45 lines
1.5 KiB
Python
"""Thin wrapper around the bits of the Immich API this project needs."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import httpx
|
|
|
|
|
|
class ImmichClient:
|
|
def __init__(self, base_url: str, api_key: str):
|
|
self.base_url = base_url.rstrip("/")
|
|
self._headers = {"x-api-key": api_key}
|
|
|
|
def list_albums(self) -> list[dict]:
|
|
resp = httpx.get(f"{self.base_url}/api/albums", headers=self._headers, timeout=10)
|
|
resp.raise_for_status()
|
|
return resp.json()
|
|
|
|
def list_album_assets(self, album_id: str) -> list[dict]:
|
|
"""GET /api/albums/{id} doesn't embed assets in this Immich version
|
|
(AlbumResponseDto only has assetCount) -- assets live behind the
|
|
general search API instead, filtered by albumIds.
|
|
|
|
Only returns the first page. Fine for a photo frame cycling
|
|
through an album; worth adding nextPage pagination if someone
|
|
points this at an album large enough to need it.
|
|
"""
|
|
resp = httpx.post(
|
|
f"{self.base_url}/api/search/metadata",
|
|
headers=self._headers,
|
|
json={"albumIds": [album_id]},
|
|
timeout=15,
|
|
)
|
|
resp.raise_for_status()
|
|
return resp.json().get("assets", {}).get("items", [])
|
|
|
|
def download_asset_preview(self, asset_id: str) -> bytes:
|
|
resp = httpx.get(
|
|
f"{self.base_url}/api/assets/{asset_id}/thumbnail",
|
|
params={"size": "preview"},
|
|
headers=self._headers,
|
|
timeout=30,
|
|
)
|
|
resp.raise_for_status()
|
|
return resp.content
|