Immich bindings and CLI in OCaml
1(*---------------------------------------------------------------------------
2 Copyright (c) 2025 Anil Madhavapeddy. All rights reserved.
3 SPDX-License-Identifier: ISC
4 ---------------------------------------------------------------------------*)
5
6(** Cmdliner helpers for Immich CLI authentication.
7
8 This module provides reusable command-line argument definitions and command
9 builders for authentication workflows. It supports multiple profiles for
10 managing multiple server connections.
11
12 {2 Usage}
13
14 {[
15 (* In your main.ml *)
16 Eio_main.run @@ fun env ->
17 let fs = env#fs in
18 Cmd.group (Cmd.info "immich")
19 [ Cmd.auth_cmd env fs
20 ; (* other commands *)
21 ]
22 |> Cmd.eval_exn
23 ]}
24
25 {2 Environment Variables}
26
27 - [IMMICH_SERVER]: Default server URL
28 - [IMMICH_API_KEY]: Default API key
29
30 {2 Logging}
31
32 Uses Logs_cli for verbosity control:
33 - [-v] or [--verbose]: Info level logging
34 - [-v -v] or [--verbosity=debug]: Debug level logging
35 - [--verbose-http]: Enable verbose HTTP protocol logging *)
36
37open Cmdliner
38
39(** {1 Common Arguments} *)
40
41val server_arg : string Term.t
42(** Required positional argument for server URL (also reads [IMMICH_SERVER]). *)
43
44val server_opt : string option Term.t
45(** Optional [--server] argument (also reads [IMMICH_SERVER]). *)
46
47val api_key_arg : string option Term.t
48(** Optional [--api-key] argument (also reads [IMMICH_API_KEY]). *)
49
50val email_arg : string option Term.t
51(** Optional [--email] argument for password authentication. *)
52
53val password_arg : string option Term.t
54(** Optional [--password] argument. *)
55
56val profile_arg : string option Term.t
57(** Optional [--profile] argument for selecting a specific profile. *)
58
59val key_name_arg : string option Term.t
60(** Optional [--name] argument for naming API keys. *)
61
62(** {1 Logging and Configuration} *)
63
64val setup_logging : (Fmt.style_renderer option * Logs.level option) Term.t
65(** Term that collects logging options ([-v], [--color], etc.).
66 Use with [setup_logging_with_config] to apply logging after parsing. *)
67
68val setup_logging_with_config :
69 Fmt.style_renderer option ->
70 Logs.level option ->
71 Requests.Cmd.config ->
72 unit
73(** [setup_logging_with_config style_renderer level config] sets up logging
74 with the given options. Extracts [--verbose-http] from the requests config.
75 Call this at the start of command execution. *)
76
77val requests_config_term : Eio.Fs.dir_ty Eio.Path.t -> Requests.Cmd.config Term.t
78(** Term for HTTP request configuration (timeouts, retries, proxy, etc.). *)
79
80(** {1 Commands}
81
82 Commands take an [env] parameter from the outer [Eio_main.run] context,
83 and an [fs] path for building cmdliner terms. *)
84
85val auth_cmd :
86 < fs : Eio.Fs.dir_ty Eio.Path.t
87 ; clock : _ Eio.Time.clock
88 ; net : _ Eio.Net.t
89 ; .. > ->
90 Eio.Fs.dir_ty Eio.Path.t ->
91 unit Cmd.t
92(** Complete auth command group combining login, logout, status, and profile. *)
93
94(** {1 Helper Functions} *)
95
96val with_session :
97 ?profile:string ->
98 (Eio.Fs.dir_ty Eio.Path.t -> Session.t -> 'a) ->
99 < fs : Eio.Fs.dir_ty Eio.Path.t ; .. > ->
100 'a
101(** [with_session ?profile f env] loads the session and calls
102 [f fs session]. Prints an error and exits if not logged in.
103 @param profile Profile to load (default: current profile) *)
104
105val with_client :
106 ?requests_config:Requests.Cmd.config ->
107 ?profile:string ->
108 (Eio.Fs.dir_ty Eio.Path.t -> Client.t -> 'a) ->
109 < fs : Eio.Fs.dir_ty Eio.Path.t
110 ; clock : _ Eio.Time.clock
111 ; net : _ Eio.Net.t
112 ; .. > ->
113 'a
114(** [with_client ?requests_config ?profile f env] loads the session, creates a client, and calls
115 [f fs client]. Prints an error and exits if not logged in.
116 @param requests_config HTTP request configuration
117 @param profile Profile to load (default: current profile) *)
118
119(** {1 Profile Configuration for External Programs}
120
121 These types and functions allow other programs to easily use Immich profiles
122 that were set up with the immich CLI. This provides a single cmdliner term
123 that bundles all the necessary configuration.
124
125 {2 Example Usage}
126
127 {[
128 (* In your sortal/bin/main.ml *)
129 open Cmdliner
130
131 let my_cmd env fs =
132 let doc = "My command using Immich" in
133 let info = Cmd.info "my-command" ~doc in
134 let action config =
135 let open Immich_auth.Cmd.Profile_config in
136 setup_logging config;
137 Immich_auth.Cmd.with_client
138 ~requests_config:(requests_config config)
139 ?profile:(profile config)
140 (fun _fs client ->
141 let api = Immich_auth.Client.client client in
142 (* Use the Immich API here *)
143 ()
144 ) env
145 in
146 Cmd.v info Term.(const action $ Immich_auth.Cmd.profile_config_term fs)
147 ]} *)
148
149(** Configuration for using an Immich profile. *)
150module Profile_config : sig
151 type t
152 (** Bundled configuration for Immich profile access. *)
153
154 val style_renderer : t -> Fmt.style_renderer option
155 (** Terminal style renderer setting. *)
156
157 val log_level : t -> Logs.level option
158 (** Logging level. *)
159
160 val requests_config : t -> Requests.Cmd.config
161 (** HTTP request configuration. *)
162
163 val profile : t -> string option
164 (** Selected profile name, if any. *)
165
166 val setup_logging : t -> unit
167 (** [setup_logging config] initializes logging with the bundled settings.
168 Call this at the start of your command execution. *)
169end
170
171val profile_config_term : Eio.Fs.dir_ty Eio.Path.t -> Profile_config.t Term.t
172(** Cmdliner term that collects all configuration needed to use an Immich profile.
173
174 Combines:
175 - Logging options ([-v], [--color], etc.)
176 - HTTP configuration (timeouts, retries, proxy, [--verbose-http])
177 - Profile selection ([--profile])
178
179 Use with {!with_client} to create an authenticated client. *)