Immich bindings and CLI in OCaml
at main 128 lines 4.4 kB view raw
1(*--------------------------------------------------------------------------- 2 Copyright (c) 2025 Anil Madhavapeddy. All rights reserved. 3 SPDX-License-Identifier: ISC 4 ---------------------------------------------------------------------------*) 5 6(** Session management for Immich CLI with profile support. 7 8 This module provides session persistence for Immich authentication, 9 supporting both JWT tokens and API keys. Sessions are stored in 10 profile-specific directories under [~/.config/immich/profiles/<profile>/session.json]. 11 12 {2 Directory Structure} 13 14 {v 15 ~/.config/immich/ 16 config.json # Stores current_profile setting 17 profiles/ 18 default/ 19 session.json # Session for "default" profile 20 home/ 21 session.json # Session for "home" profile 22 work/ 23 session.json # Session for "work" profile 24 v} 25 26 {2 Authentication Methods} 27 28 Immich supports two authentication methods: 29 - {b JWT}: Obtained via email/password login. Tokens expire and need refresh. 30 - {b API Key}: Created in Immich settings. Never expires, simpler for CLI use. 31 32 {[ 33 (* Login with API key *) 34 let session = Session.create 35 ~server_url:"https://immich.example.com" 36 ~auth:(Api_key { key = "xxx"; name = Some "cli" }) 37 () in 38 Session.save fs ~profile:"home" session 39 ]} *) 40 41(** {1 Types} *) 42 43type auth_method = 44 | Jwt of { access_token : string; user_id : string; email : string } 45 | Api_key of { key : string; name : string option } 46(** Authentication method. API keys are preferred for CLI use as they 47 don't expire. *) 48 49type t 50(** Session data. *) 51 52val jsont : t Jsont.t 53(** JSON codec for sessions. *) 54 55(** {1 Session Construction} *) 56 57val create : server_url:string -> auth:auth_method -> unit -> t 58(** [create ~server_url ~auth ()] creates a new session with the current timestamp. *) 59 60(** {1 Session Accessors} *) 61 62val server_url : t -> string 63(** [server_url t] returns the server URL. *) 64 65val auth : t -> auth_method 66(** [auth t] returns the authentication method. *) 67 68val created_at : t -> string 69(** [created_at t] returns the creation timestamp (RFC 3339). *) 70 71(** {1 Profile Management} *) 72 73val default_profile : string 74(** The default profile name (["default"]). *) 75 76val get_current_profile : Eio.Fs.dir_ty Eio.Path.t -> string 77(** [get_current_profile fs] returns the current profile name. Returns 78 {!default_profile} if no profile has been set. *) 79 80val set_current_profile : Eio.Fs.dir_ty Eio.Path.t -> string -> unit 81(** [set_current_profile fs profile] sets the current profile. *) 82 83val list_profiles : Eio.Fs.dir_ty Eio.Path.t -> string list 84(** [list_profiles fs] returns all profiles that have sessions. 85 Returns profile names sorted alphabetically. *) 86 87(** {1 Directory Paths} *) 88 89val base_config_dir : Eio.Fs.dir_ty Eio.Path.t -> Eio.Fs.dir_ty Eio.Path.t 90(** [base_config_dir fs] returns the base config directory 91 ([~/.config/immich]), creating it if needed. *) 92 93val config_dir : 94 Eio.Fs.dir_ty Eio.Path.t -> 95 ?profile:string -> 96 unit -> 97 Eio.Fs.dir_ty Eio.Path.t 98(** [config_dir fs ?profile ()] returns the config directory for a 99 profile, creating it if needed. 100 @param profile Profile name (default: current profile) *) 101 102(** {1 Session Persistence} *) 103 104val save : Eio.Fs.dir_ty Eio.Path.t -> ?profile:string -> t -> unit 105(** [save fs ?profile session] saves the session. 106 @param profile Profile name (default: current profile) *) 107 108val load : Eio.Fs.dir_ty Eio.Path.t -> ?profile:string -> unit -> t option 109(** [load fs ?profile ()] loads a saved session. 110 @param profile Profile name (default: current profile) *) 111 112val clear : Eio.Fs.dir_ty Eio.Path.t -> ?profile:string -> unit -> unit 113(** [clear fs ?profile ()] removes the saved session. 114 @param profile Profile name (default: current profile) *) 115 116(** {1 Session Utilities} *) 117 118val is_jwt_expired : ?leeway:int -> string -> bool 119(** [is_jwt_expired ?leeway token] returns [true] if the JWT token is expired. 120 @param leeway Extra time buffer in seconds (default: 60) *) 121 122val is_expired : ?leeway:int -> t -> bool 123(** [is_expired ?leeway session] returns [true] if the session is expired. 124 API key sessions never expire. 125 @param leeway Extra time buffer in seconds for JWT (default: 60) *) 126 127val pp : t Fmt.t 128(** Pretty-print a session. *)