My agentic slop goes here. Not intended for anyone else!
1# Immiche - Immich API Client Library 2 3A clean Eio-based OCaml library for interacting with Immich instances, focusing on people and face recognition data. 4 5## Overview 6 7Immiche 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. 8 9## Features 10 11- Fetch all people from an Immich instance 12- Search for people by name 13- Fetch individual person details 14- Download person thumbnails 15- Full Eio integration (no Lwt dependency) 16- Type-safe API with result types for error handling 17 18## API 19 20### Types 21 22```ocaml 23(* Client type - encapsulates session with connection pooling *) 24type ('clock, 'net) t 25 26type person = { 27 id: string; 28 name: string; 29 birth_date: string option; 30 thumbnail_path: string; 31 is_hidden: bool; 32} 33 34type people_response = { 35 total: int; 36 visible: int; 37 people: person list; 38} 39``` 40 41### Client Creation 42 43#### `create` 44Create an Immich client with connection pooling. 45 46```ocaml 47val create : 48 sw:Eio.Switch.t -> 49 env:< clock: _ ; net: _ ; fs: _ ; .. > -> 50 ?requests_session:('clock, 'net) Requests.t -> 51 base_url:string -> 52 api_key:string -> 53 unit -> ('clock, 'net) t 54``` 55 56**Parameters:** 57- `sw` - Eio switch for resource management 58- `env` - Eio environment (provides clock, net, fs) 59- `requests_session` - Optional Requests session for connection pooling. If not provided, a new session is created. 60- `base_url` - Base URL of the Immich instance (e.g., "https://photos.example.com") 61- `api_key` - API key for authentication 62 63**Returns:** An Immich client configured for the specified instance 64 65### API Functions 66 67All API functions take a client as their first parameter. The client automatically handles: 68- Connection pooling (reuses TCP connections) 69- Authentication (API key set as default header) 70- Base URL configuration 71 72#### `fetch_people` 73Fetch all people from an Immich instance. 74 75```ocaml 76val fetch_people : ('clock, 'net) t -> people_response 77``` 78 79#### `search_person` 80Search for people by name. 81 82```ocaml 83val search_person : ('clock, 'net) t -> name:string -> person list 84``` 85 86#### `fetch_person` 87Fetch details for a specific person. 88 89```ocaml 90val fetch_person : ('clock, 'net) t -> person_id:string -> person 91``` 92 93#### `download_thumbnail` 94Download a person's thumbnail image. 95 96```ocaml 97val download_thumbnail : 98 ('clock, 'net) t -> 99 fs:_ Eio.Path.t -> 100 person_id:string -> 101 output_path:string -> 102 (unit, [> `Msg of string]) result 103``` 104 105## Example Usage 106 107### Basic Usage 108 109```ocaml 110open Eio.Std 111 112let () = 113 Eio_main.run @@ fun env -> 114 Switch.run @@ fun sw -> 115 116 (* Create client once with connection pooling *) 117 let client = Immiche.create ~sw ~env 118 ~base_url:"https://photos.example.com" 119 ~api_key:"your-api-key" () in 120 121 (* Fetch all people - connection pooling automatic *) 122 let response = Immiche.fetch_people client in 123 Printf.printf "Total people: %d\n" response.total; 124 125 (* Search for a person - reuses connections *) 126 let results = Immiche.search_person client ~name:"John" in 127 128 (* Download first result's thumbnail *) 129 match results with 130 | person :: _ -> 131 let result = Immiche.download_thumbnail client 132 ~fs:(Eio.Stdenv.fs env) 133 ~person_id:person.id 134 ~output_path:"thumbnail.jpg" in 135 begin match result with 136 | Ok () -> print_endline "Thumbnail downloaded!" 137 | Error (`Msg err) -> Printf.eprintf "Error: %s\n" err 138 end 139 | [] -> print_endline "No results found" 140``` 141 142### Sharing Connection Pools 143 144You can share a `Requests.t` session across multiple API clients for maximum connection reuse: 145 146```ocaml 147Eio_main.run @@ fun env -> 148Switch.run @@ fun sw -> 149 150 (* Create shared Requests session *) 151 let shared_session = Requests.create ~sw env in 152 153 (* Create multiple clients sharing the same connection pools *) 154 let immich1 = Immiche.create ~sw ~env ~requests_session:shared_session 155 ~base_url:"https://photos1.example.com" 156 ~api_key:"key1" () in 157 158 let immich2 = Immiche.create ~sw ~env ~requests_session:shared_session 159 ~base_url:"https://photos2.example.com" 160 ~api_key:"key2" () in 161 162 (* Both clients share the same connection pools! *) 163 let people1 = Immiche.fetch_people immich1 in 164 let people2 = Immiche.fetch_people immich2 in 165 () 166``` 167 168## Dependencies 169 170- `eio` - Concurrent I/O library 171- `requests` - HTTP client library 172- `ezjsonm` - JSON parsing 173- `uri` - URI encoding 174- `fmt` - Formatting 175- `ptime` - Time handling 176 177## Implementation Notes 178 179- Uses `Requests.t` for session-based HTTP requests with connection pooling 180- Authentication via `x-api-key` header (set as default on session creation) 181- Direct Eio style - no Lwt dependencies 182- Connection pools shared across derived sessions 183- Extracted and adapted from `bushel/bin/bushel_faces.ml` 184 185## Benefits 186 187**Connection Pooling** - Automatic TCP connection reuse across requests 188**Clean API** - Session-level configuration passed once, not per-request 189**Injectable Sessions** - Can share `Requests.t` across multiple libraries 190**Type Safety** - Client parameterized by clock/net types 191**Immutable Configuration** - Derived sessions don't affect original 192 193## License 194 195ISC