# Immiche - Immich API Client Library A clean Eio-based OCaml library for interacting with Immich instances, focusing on people and face recognition data. ## Overview Immiche provides a straightforward API for interacting with Immich's people management endpoints. It uses the Requests library for HTTP operations and follows Eio patterns for concurrency and resource management. ## Features - Fetch all people from an Immich instance - Search for people by name - Fetch individual person details - Download person thumbnails - Full Eio integration (no Lwt dependency) - Type-safe API with result types for error handling ## API ### Types ```ocaml (* Client type - encapsulates session with connection pooling *) type ('clock, 'net) t type person = { id: string; name: string; birth_date: string option; thumbnail_path: string; is_hidden: bool; } type people_response = { total: int; visible: int; people: person list; } ``` ### Client Creation #### `create` Create an Immich client with connection pooling. ```ocaml val create : sw:Eio.Switch.t -> env:< clock: _ ; net: _ ; fs: _ ; .. > -> ?requests_session:('clock, 'net) Requests.t -> base_url:string -> api_key:string -> unit -> ('clock, 'net) t ``` **Parameters:** - `sw` - Eio switch for resource management - `env` - Eio environment (provides clock, net, fs) - `requests_session` - Optional Requests session for connection pooling. If not provided, a new session is created. - `base_url` - Base URL of the Immich instance (e.g., "https://photos.example.com") - `api_key` - API key for authentication **Returns:** An Immich client configured for the specified instance ### API Functions All API functions take a client as their first parameter. The client automatically handles: - Connection pooling (reuses TCP connections) - Authentication (API key set as default header) - Base URL configuration #### `fetch_people` Fetch all people from an Immich instance. ```ocaml val fetch_people : ('clock, 'net) t -> people_response ``` #### `search_person` Search for people by name. ```ocaml val search_person : ('clock, 'net) t -> name:string -> person list ``` #### `fetch_person` Fetch details for a specific person. ```ocaml val fetch_person : ('clock, 'net) t -> person_id:string -> person ``` #### `download_thumbnail` Download a person's thumbnail image. ```ocaml val download_thumbnail : ('clock, 'net) t -> fs:_ Eio.Path.t -> person_id:string -> output_path:string -> (unit, [> `Msg of string]) result ``` ## Example Usage ### Basic Usage ```ocaml open Eio.Std let () = Eio_main.run @@ fun env -> Switch.run @@ fun sw -> (* Create client once with connection pooling *) let client = Immiche.create ~sw ~env ~base_url:"https://photos.example.com" ~api_key:"your-api-key" () in (* Fetch all people - connection pooling automatic *) let response = Immiche.fetch_people client in Printf.printf "Total people: %d\n" response.total; (* Search for a person - reuses connections *) let results = Immiche.search_person client ~name:"John" in (* Download first result's thumbnail *) match results with | person :: _ -> let result = Immiche.download_thumbnail client ~fs:(Eio.Stdenv.fs env) ~person_id:person.id ~output_path:"thumbnail.jpg" in begin match result with | Ok () -> print_endline "Thumbnail downloaded!" | Error (`Msg err) -> Printf.eprintf "Error: %s\n" err end | [] -> print_endline "No results found" ``` ### Sharing Connection Pools You can share a `Requests.t` session across multiple API clients for maximum connection reuse: ```ocaml Eio_main.run @@ fun env -> Switch.run @@ fun sw -> (* Create shared Requests session *) let shared_session = Requests.create ~sw env in (* Create multiple clients sharing the same connection pools *) let immich1 = Immiche.create ~sw ~env ~requests_session:shared_session ~base_url:"https://photos1.example.com" ~api_key:"key1" () in let immich2 = Immiche.create ~sw ~env ~requests_session:shared_session ~base_url:"https://photos2.example.com" ~api_key:"key2" () in (* Both clients share the same connection pools! *) let people1 = Immiche.fetch_people immich1 in let people2 = Immiche.fetch_people immich2 in () ``` ## Dependencies - `eio` - Concurrent I/O library - `requests` - HTTP client library - `ezjsonm` - JSON parsing - `uri` - URI encoding - `fmt` - Formatting - `ptime` - Time handling ## Implementation Notes - Uses `Requests.t` for session-based HTTP requests with connection pooling - Authentication via `x-api-key` header (set as default on session creation) - Direct Eio style - no Lwt dependencies - Connection pools shared across derived sessions - Extracted and adapted from `bushel/bin/bushel_faces.ml` ## Benefits ✅ **Connection Pooling** - Automatic TCP connection reuse across requests ✅ **Clean API** - Session-level configuration passed once, not per-request ✅ **Injectable Sessions** - Can share `Requests.t` across multiple libraries ✅ **Type Safety** - Client parameterized by clock/net types ✅ **Immutable Configuration** - Derived sessions don't affect original ## License ISC