Skip to main content

ImmichApiClient

Struct ImmichApiClient 

Source
pub struct ImmichApiClient {
    pub client: Client,
    settings: RwLock<ApiClientSettings>,
    pub active_url: Mutex<Option<String>>,
    last_issue: Mutex<Option<ApiIssue>>,
    album_cache: Mutex<HashMap<String, String>>,
    album_create_locks: Mutex<HashMap<String, Arc<Mutex<()>>>>,
    album_fetch_lock: Mutex<()>,
    connection_check_lock: Mutex<()>,
    last_successful_check: Mutex<Option<Instant>>,
    albums_fetched: Mutex<bool>,
    thumbnail_semaphore: Arc<Semaphore>,
}
Expand description

Asynchronous Immich API client with failover and request serialization.

Fields§

§client: Client

Internal HTTP client instance.

§settings: RwLock<ApiClientSettings>

Configuration settings wrapper.

§active_url: Mutex<Option<String>>

The currently active base URL, selected by the last successful connectivity check.

§last_issue: Mutex<Option<ApiIssue>>

Most recent actionable API/client problem, used for the dashboard and diagnostics.

§album_cache: Mutex<HashMap<String, String>>

Caches album names to album IDs to avoid repeated list/create API calls.

§album_create_locks: Mutex<HashMap<String, Arc<Mutex<()>>>>

Per-album-name async locks that serialize concurrent get-or-create calls for the same name, preventing duplicate-album creation under load.

§album_fetch_lock: Mutex<()>

Serializes fetch_all_albums so concurrent callers don’t all hit the network and race writes into the cache.

§connection_check_lock: Mutex<()>

Serializes check_connection so concurrent callers collapse into one connectivity probe instead of each issuing their own LAN+WAN pings.

§last_successful_check: Mutex<Option<Instant>>

Timestamp of the most recent successful connectivity probe. Used to coalesce concurrent burst callers without suppressing periodic re-checks.

§albums_fetched: Mutex<bool>

Flag indicating whether the album list has been successfully fetched in this session.

§thumbnail_semaphore: Arc<Semaphore>

Semaphore guarding maximum concurrent thumbnail downloads.

Implementations§

Source§

impl ImmichApiClient

Source

async fn fetch_all_albums(&self)

Retrieve all albums from the Immich server, populating the local in-memory cache.

Source

async fn fetch_all_albums_locked(&self)

Inner fetch implementation. Assumes album_fetch_lock is held by the caller and albums_fetched is already known to be false.

Source

async fn handle_fetch_albums_response(&self, result: Result<Response, Error>)

Source

fn process_album_summaries( albums: Vec<AlbumSummary>, ) -> (HashMap<String, String>, usize, usize)

Source

pub async fn refresh_album_cache(&self)

Source

pub async fn get_all_albums(&self) -> Result<Vec<(String, String)>, String>

Return a snapshot of all cached albums as a list of (albumName, id)

Source

pub async fn create_album( &self, album_name: &str, ) -> Result<Option<String>, String>

Create a new album. Returns the new album ID.

Source

pub async fn get_or_create_album( &self, album_name: &str, ) -> Result<Option<String>, String>

Return an existing album ID or create a new one.

Source

pub async fn get_album_id_if_exists( &self, album_name: &str, ) -> Result<Option<String>, String>

Return an existing album ID without creating a new album as a side effect.

Source

pub async fn resolve_album_by_name( &self, album_name: &str, force_refresh: bool, ) -> Result<Option<String>, String>

Source

pub async fn bulk_existing_asset_ids( &self, checksums: &[String], ) -> HashMap<String, String>

Check whether an asset already exists on the server by checksum and return its asset ID. Batch checksum existence check. Returns a map from checksum to asset id for every checksum the server already has. Missing checksums are absent from the result. The Immich endpoint accepts arbitrary batch sizes, but we chunk to keep request bodies modest.

Source

pub async fn find_existing_asset_id(&self, checksum: &str) -> Option<String>

Source

pub async fn add_assets_to_album( &self, album_id: &str, asset_ids: &[String], ) -> bool

Add a list of asset IDs to an album.

Source

pub async fn count_albums_for_asset(&self, asset_id: &str) -> Option<usize>

Count the albums that currently contain the given asset on the server. Drives the trash-vs-remove-from-album decision when mirroring a local deletion: an asset in multiple albums should only be unlinked from the linked album, never destroyed.

Source

pub async fn remove_assets_from_album( &self, album_id: &str, asset_ids: &[String], ) -> bool

Remove assets from an album without trashing them on the server. Used when an asset is referenced from more than one watch folder — we want to mirror the local deletion’s album side, not destroy the asset.

Source§

impl ImmichApiClient

Source

pub async fn fetch_library_albums(&self) -> Result<Vec<LibraryAlbum>, String>

Retrieve the complete list of albums from the Immich server for library display.

Source

pub async fn fetch_album_assets( &self, album_id: &str, page: u32, size: u32, order: Option<SortOrder>, ) -> Result<(Vec<LibraryAsset>, bool), String>

Retrieve paginated assets contained in a specific album.

Source

pub async fn fetch_thumbnail( &self, asset_id: &str, size: ThumbnailSize, ) -> Result<Vec<u8>, String>

Retrieve raw thumbnail/preview image byte array for a given asset ID.

Source

async fn fetch_asset_generic<T: DeserializeOwned>( &self, asset_id: &str, ) -> Result<T, String>

Generic helper to fetch asset JSON details.

Source

pub async fn fetch_asset_details( &self, asset_id: &str, ) -> Result<AssetDetails, String>

Retrieve full EXIF metadata and details for a given asset ID.

Source

pub async fn fetch_asset_by_id( &self, asset_id: &str, ) -> Result<LibraryAsset, String>

Fetch a single asset as a LibraryAsset by its ID.

Source

pub async fn download_original_to_file( &self, asset_id: &str, output_path: &Path, progress: Option<Arc<dyn Fn(u64, Option<u64>) + Send + Sync>>, ) -> Result<(), String>

Download original source file of a given asset ID and save it locally.

Source

pub async fn fetch_current_user_id(&self) -> Result<String, String>

Fetch unique user ID of the logged-in API user.

Source

pub async fn delete_assets(&self, asset_ids: &[String]) -> Result<(), String>

Soft-delete specified assets from the Immich server.

Source§

impl ImmichApiClient

Source

pub async fn fetch_people( &self, include_hidden: bool, ) -> Result<Vec<Person>, String>

Fetch the list of recognized people faces from the server.

Source

pub async fn fetch_explore(&self) -> Result<Vec<ExploreSection>, String>

Sectioned tile data (places + things) for the Explore landing.

Source

pub async fn fetch_all_places(&self) -> Result<Vec<PlaceItem>, String>

Fetch all unique cities that have at least one asset with EXIF city data. Pages through /api/search/metadata collecting one representative asset per city. Caps at 500 pages to bound runtime on very large libraries.

Source

pub async fn fetch_person_thumbnail( &self, person_id: &str, ) -> Result<Vec<u8>, String>

Per-person face thumbnail. Distinct from fetch_thumbnail (asset).

Source

pub async fn search_smart( &self, query: &str, page: u32, size: u32, ) -> Result<(Vec<LibraryAsset>, bool), String>

Perform a CLIP embedding-based smart search for matching assets.

Source

pub async fn search_smart_filtered( &self, query: &str, filters: &MetadataSearchFilters, page: u32, size: u32, ) -> Result<(Vec<LibraryAsset>, bool), String>

CLIP-based smart search combined with metadata filters.

The Immich SmartSearchDto supports the same filter dimensions as MetadataSearchDto (location, date, type, etc.) alongside the CLIP query field. This method serialises the filters and injects the CLIP query on top.

Source

pub async fn search_ocr( &self, query: &str, page: u32, size: u32, order: Option<SortOrder>, ) -> Result<(Vec<LibraryAsset>, bool), String>

Perform an OCR-based search to match recognized text inside library images.

Source

pub async fn search_metadata( &self, query: &str, page: u32, size: u32, order: Option<SortOrder>, ) -> Result<(Vec<LibraryAsset>, bool), String>

Search library assets matching specific text within their original filenames.

Source

pub async fn search_metadata_with_filters( &self, filters: &MetadataSearchFilters, page: u32, size: u32, ) -> Result<(Vec<LibraryAsset>, bool), String>

Perform a advanced search matching specific metadata filters.

Source

pub async fn fetch_server_stats(&self) -> Result<ServerStats, String>

Retrieve total images, videos, and overall asset count statistics from the server.

Source

pub async fn fetch_server_statistics(&self) -> Result<ServerStatistics, String>

Fetch server-wide statistics including per-user usage breakdown.

Admin-only endpoint; non-admin sessions will receive an HTTP 403 and an Err is returned. Caller should fall back to per-user asset counts.

Source

pub async fn fetch_server_about(&self) -> Result<ServerAbout, String>

Retrieve detailed Immich server system information (e.g. version).

Source

pub(super) async fn fetch_search_assets( &self, endpoint: &str, body: Value, context: RequestContext, subject: Option<&str>, ) -> Result<(Vec<LibraryAsset>, bool), String>

Shared internal helper executing paginated POST search queries against asset endpoints.

Source§

impl ImmichApiClient

Source

pub async fn fetch_search_suggestions( &self, suggestion_type: &str, ) -> Result<Vec<String>, String>

Fetch autocomplete suggestions for a given metadata dimension.

suggestion_type must be one of: "country", "state", "city", "camera-make", "camera-model", "camera-lens-model".

Source§

impl ImmichApiClient

Source

pub async fn upload_asset( &self, file_path: &str, checksum: &str, sidecar_path: Option<&str>, progress: Option<Arc<dyn Fn(u64, Option<u64>) + Send + Sync>>, ) -> Option<String>

Upload a single local asset to the Immich server with progressive status tracking.

When sidecar_path points to an existing XMP file it is attached as the sidecarData multipart field so Immich ingests it alongside the asset.

Source

async fn handle_upload_response( &self, resp: Response, filename: &str, file_len: u64, desired_time_zone: &Option<String>, base_url: String, progress: Option<&Arc<dyn Fn(u64, Option<u64>) + Send + Sync>>, ) -> Option<String>

Source

async fn handle_upload_too_large(&self, filename: &str) -> Option<String>

Source

async fn handle_upload_auth_error(&self) -> Option<String>

Source

async fn handle_upload_server_error( &self, status: u16, filename: &str, ) -> Option<String>

Source

async fn handle_upload_unknown_error( &self, resp: Response, status: u16, filename: &str, ) -> Option<String>

Source

async fn set_upload_issue(&self, issue: ApiIssue)

Source

fn schedule_asset_timezone_fixup( &self, base_url: String, asset_id: String, time_zone: Option<String>, )

Schedule a background task to fix asset timezones after upload.

Source

async fn handle_upload_success( &self, resp: Response, filename: &str, file_len: u64, desired_time_zone: &Option<String>, base_url: String, progress: Option<&Arc<dyn Fn(u64, Option<u64>) + Send + Sync>>, ) -> Option<String>

Source

async fn handle_upload_duplicate( &self, resp: Response, filename: &str, file_len: u64, progress: Option<&Arc<dyn Fn(u64, Option<u64>) + Send + Sync>>, ) -> Option<String>

Source

async fn attach_sidecar(form: Form, sidecar_path: Option<&str>) -> Form

Source

async fn read_asset_metadata(&self, file_path: &str) -> Option<Metadata>

Source

async fn open_asset_file(&self, path: &Path, file_path: &str) -> Option<File>

Source

async fn check_active_url(&self, file_path: &str) -> Option<String>

Source

async fn execute_upload_request( &self, form: Form, base_url: String, filename: String, file_len: u64, desired_time_zone: Option<String>, progress: Option<Arc<dyn Fn(u64, Option<u64>) + Send + Sync>>, ) -> Option<String>

Source§

impl ImmichApiClient

Source

pub fn new(internal_url: String, external_url: String, api_key: String) -> Self

Initialize a new ImmichApiClient.

Source

pub async fn active_route_label(&self) -> Option<String>

Retrieve the route label (LAN/WAN) for the currently active connection URL.

Source

pub async fn latest_issue(&self) -> Option<ApiIssue>

Retrieve the most recently recorded API issue.

Source

pub async fn update_settings( &self, internal_url: String, external_url: String, api_key: String, )

Update in-memory configuration settings and reset connection state.

Source

pub(crate) async fn set_issue(&self, issue: ApiIssue)

Set the last encountered API issue.

Source

pub(crate) async fn clear_issue(&self)

Clear the active API issue.

Source

pub(crate) fn settings_snapshot(&self) -> ApiClientSettings

Retrieve a snapshot copy of the current configuration settings.

Source

pub(crate) fn route_label_for_url(&self, url: &str) -> String

Retrieve the LAN/WAN/Custom route label matching a specific URL.

Source

pub async fn check_connection(&self) -> bool

Determine which base URL to use, preferring the internal address when reachable.

Source

async fn try_activate_url(&self, url: &str, was_offline: bool) -> bool

Source

pub async fn ping_url(&self, url: &str) -> bool

Ping a specific Immich base URL and validate that it returns a real pong response.

Source

pub(crate) async fn get_active_url(&self) -> Option<String>

Return the cached active base URL, resolving connectivity first if needed.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more