immichpy 1.6.5__py3-none-any.whl → 1.7.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (435) hide show
  1. immichpy/cli/commands/activities.py +23 -11
  2. immichpy/cli/commands/albums.py +34 -20
  3. immichpy/cli/commands/api_keys.py +6 -4
  4. immichpy/cli/commands/assets.py +274 -65
  5. immichpy/cli/commands/authentication.py +115 -25
  6. immichpy/cli/commands/database_backups_admin.py +111 -0
  7. immichpy/cli/commands/download.py +13 -5
  8. immichpy/cli/commands/duplicates.py +1 -1
  9. immichpy/cli/commands/faces.py +17 -11
  10. immichpy/cli/commands/jobs.py +6 -4
  11. immichpy/cli/commands/libraries.py +15 -9
  12. immichpy/cli/commands/maintenance_admin.py +39 -2
  13. immichpy/cli/commands/map.py +8 -8
  14. immichpy/cli/commands/memories.py +35 -21
  15. immichpy/cli/commands/notifications.py +16 -8
  16. immichpy/cli/commands/notifications_admin.py +43 -17
  17. immichpy/cli/commands/partners.py +9 -3
  18. immichpy/cli/commands/people.py +30 -24
  19. immichpy/cli/commands/plugins.py +14 -0
  20. immichpy/cli/commands/queues.py +8 -6
  21. immichpy/cli/commands/search.py +395 -189
  22. immichpy/cli/commands/server.py +6 -2
  23. immichpy/cli/commands/sessions.py +6 -4
  24. immichpy/cli/commands/shared_links.py +42 -25
  25. immichpy/cli/commands/stacks.py +4 -4
  26. immichpy/cli/commands/sync.py +26 -10
  27. immichpy/cli/commands/system_config.py +216 -115
  28. immichpy/cli/commands/system_metadata.py +3 -1
  29. immichpy/cli/commands/tags.py +9 -9
  30. immichpy/cli/commands/trash.py +1 -1
  31. immichpy/cli/commands/users.py +57 -29
  32. immichpy/cli/commands/users_admin.py +79 -45
  33. immichpy/cli/commands/workflows.py +40 -11
  34. immichpy/cli/main.py +8 -0
  35. immichpy/client/.openapi-generator/FILES +26 -2
  36. immichpy/client/generated/__init__.py +101 -7
  37. immichpy/client/generated/api/__init__.py +3 -0
  38. immichpy/client/generated/api/activities_api.py +73 -43
  39. immichpy/client/generated/api/albums_api.py +40 -19
  40. immichpy/client/generated/api/api_keys_api.py +1 -1
  41. immichpy/client/generated/api/assets_api.py +1768 -366
  42. immichpy/client/generated/api/authentication_admin_api.py +1 -1
  43. immichpy/client/generated/api/authentication_api.py +1 -1
  44. immichpy/client/generated/api/database_backups_admin_api.py +1224 -0
  45. immichpy/client/generated/api/deprecated_api.py +103 -73
  46. immichpy/client/generated/api/download_api.py +1 -1
  47. immichpy/client/generated/api/duplicates_api.py +1 -1
  48. immichpy/client/generated/api/faces_api.py +7 -7
  49. immichpy/client/generated/api/jobs_api.py +7 -7
  50. immichpy/client/generated/api/libraries_api.py +1 -1
  51. immichpy/client/generated/api/maintenance_admin_api.py +459 -1
  52. immichpy/client/generated/api/map_api.py +103 -49
  53. immichpy/client/generated/api/memories_api.py +109 -61
  54. immichpy/client/generated/api/notifications_admin_api.py +1 -1
  55. immichpy/client/generated/api/notifications_api.py +52 -25
  56. immichpy/client/generated/api/partners_api.py +7 -7
  57. immichpy/client/generated/api/people_api.py +37 -19
  58. immichpy/client/generated/api/plugins_api.py +230 -1
  59. immichpy/client/generated/api/queues_api.py +37 -31
  60. immichpy/client/generated/api/search_api.py +529 -283
  61. immichpy/client/generated/api/server_api.py +1 -1
  62. immichpy/client/generated/api/sessions_api.py +1 -1
  63. immichpy/client/generated/api/shared_links_api.py +53 -19
  64. immichpy/client/generated/api/stacks_api.py +13 -7
  65. immichpy/client/generated/api/sync_api.py +1 -1
  66. immichpy/client/generated/api/system_config_api.py +1 -1
  67. immichpy/client/generated/api/system_metadata_api.py +1 -1
  68. immichpy/client/generated/api/tags_api.py +1 -1
  69. immichpy/client/generated/api/timeline_api.py +1 -1
  70. immichpy/client/generated/api/trash_api.py +1 -1
  71. immichpy/client/generated/api/users_admin_api.py +55 -31
  72. immichpy/client/generated/api/users_api.py +16 -7
  73. immichpy/client/generated/api/views_api.py +1 -1
  74. immichpy/client/generated/api/workflows_api.py +1 -1
  75. immichpy/client/generated/api_client.py +1 -1
  76. immichpy/client/generated/configuration.py +2 -2
  77. immichpy/client/generated/exceptions.py +1 -1
  78. immichpy/client/generated/models/__init__.py +56 -3
  79. immichpy/client/generated/models/activity_create_dto.py +11 -5
  80. immichpy/client/generated/models/activity_response_dto.py +10 -6
  81. immichpy/client/generated/models/activity_statistics_response_dto.py +4 -4
  82. immichpy/client/generated/models/add_users_dto.py +2 -2
  83. immichpy/client/generated/models/admin_onboarding_update_dto.py +4 -2
  84. immichpy/client/generated/models/album_response_dto.py +28 -16
  85. immichpy/client/generated/models/album_statistics_response_dto.py +6 -4
  86. immichpy/client/generated/models/album_user_add_dto.py +3 -3
  87. immichpy/client/generated/models/album_user_create_dto.py +3 -3
  88. immichpy/client/generated/models/album_user_response_dto.py +3 -3
  89. immichpy/client/generated/models/album_user_role.py +2 -2
  90. immichpy/client/generated/models/albums_add_assets_dto.py +3 -3
  91. immichpy/client/generated/models/albums_add_assets_response_dto.py +4 -4
  92. immichpy/client/generated/models/albums_response.py +4 -2
  93. immichpy/client/generated/models/albums_update.py +5 -3
  94. immichpy/client/generated/models/api_key_create_dto.py +5 -3
  95. immichpy/client/generated/models/api_key_create_response_dto.py +2 -2
  96. immichpy/client/generated/models/api_key_response_dto.py +6 -6
  97. immichpy/client/generated/models/api_key_update_dto.py +5 -3
  98. immichpy/client/generated/models/asset_bulk_delete_dto.py +6 -4
  99. immichpy/client/generated/models/asset_bulk_update_dto.py +28 -12
  100. immichpy/client/generated/models/asset_bulk_upload_check_dto.py +3 -3
  101. immichpy/client/generated/models/asset_bulk_upload_check_item.py +3 -3
  102. immichpy/client/generated/models/asset_bulk_upload_check_response_dto.py +5 -3
  103. immichpy/client/generated/models/asset_bulk_upload_check_result.py +12 -6
  104. immichpy/client/generated/models/asset_copy_dto.py +16 -8
  105. immichpy/client/generated/models/asset_delta_sync_dto.py +5 -3
  106. immichpy/client/generated/models/asset_delta_sync_response_dto.py +6 -4
  107. immichpy/client/generated/models/asset_edit_action.py +35 -0
  108. immichpy/client/generated/models/asset_edit_action_crop.py +95 -0
  109. immichpy/client/generated/models/asset_edit_action_list_dto.py +104 -0
  110. immichpy/client/generated/models/asset_edit_action_list_dto_edits_inner.py +188 -0
  111. immichpy/client/generated/models/asset_edit_action_mirror.py +95 -0
  112. immichpy/client/generated/models/asset_edit_action_rotate.py +95 -0
  113. immichpy/client/generated/models/asset_edits_dto.py +107 -0
  114. immichpy/client/generated/models/asset_face_create_dto.py +13 -9
  115. immichpy/client/generated/models/asset_face_delete_dto.py +3 -3
  116. immichpy/client/generated/models/asset_face_response_dto.py +26 -10
  117. immichpy/client/generated/models/asset_face_update_dto.py +3 -3
  118. immichpy/client/generated/models/asset_face_update_item.py +3 -3
  119. immichpy/client/generated/models/asset_face_without_person_response_dto.py +23 -9
  120. immichpy/client/generated/models/asset_full_sync_dto.py +13 -5
  121. immichpy/client/generated/models/asset_ids_dto.py +2 -2
  122. immichpy/client/generated/models/asset_ids_response_dto.py +6 -4
  123. immichpy/client/generated/models/asset_job_name.py +2 -2
  124. immichpy/client/generated/models/asset_jobs_dto.py +3 -3
  125. immichpy/client/generated/models/asset_media_response_dto.py +4 -4
  126. immichpy/client/generated/models/asset_media_size.py +2 -1
  127. immichpy/client/generated/models/asset_media_status.py +2 -2
  128. immichpy/client/generated/models/asset_metadata_bulk_delete_dto.py +103 -0
  129. immichpy/client/generated/models/asset_metadata_bulk_delete_item_dto.py +86 -0
  130. immichpy/client/generated/models/asset_metadata_bulk_response_dto.py +93 -0
  131. immichpy/client/generated/models/asset_metadata_bulk_upsert_dto.py +103 -0
  132. immichpy/client/generated/models/asset_metadata_bulk_upsert_item_dto.py +91 -0
  133. immichpy/client/generated/models/asset_metadata_response_dto.py +5 -6
  134. immichpy/client/generated/models/asset_metadata_upsert_dto.py +5 -3
  135. immichpy/client/generated/models/asset_metadata_upsert_item_dto.py +4 -5
  136. immichpy/client/generated/models/asset_ocr_response_dto.py +1 -1
  137. immichpy/client/generated/models/asset_order.py +2 -2
  138. immichpy/client/generated/models/asset_response_dto.py +66 -24
  139. immichpy/client/generated/models/asset_stack_response_dto.py +8 -4
  140. immichpy/client/generated/models/asset_stats_response_dto.py +5 -5
  141. immichpy/client/generated/models/asset_type_enum.py +2 -2
  142. immichpy/client/generated/models/asset_visibility.py +2 -2
  143. immichpy/client/generated/models/audio_codec.py +2 -2
  144. immichpy/client/generated/models/auth_status_response_dto.py +12 -6
  145. immichpy/client/generated/models/avatar_update.py +3 -3
  146. immichpy/client/generated/models/bulk_id_error_reason.py +2 -2
  147. immichpy/client/generated/models/bulk_id_response_dto.py +14 -5
  148. immichpy/client/generated/models/bulk_ids_dto.py +3 -3
  149. immichpy/client/generated/models/cast_response.py +4 -2
  150. immichpy/client/generated/models/cast_update.py +4 -2
  151. immichpy/client/generated/models/change_password_dto.py +6 -4
  152. immichpy/client/generated/models/check_existing_assets_dto.py +3 -3
  153. immichpy/client/generated/models/check_existing_assets_response_dto.py +4 -2
  154. immichpy/client/generated/models/clip_config.py +5 -3
  155. immichpy/client/generated/models/colorspace.py +1 -1
  156. immichpy/client/generated/models/contributor_count_response_dto.py +5 -3
  157. immichpy/client/generated/models/cq_mode.py +2 -2
  158. immichpy/client/generated/models/create_album_dto.py +9 -5
  159. immichpy/client/generated/models/create_library_dto.py +9 -5
  160. immichpy/client/generated/models/create_profile_image_response_dto.py +8 -4
  161. immichpy/client/generated/models/crop_parameters.py +105 -0
  162. immichpy/client/generated/models/database_backup_config.py +6 -4
  163. immichpy/client/generated/models/database_backup_delete_dto.py +82 -0
  164. immichpy/client/generated/models/database_backup_dto.py +85 -0
  165. immichpy/client/generated/models/database_backup_list_response_dto.py +98 -0
  166. immichpy/client/generated/models/download_archive_info.py +5 -3
  167. immichpy/client/generated/models/download_info_dto.py +11 -5
  168. immichpy/client/generated/models/download_response.py +8 -3
  169. immichpy/client/generated/models/download_response_dto.py +3 -3
  170. immichpy/client/generated/models/download_update.py +5 -3
  171. immichpy/client/generated/models/duplicate_detection_config.py +6 -3
  172. immichpy/client/generated/models/duplicate_response_dto.py +5 -3
  173. immichpy/client/generated/models/email_notifications_response.py +10 -4
  174. immichpy/client/generated/models/email_notifications_update.py +14 -4
  175. immichpy/client/generated/models/exif_response_dto.py +47 -23
  176. immichpy/client/generated/models/face_dto.py +3 -3
  177. immichpy/client/generated/models/facial_recognition_config.py +15 -6
  178. immichpy/client/generated/models/folders_response.py +5 -3
  179. immichpy/client/generated/models/folders_update.py +9 -3
  180. immichpy/client/generated/models/image_format.py +2 -2
  181. immichpy/client/generated/models/job_create_dto.py +3 -3
  182. immichpy/client/generated/models/job_name.py +3 -2
  183. immichpy/client/generated/models/job_settings_dto.py +4 -2
  184. immichpy/client/generated/models/library_response_dto.py +16 -10
  185. immichpy/client/generated/models/library_stats_response_dto.py +6 -6
  186. immichpy/client/generated/models/license_key_dto.py +7 -3
  187. immichpy/client/generated/models/license_response_dto.py +8 -4
  188. immichpy/client/generated/models/log_level.py +1 -1
  189. immichpy/client/generated/models/login_credential_dto.py +4 -4
  190. immichpy/client/generated/models/login_response_dto.py +13 -9
  191. immichpy/client/generated/models/logout_response_dto.py +3 -3
  192. immichpy/client/generated/models/machine_learning_availability_checks_dto.py +3 -3
  193. immichpy/client/generated/models/maintenance_action.py +4 -2
  194. immichpy/client/generated/models/maintenance_auth_dto.py +3 -3
  195. immichpy/client/generated/models/maintenance_detect_install_response_dto.py +101 -0
  196. immichpy/client/generated/models/maintenance_detect_install_storage_folder_dto.py +95 -0
  197. immichpy/client/generated/models/maintenance_login_dto.py +3 -3
  198. immichpy/client/generated/models/maintenance_status_response_dto.py +109 -0
  199. immichpy/client/generated/models/manual_job_name.py +2 -2
  200. immichpy/client/generated/models/map_marker_response_dto.py +8 -8
  201. immichpy/client/generated/models/map_reverse_geocode_response_dto.py +5 -5
  202. immichpy/client/generated/models/memories_response.py +4 -4
  203. immichpy/client/generated/models/memories_update.py +7 -3
  204. immichpy/client/generated/models/memory_create_dto.py +12 -6
  205. immichpy/client/generated/models/memory_response_dto.py +20 -12
  206. immichpy/client/generated/models/memory_search_order.py +1 -1
  207. immichpy/client/generated/models/memory_statistics_response_dto.py +3 -3
  208. immichpy/client/generated/models/memory_type.py +1 -1
  209. immichpy/client/generated/models/memory_update_dto.py +10 -4
  210. immichpy/client/generated/models/merge_person_dto.py +3 -3
  211. immichpy/client/generated/models/metadata_search_dto.py +124 -46
  212. immichpy/client/generated/models/{asset_metadata_key.py → mirror_axis.py} +6 -5
  213. immichpy/client/generated/models/mirror_parameters.py +83 -0
  214. immichpy/client/generated/models/notification_create_dto.py +18 -8
  215. immichpy/client/generated/models/notification_delete_all_dto.py +3 -3
  216. immichpy/client/generated/models/notification_dto.py +15 -9
  217. immichpy/client/generated/models/notification_level.py +1 -1
  218. immichpy/client/generated/models/notification_type.py +1 -1
  219. immichpy/client/generated/models/notification_update_all_dto.py +5 -3
  220. immichpy/client/generated/models/notification_update_dto.py +4 -2
  221. immichpy/client/generated/models/o_auth_authorize_response_dto.py +3 -3
  222. immichpy/client/generated/models/o_auth_callback_dto.py +8 -4
  223. immichpy/client/generated/models/o_auth_config_dto.py +10 -4
  224. immichpy/client/generated/models/o_auth_token_endpoint_auth_method.py +2 -2
  225. immichpy/client/generated/models/ocr_config.py +14 -6
  226. immichpy/client/generated/models/on_this_day_dto.py +2 -2
  227. immichpy/client/generated/models/onboarding_dto.py +4 -2
  228. immichpy/client/generated/models/onboarding_response_dto.py +4 -2
  229. immichpy/client/generated/models/partner_create_dto.py +4 -2
  230. immichpy/client/generated/models/partner_direction.py +1 -1
  231. immichpy/client/generated/models/partner_response_dto.py +16 -8
  232. immichpy/client/generated/models/partner_update_dto.py +4 -2
  233. immichpy/client/generated/models/people_response.py +5 -3
  234. immichpy/client/generated/models/people_response_dto.py +7 -5
  235. immichpy/client/generated/models/people_update.py +9 -3
  236. immichpy/client/generated/models/people_update_dto.py +3 -3
  237. immichpy/client/generated/models/people_update_item.py +10 -10
  238. immichpy/client/generated/models/permission.py +13 -2
  239. immichpy/client/generated/models/person_create_dto.py +8 -8
  240. immichpy/client/generated/models/person_response_dto.py +17 -9
  241. immichpy/client/generated/models/person_statistics_response_dto.py +3 -3
  242. immichpy/client/generated/models/person_update_dto.py +9 -9
  243. immichpy/client/generated/models/person_with_faces_response_dto.py +20 -10
  244. immichpy/client/generated/models/pin_code_change_dto.py +10 -4
  245. immichpy/client/generated/models/pin_code_reset_dto.py +7 -3
  246. immichpy/client/generated/models/pin_code_setup_dto.py +2 -2
  247. immichpy/client/generated/models/places_response_dto.py +11 -7
  248. immichpy/client/generated/models/plugin_action_response_dto.py +13 -9
  249. immichpy/client/generated/models/{plugin_context.py → plugin_context_type.py} +4 -4
  250. immichpy/client/generated/models/plugin_filter_response_dto.py +13 -9
  251. immichpy/client/generated/models/plugin_response_dto.py +11 -11
  252. immichpy/client/generated/models/plugin_trigger_response_dto.py +89 -0
  253. immichpy/client/generated/models/plugin_trigger_type.py +2 -2
  254. immichpy/client/generated/models/purchase_response.py +7 -3
  255. immichpy/client/generated/models/purchase_update.py +7 -3
  256. immichpy/client/generated/models/queue_command.py +2 -2
  257. immichpy/client/generated/models/queue_command_dto.py +6 -4
  258. immichpy/client/generated/models/queue_delete_dto.py +1 -1
  259. immichpy/client/generated/models/queue_job_response_dto.py +6 -6
  260. immichpy/client/generated/models/queue_job_status.py +1 -1
  261. immichpy/client/generated/models/queue_name.py +2 -1
  262. immichpy/client/generated/models/queue_response_dto.py +5 -3
  263. immichpy/client/generated/models/queue_response_legacy_dto.py +1 -1
  264. immichpy/client/generated/models/queue_statistics_dto.py +8 -8
  265. immichpy/client/generated/models/queue_status_legacy_dto.py +8 -3
  266. immichpy/client/generated/models/queue_update_dto.py +4 -2
  267. immichpy/client/generated/models/queues_response_legacy_dto.py +9 -1
  268. immichpy/client/generated/models/random_search_dto.py +96 -34
  269. immichpy/client/generated/models/ratings_response.py +3 -3
  270. immichpy/client/generated/models/ratings_update.py +5 -3
  271. immichpy/client/generated/models/reaction_level.py +1 -1
  272. immichpy/client/generated/models/reaction_type.py +1 -1
  273. immichpy/client/generated/models/reverse_geocoding_state_response_dto.py +7 -3
  274. immichpy/client/generated/models/rotate_parameters.py +84 -0
  275. immichpy/client/generated/models/search_album_response_dto.py +4 -4
  276. immichpy/client/generated/models/search_asset_response_dto.py +6 -4
  277. immichpy/client/generated/models/search_explore_item.py +3 -3
  278. immichpy/client/generated/models/search_explore_response_dto.py +2 -2
  279. immichpy/client/generated/models/search_facet_count_response_dto.py +4 -4
  280. immichpy/client/generated/models/search_facet_response_dto.py +3 -3
  281. immichpy/client/generated/models/search_response_dto.py +1 -1
  282. immichpy/client/generated/models/search_statistics_response_dto.py +3 -3
  283. immichpy/client/generated/models/search_suggestion_type.py +1 -1
  284. immichpy/client/generated/models/server_about_response_dto.py +46 -22
  285. immichpy/client/generated/models/server_apk_links_dto.py +12 -6
  286. immichpy/client/generated/models/server_config_dto.py +36 -12
  287. immichpy/client/generated/models/server_features_dto.py +32 -16
  288. immichpy/client/generated/models/server_media_types_response_dto.py +5 -5
  289. immichpy/client/generated/models/server_ping_response.py +1 -1
  290. immichpy/client/generated/models/server_stats_response_dto.py +10 -6
  291. immichpy/client/generated/models/server_storage_response_dto.py +21 -8
  292. immichpy/client/generated/models/server_theme_dto.py +4 -2
  293. immichpy/client/generated/models/server_version_history_response_dto.py +6 -4
  294. immichpy/client/generated/models/server_version_response_dto.py +5 -5
  295. immichpy/client/generated/models/session_create_dto.py +8 -4
  296. immichpy/client/generated/models/session_create_response_dto.py +17 -11
  297. immichpy/client/generated/models/session_response_dto.py +16 -10
  298. immichpy/client/generated/models/session_unlock_dto.py +7 -3
  299. immichpy/client/generated/models/session_update_dto.py +2 -2
  300. immichpy/client/generated/models/set_maintenance_mode_dto.py +17 -7
  301. immichpy/client/generated/models/shared_link_create_dto.py +25 -11
  302. immichpy/client/generated/models/shared_link_edit_dto.py +19 -9
  303. immichpy/client/generated/models/shared_link_response_dto.py +18 -14
  304. immichpy/client/generated/models/shared_link_type.py +2 -2
  305. immichpy/client/generated/models/shared_links_response.py +5 -3
  306. immichpy/client/generated/models/shared_links_update.py +9 -3
  307. immichpy/client/generated/models/sign_up_dto.py +5 -5
  308. immichpy/client/generated/models/smart_search_dto.py +102 -36
  309. immichpy/client/generated/models/source_type.py +2 -2
  310. immichpy/client/generated/models/stack_create_dto.py +2 -2
  311. immichpy/client/generated/models/stack_response_dto.py +6 -4
  312. immichpy/client/generated/models/stack_update_dto.py +4 -2
  313. immichpy/client/generated/models/statistics_search_dto.py +86 -30
  314. immichpy/client/generated/models/storage_folder.py +38 -0
  315. immichpy/client/generated/models/sync_ack_delete_dto.py +5 -3
  316. immichpy/client/generated/models/sync_ack_dto.py +4 -4
  317. immichpy/client/generated/models/sync_ack_set_dto.py +4 -2
  318. immichpy/client/generated/models/sync_album_delete_v1.py +2 -2
  319. immichpy/client/generated/models/sync_album_to_asset_delete_v1.py +3 -3
  320. immichpy/client/generated/models/sync_album_to_asset_v1.py +3 -3
  321. immichpy/client/generated/models/sync_album_user_delete_v1.py +3 -3
  322. immichpy/client/generated/models/sync_album_user_v1.py +4 -4
  323. immichpy/client/generated/models/sync_album_v1.py +13 -9
  324. immichpy/client/generated/models/sync_asset_delete_v1.py +2 -2
  325. immichpy/client/generated/models/sync_asset_exif_v1.py +46 -26
  326. immichpy/client/generated/models/sync_asset_face_delete_v1.py +2 -2
  327. immichpy/client/generated/models/sync_asset_face_v1.py +5 -5
  328. immichpy/client/generated/models/sync_asset_metadata_delete_v1.py +3 -4
  329. immichpy/client/generated/models/sync_asset_metadata_v1.py +4 -5
  330. immichpy/client/generated/models/sync_asset_v1.py +47 -18
  331. immichpy/client/generated/models/sync_auth_user_v1.py +22 -12
  332. immichpy/client/generated/models/sync_entity_type.py +2 -2
  333. immichpy/client/generated/models/sync_memory_asset_delete_v1.py +3 -3
  334. immichpy/client/generated/models/sync_memory_asset_v1.py +3 -3
  335. immichpy/client/generated/models/sync_memory_delete_v1.py +2 -2
  336. immichpy/client/generated/models/sync_memory_v1.py +13 -13
  337. immichpy/client/generated/models/sync_partner_delete_v1.py +5 -3
  338. immichpy/client/generated/models/sync_partner_v1.py +6 -4
  339. immichpy/client/generated/models/sync_person_delete_v1.py +2 -2
  340. immichpy/client/generated/models/sync_person_v1.py +13 -11
  341. immichpy/client/generated/models/sync_request_type.py +2 -2
  342. immichpy/client/generated/models/sync_stack_delete_v1.py +2 -2
  343. immichpy/client/generated/models/sync_stack_v1.py +8 -6
  344. immichpy/client/generated/models/sync_stream_dto.py +4 -4
  345. immichpy/client/generated/models/sync_user_delete_v1.py +2 -2
  346. immichpy/client/generated/models/sync_user_metadata_delete_v1.py +3 -3
  347. immichpy/client/generated/models/sync_user_metadata_v1.py +4 -4
  348. immichpy/client/generated/models/sync_user_v1.py +16 -8
  349. immichpy/client/generated/models/system_config_backups_dto.py +1 -1
  350. immichpy/client/generated/models/system_config_dto.py +1 -1
  351. immichpy/client/generated/models/system_config_f_fmpeg_dto.py +44 -22
  352. immichpy/client/generated/models/system_config_faces_dto.py +2 -2
  353. immichpy/client/generated/models/system_config_generated_fullsize_image_dto.py +13 -7
  354. immichpy/client/generated/models/system_config_generated_image_dto.py +14 -8
  355. immichpy/client/generated/models/system_config_image_dto.py +5 -3
  356. immichpy/client/generated/models/system_config_job_dto.py +9 -1
  357. immichpy/client/generated/models/system_config_library_dto.py +1 -1
  358. immichpy/client/generated/models/system_config_library_scan_dto.py +2 -2
  359. immichpy/client/generated/models/system_config_library_watch_dto.py +3 -3
  360. immichpy/client/generated/models/system_config_logging_dto.py +3 -3
  361. immichpy/client/generated/models/system_config_machine_learning_dto.py +2 -2
  362. immichpy/client/generated/models/system_config_map_dto.py +2 -2
  363. immichpy/client/generated/models/system_config_metadata_dto.py +1 -1
  364. immichpy/client/generated/models/system_config_new_version_check_dto.py +3 -3
  365. immichpy/client/generated/models/system_config_nightly_tasks_dto.py +16 -6
  366. immichpy/client/generated/models/system_config_notifications_dto.py +1 -1
  367. immichpy/client/generated/models/system_config_o_auth_dto.py +28 -18
  368. immichpy/client/generated/models/system_config_password_login_dto.py +3 -3
  369. immichpy/client/generated/models/system_config_reverse_geocoding_dto.py +3 -3
  370. immichpy/client/generated/models/system_config_server_dto.py +8 -4
  371. immichpy/client/generated/models/system_config_smtp_dto.py +8 -4
  372. immichpy/client/generated/models/system_config_smtp_transport_dto.py +9 -7
  373. immichpy/client/generated/models/system_config_storage_template_dto.py +6 -4
  374. immichpy/client/generated/models/system_config_template_emails_dto.py +1 -1
  375. immichpy/client/generated/models/system_config_template_storage_option_dto.py +32 -9
  376. immichpy/client/generated/models/system_config_templates_dto.py +1 -1
  377. immichpy/client/generated/models/system_config_theme_dto.py +4 -2
  378. immichpy/client/generated/models/system_config_trash_dto.py +3 -3
  379. immichpy/client/generated/models/system_config_user_dto.py +4 -2
  380. immichpy/client/generated/models/tag_bulk_assets_dto.py +3 -3
  381. immichpy/client/generated/models/tag_bulk_assets_response_dto.py +3 -3
  382. immichpy/client/generated/models/tag_create_dto.py +8 -4
  383. immichpy/client/generated/models/tag_response_dto.py +10 -8
  384. immichpy/client/generated/models/tag_update_dto.py +3 -3
  385. immichpy/client/generated/models/tag_upsert_dto.py +3 -3
  386. immichpy/client/generated/models/tags_response.py +5 -3
  387. immichpy/client/generated/models/tags_update.py +9 -3
  388. immichpy/client/generated/models/template_dto.py +3 -3
  389. immichpy/client/generated/models/template_response_dto.py +4 -4
  390. immichpy/client/generated/models/test_email_response_dto.py +2 -2
  391. immichpy/client/generated/models/time_bucket_asset_response_dto.py +2 -3
  392. immichpy/client/generated/models/time_buckets_response_dto.py +1 -1
  393. immichpy/client/generated/models/tone_mapping.py +2 -2
  394. immichpy/client/generated/models/transcode_hw_accel.py +2 -2
  395. immichpy/client/generated/models/transcode_policy.py +2 -2
  396. immichpy/client/generated/models/trash_response_dto.py +3 -3
  397. immichpy/client/generated/models/update_album_dto.py +12 -6
  398. immichpy/client/generated/models/update_album_user_dto.py +3 -3
  399. immichpy/client/generated/models/update_asset_dto.py +21 -9
  400. immichpy/client/generated/models/update_library_dto.py +8 -4
  401. immichpy/client/generated/models/usage_by_user_dto.py +16 -9
  402. immichpy/client/generated/models/user_admin_create_dto.py +20 -10
  403. immichpy/client/generated/models/user_admin_delete_dto.py +5 -3
  404. immichpy/client/generated/models/user_admin_response_dto.py +35 -18
  405. immichpy/client/generated/models/user_admin_update_dto.py +20 -10
  406. immichpy/client/generated/models/user_avatar_color.py +2 -2
  407. immichpy/client/generated/models/user_license.py +6 -4
  408. immichpy/client/generated/models/user_metadata_key.py +2 -2
  409. immichpy/client/generated/models/user_preferences_response_dto.py +1 -1
  410. immichpy/client/generated/models/user_preferences_update_dto.py +1 -1
  411. immichpy/client/generated/models/user_response_dto.py +13 -7
  412. immichpy/client/generated/models/user_status.py +2 -2
  413. immichpy/client/generated/models/user_update_me_dto.py +10 -5
  414. immichpy/client/generated/models/validate_access_token_response_dto.py +4 -2
  415. immichpy/client/generated/models/validate_library_dto.py +9 -3
  416. immichpy/client/generated/models/validate_library_import_path_response_dto.py +4 -4
  417. immichpy/client/generated/models/validate_library_response_dto.py +4 -2
  418. immichpy/client/generated/models/version_check_state_response_dto.py +7 -3
  419. immichpy/client/generated/models/video_codec.py +2 -2
  420. immichpy/client/generated/models/video_container.py +2 -2
  421. immichpy/client/generated/models/workflow_action_item_dto.py +7 -3
  422. immichpy/client/generated/models/workflow_action_response_dto.py +10 -6
  423. immichpy/client/generated/models/workflow_create_dto.py +11 -7
  424. immichpy/client/generated/models/workflow_filter_item_dto.py +7 -3
  425. immichpy/client/generated/models/workflow_filter_response_dto.py +10 -6
  426. immichpy/client/generated/models/workflow_response_dto.py +14 -27
  427. immichpy/client/generated/models/workflow_update_dto.py +19 -7
  428. immichpy/client/generated/rest.py +1 -1
  429. immichpy/client/main.py +4 -1
  430. {immichpy-1.6.5.dist-info → immichpy-1.7.5.dist-info}/METADATA +1 -3
  431. immichpy-1.7.5.dist-info/RECORD +464 -0
  432. immichpy-1.6.5.dist-info/RECORD +0 -439
  433. {immichpy-1.6.5.dist-info → immichpy-1.7.5.dist-info}/WHEEL +0 -0
  434. {immichpy-1.6.5.dist-info → immichpy-1.7.5.dist-info}/entry_points.txt +0 -0
  435. {immichpy-1.6.5.dist-info → immichpy-1.7.5.dist-info}/licenses/LICENSE +0 -0
@@ -22,7 +22,13 @@ app = typer.Typer(
22
22
  @app.command("check-bulk-upload", deprecated=False, rich_help_panel="API commands")
23
23
  def check_bulk_upload(
24
24
  ctx: typer.Context,
25
- assets: list[str] = typer.Option(..., "--assets", help="""As a JSON string"""),
25
+ assets: list[str] = typer.Option(
26
+ ...,
27
+ "--assets",
28
+ help="""Assets to check
29
+
30
+ As a JSON string""",
31
+ ),
26
32
  ) -> None:
27
33
  """Check bulk upload
28
34
 
@@ -42,8 +48,10 @@ def check_bulk_upload(
42
48
  @app.command("check-existing-assets", deprecated=False, rich_help_panel="API commands")
43
49
  def check_existing_assets(
44
50
  ctx: typer.Context,
45
- device_asset_ids: list[str] = typer.Option(..., "--device-asset-ids", help=""""""),
46
- device_id: str = typer.Option(..., "--device-id", help=""""""),
51
+ device_asset_ids: list[str] = typer.Option(
52
+ ..., "--device-asset-ids", help="""Device asset IDs to check"""
53
+ ),
54
+ device_id: str = typer.Option(..., "--device-id", help="""Device ID"""),
47
55
  ) -> None:
48
56
  """Check existing assets
49
57
 
@@ -64,20 +72,22 @@ def check_existing_assets(
64
72
  def copy_asset(
65
73
  ctx: typer.Context,
66
74
  albums: Literal["true", "false"] | None = typer.Option(
67
- None, "--albums", help=""""""
75
+ None, "--albums", help="""Copy album associations"""
68
76
  ),
69
77
  favorite: Literal["true", "false"] | None = typer.Option(
70
- None, "--favorite", help=""""""
78
+ None, "--favorite", help="""Copy favorite status"""
71
79
  ),
72
80
  shared_links: Literal["true", "false"] | None = typer.Option(
73
- None, "--shared-links", help=""""""
81
+ None, "--shared-links", help="""Copy shared links"""
74
82
  ),
75
83
  sidecar: Literal["true", "false"] | None = typer.Option(
76
- None, "--sidecar", help=""""""
84
+ None, "--sidecar", help="""Copy sidecar file"""
85
+ ),
86
+ source_id: str = typer.Option(..., "--source-id", help="""Source asset ID"""),
87
+ stack: Literal["true", "false"] | None = typer.Option(
88
+ None, "--stack", help="""Copy stack association"""
77
89
  ),
78
- source_id: str = typer.Option(..., "--source-id", help=""""""),
79
- stack: Literal["true", "false"] | None = typer.Option(None, "--stack", help=""""""),
80
- target_id: str = typer.Option(..., "--target-id", help=""""""),
90
+ target_id: str = typer.Option(..., "--target-id", help="""Target asset ID"""),
81
91
  ) -> None:
82
92
  """Copy asset
83
93
 
@@ -107,8 +117,8 @@ def copy_asset(
107
117
  @app.command("delete-asset-metadata", deprecated=False, rich_help_panel="API commands")
108
118
  def delete_asset_metadata(
109
119
  ctx: typer.Context,
110
- id: str = typer.Argument(..., help=""""""),
111
- key: AssetMetadataKey = typer.Argument(..., help=""""""),
120
+ id: str = typer.Argument(..., help="""Asset ID"""),
121
+ key: str = typer.Argument(..., help="""Metadata key"""),
112
122
  ) -> None:
113
123
  """Delete asset metadata by key
114
124
 
@@ -125,8 +135,10 @@ def delete_asset_metadata(
125
135
  @app.command("delete-assets", deprecated=False, rich_help_panel="API commands")
126
136
  def delete_assets(
127
137
  ctx: typer.Context,
128
- force: Literal["true", "false"] | None = typer.Option(None, "--force", help=""""""),
129
- ids: list[str] = typer.Option(..., "--ids", help=""""""),
138
+ force: Literal["true", "false"] | None = typer.Option(
139
+ None, "--force", help="""Force delete even if in use"""
140
+ ),
141
+ ids: list[str] = typer.Option(..., "--ids", help="""IDs to process"""),
130
142
  ) -> None:
131
143
  """Delete assets
132
144
 
@@ -144,10 +156,45 @@ def delete_assets(
144
156
  print_response(result, ctx)
145
157
 
146
158
 
159
+ @app.command(
160
+ "delete-bulk-asset-metadata", deprecated=False, rich_help_panel="API commands"
161
+ )
162
+ def delete_bulk_asset_metadata(
163
+ ctx: typer.Context,
164
+ items: list[str] = typer.Option(
165
+ ...,
166
+ "--items",
167
+ help="""Metadata items to delete
168
+
169
+ As a JSON string""",
170
+ ),
171
+ ) -> None:
172
+ """Delete asset metadata
173
+
174
+ [link=https://api.immich.app/endpoints/assets/deleteBulkAssetMetadata]Immich API documentation[/link]
175
+ """
176
+ kwargs = {}
177
+ json_data = {}
178
+ value_items = [json.loads(i) for i in items]
179
+ set_nested(json_data, ["items"], value_items)
180
+ asset_metadata_bulk_delete_dto = AssetMetadataBulkDeleteDto.model_validate(
181
+ json_data
182
+ )
183
+ kwargs["asset_metadata_bulk_delete_dto"] = asset_metadata_bulk_delete_dto
184
+ client: "AsyncClient" = ctx.obj["client"]
185
+ result = run_command(
186
+ client, client.assets, "delete_bulk_asset_metadata", ctx, **kwargs
187
+ )
188
+ print_response(result, ctx)
189
+
190
+
147
191
  @app.command("download-asset", deprecated=False, rich_help_panel="API commands")
148
192
  def download_asset(
149
193
  ctx: typer.Context,
150
194
  id: str = typer.Argument(..., help=""""""),
195
+ edited: Literal["true", "false"] | None = typer.Option(
196
+ None, "--edited", help="""Return edited asset if available"""
197
+ ),
151
198
  key: str | None = typer.Option(None, "--key", help=""""""),
152
199
  slug: str | None = typer.Option(None, "--slug", help=""""""),
153
200
  ) -> None:
@@ -156,6 +203,8 @@ def download_asset(
156
203
  [link=https://api.immich.app/endpoints/assets/downloadAsset]Immich API documentation[/link]
157
204
  """
158
205
  kwargs = {}
206
+ if edited is not None:
207
+ kwargs["edited"] = edited.lower() == "true"
159
208
  kwargs["id"] = id
160
209
  if key is not None:
161
210
  kwargs["key"] = key
@@ -166,12 +215,40 @@ def download_asset(
166
215
  print_response(result, ctx)
167
216
 
168
217
 
218
+ @app.command("edit-asset", deprecated=False, rich_help_panel="API commands")
219
+ def edit_asset(
220
+ ctx: typer.Context,
221
+ id: str = typer.Argument(..., help=""""""),
222
+ edits: list[str] = typer.Option(
223
+ ...,
224
+ "--edits",
225
+ help="""List of edit actions to apply (crop, rotate, or mirror)
226
+
227
+ As a JSON string""",
228
+ ),
229
+ ) -> None:
230
+ """Apply edits to an existing asset
231
+
232
+ [link=https://api.immich.app/endpoints/assets/editAsset]Immich API documentation[/link]
233
+ """
234
+ kwargs = {}
235
+ json_data = {}
236
+ kwargs["id"] = id
237
+ value_edits = [json.loads(i) for i in edits]
238
+ set_nested(json_data, ["edits"], value_edits)
239
+ asset_edit_action_list_dto = AssetEditActionListDto.model_validate(json_data)
240
+ kwargs["asset_edit_action_list_dto"] = asset_edit_action_list_dto
241
+ client: "AsyncClient" = ctx.obj["client"]
242
+ result = run_command(client, client.assets, "edit_asset", ctx, **kwargs)
243
+ print_response(result, ctx)
244
+
245
+
169
246
  @app.command(
170
247
  "get-all-user-assets-by-device-id", deprecated=True, rich_help_panel="API commands"
171
248
  )
172
249
  def get_all_user_assets_by_device_id(
173
250
  ctx: typer.Context,
174
- device_id: str = typer.Argument(..., help=""""""),
251
+ device_id: str = typer.Argument(..., help="""Device ID"""),
175
252
  ) -> None:
176
253
  """Retrieve assets by device ID
177
254
 
@@ -186,6 +263,22 @@ def get_all_user_assets_by_device_id(
186
263
  print_response(result, ctx)
187
264
 
188
265
 
266
+ @app.command("get-asset-edits", deprecated=False, rich_help_panel="API commands")
267
+ def get_asset_edits(
268
+ ctx: typer.Context,
269
+ id: str = typer.Argument(..., help=""""""),
270
+ ) -> None:
271
+ """Retrieve edits for an existing asset
272
+
273
+ [link=https://api.immich.app/endpoints/assets/getAssetEdits]Immich API documentation[/link]
274
+ """
275
+ kwargs = {}
276
+ kwargs["id"] = id
277
+ client: "AsyncClient" = ctx.obj["client"]
278
+ result = run_command(client, client.assets, "get_asset_edits", ctx, **kwargs)
279
+ print_response(result, ctx)
280
+
281
+
189
282
  @app.command("get-asset-info", deprecated=False, rich_help_panel="API commands")
190
283
  def get_asset_info(
191
284
  ctx: typer.Context,
@@ -229,8 +322,8 @@ def get_asset_metadata(
229
322
  )
230
323
  def get_asset_metadata_by_key(
231
324
  ctx: typer.Context,
232
- id: str = typer.Argument(..., help=""""""),
233
- key: AssetMetadataKey = typer.Argument(..., help=""""""),
325
+ id: str = typer.Argument(..., help="""Asset ID"""),
326
+ key: str = typer.Argument(..., help="""Metadata key"""),
234
327
  ) -> None:
235
328
  """Retrieve asset metadata by key
236
329
 
@@ -266,13 +359,13 @@ def get_asset_ocr(
266
359
  def get_asset_statistics(
267
360
  ctx: typer.Context,
268
361
  is_favorite: Literal["true", "false"] | None = typer.Option(
269
- None, "--is-favorite", help=""""""
362
+ None, "--is-favorite", help="""Filter by favorite status"""
270
363
  ),
271
364
  is_trashed: Literal["true", "false"] | None = typer.Option(
272
- None, "--is-trashed", help=""""""
365
+ None, "--is-trashed", help="""Filter by trash status"""
273
366
  ),
274
367
  visibility: AssetVisibility | None = typer.Option(
275
- None, "--visibility", help=""""""
368
+ None, "--visibility", help="""Filter by visibility"""
276
369
  ),
277
370
  ) -> None:
278
371
  """Get asset statistics
@@ -294,7 +387,9 @@ def get_asset_statistics(
294
387
  @app.command("get-random", deprecated=True, rich_help_panel="API commands")
295
388
  def get_random(
296
389
  ctx: typer.Context,
297
- count: float | None = typer.Option(None, "--count", help="""""", min=1),
390
+ count: float | None = typer.Option(
391
+ None, "--count", help="""Number of random assets to return""", min=1
392
+ ),
298
393
  ) -> None:
299
394
  """Get random assets
300
395
 
@@ -330,17 +425,43 @@ def play_asset_video(
330
425
  print_response(result, ctx)
331
426
 
332
427
 
428
+ @app.command("remove-asset-edits", deprecated=False, rich_help_panel="API commands")
429
+ def remove_asset_edits(
430
+ ctx: typer.Context,
431
+ id: str = typer.Argument(..., help=""""""),
432
+ ) -> None:
433
+ """Remove edits from an existing asset
434
+
435
+ [link=https://api.immich.app/endpoints/assets/removeAssetEdits]Immich API documentation[/link]
436
+ """
437
+ kwargs = {}
438
+ kwargs["id"] = id
439
+ client: "AsyncClient" = ctx.obj["client"]
440
+ result = run_command(client, client.assets, "remove_asset_edits", ctx, **kwargs)
441
+ print_response(result, ctx)
442
+
443
+
333
444
  @app.command("replace-asset", deprecated=True, rich_help_panel="API commands")
334
445
  def replace_asset(
335
446
  ctx: typer.Context,
336
447
  id: str = typer.Argument(..., help=""""""),
337
- asset_data: Path = typer.Option(..., "--asset-data", help="""""", exists=True),
338
- device_asset_id: str = typer.Option(..., "--device-asset-id", help=""""""),
339
- device_id: str = typer.Option(..., "--device-id", help=""""""),
340
- duration: str | None = typer.Option(None, "--duration", help=""""""),
341
- file_created_at: datetime = typer.Option(..., "--file-created-at", help=""""""),
342
- file_modified_at: datetime = typer.Option(..., "--file-modified-at", help=""""""),
343
- filename: str | None = typer.Option(None, "--filename", help=""""""),
448
+ asset_data: Path = typer.Option(
449
+ ..., "--asset-data", help="""Asset file data""", exists=True
450
+ ),
451
+ device_asset_id: str = typer.Option(
452
+ ..., "--device-asset-id", help="""Device asset ID"""
453
+ ),
454
+ device_id: str = typer.Option(..., "--device-id", help="""Device ID"""),
455
+ duration: str | None = typer.Option(
456
+ None, "--duration", help="""Duration (for videos)"""
457
+ ),
458
+ file_created_at: datetime = typer.Option(
459
+ ..., "--file-created-at", help="""File creation date"""
460
+ ),
461
+ file_modified_at: datetime = typer.Option(
462
+ ..., "--file-modified-at", help="""File modification date"""
463
+ ),
464
+ filename: str | None = typer.Option(None, "--filename", help="""Filename"""),
344
465
  key: str | None = typer.Option(None, "--key", help=""""""),
345
466
  slug: str | None = typer.Option(None, "--slug", help=""""""),
346
467
  ) -> None:
@@ -373,8 +494,8 @@ def replace_asset(
373
494
  @app.command("run-asset-jobs", deprecated=False, rich_help_panel="API commands")
374
495
  def run_asset_jobs(
375
496
  ctx: typer.Context,
376
- asset_ids: list[str] = typer.Option(..., "--asset-ids", help=""""""),
377
- name: str = typer.Option(..., "--name", help=""""""),
497
+ asset_ids: list[str] = typer.Option(..., "--asset-ids", help="""Asset IDs"""),
498
+ name: str = typer.Option(..., "--name", help="""Job name"""),
378
499
  ) -> None:
379
500
  """Run an asset job
380
501
 
@@ -396,19 +517,29 @@ def update_asset(
396
517
  ctx: typer.Context,
397
518
  id: str = typer.Argument(..., help=""""""),
398
519
  date_time_original: str | None = typer.Option(
399
- None, "--date-time-original", help=""""""
520
+ None, "--date-time-original", help="""Original date and time"""
521
+ ),
522
+ description: str | None = typer.Option(
523
+ None, "--description", help="""Asset description"""
400
524
  ),
401
- description: str | None = typer.Option(None, "--description", help=""""""),
402
525
  is_favorite: Literal["true", "false"] | None = typer.Option(
403
- None, "--is-favorite", help=""""""
526
+ None, "--is-favorite", help="""Mark as favorite"""
527
+ ),
528
+ latitude: float | None = typer.Option(
529
+ None, "--latitude", help="""Latitude coordinate"""
404
530
  ),
405
- latitude: float | None = typer.Option(None, "--latitude", help=""""""),
406
531
  live_photo_video_id: str | None = typer.Option(
407
- None, "--live-photo-video-id", help=""""""
532
+ None, "--live-photo-video-id", help="""Live photo video ID"""
533
+ ),
534
+ longitude: float | None = typer.Option(
535
+ None, "--longitude", help="""Longitude coordinate"""
536
+ ),
537
+ rating: float | None = typer.Option(
538
+ None, "--rating", help="""Rating""", min=-1, max=5
539
+ ),
540
+ visibility: str | None = typer.Option(
541
+ None, "--visibility", help="""Asset visibility"""
408
542
  ),
409
- longitude: float | None = typer.Option(None, "--longitude", help=""""""),
410
- rating: float | None = typer.Option(None, "--rating", help="""""", min=-1, max=5),
411
- visibility: str | None = typer.Option(None, "--visibility", help=""""""),
412
543
  ) -> None:
413
544
  """Update an asset
414
545
 
@@ -444,7 +575,13 @@ def update_asset(
444
575
  def update_asset_metadata(
445
576
  ctx: typer.Context,
446
577
  id: str = typer.Argument(..., help=""""""),
447
- items: list[str] = typer.Option(..., "--items", help="""As a JSON string"""),
578
+ items: list[str] = typer.Option(
579
+ ...,
580
+ "--items",
581
+ help="""Metadata items to upsert
582
+
583
+ As a JSON string""",
584
+ ),
448
585
  ) -> None:
449
586
  """Update asset metadata
450
587
 
@@ -466,22 +603,36 @@ def update_asset_metadata(
466
603
  def update_assets(
467
604
  ctx: typer.Context,
468
605
  date_time_original: str | None = typer.Option(
469
- None, "--date-time-original", help=""""""
606
+ None, "--date-time-original", help="""Original date and time"""
470
607
  ),
471
608
  date_time_relative: float | None = typer.Option(
472
- None, "--date-time-relative", help=""""""
609
+ None, "--date-time-relative", help="""Relative time offset in seconds"""
610
+ ),
611
+ description: str | None = typer.Option(
612
+ None, "--description", help="""Asset description"""
613
+ ),
614
+ duplicate_id: str | None = typer.Option(
615
+ None, "--duplicate-id", help="""Duplicate asset ID"""
473
616
  ),
474
- description: str | None = typer.Option(None, "--description", help=""""""),
475
- duplicate_id: str | None = typer.Option(None, "--duplicate-id", help=""""""),
476
- ids: list[str] = typer.Option(..., "--ids", help=""""""),
617
+ ids: list[str] = typer.Option(..., "--ids", help="""Asset IDs to update"""),
477
618
  is_favorite: Literal["true", "false"] | None = typer.Option(
478
- None, "--is-favorite", help=""""""
619
+ None, "--is-favorite", help="""Mark as favorite"""
620
+ ),
621
+ latitude: float | None = typer.Option(
622
+ None, "--latitude", help="""Latitude coordinate"""
623
+ ),
624
+ longitude: float | None = typer.Option(
625
+ None, "--longitude", help="""Longitude coordinate"""
626
+ ),
627
+ rating: float | None = typer.Option(
628
+ None, "--rating", help="""Rating""", min=-1, max=5
629
+ ),
630
+ time_zone: str | None = typer.Option(
631
+ None, "--time-zone", help="""Time zone (IANA timezone)"""
632
+ ),
633
+ visibility: str | None = typer.Option(
634
+ None, "--visibility", help="""Asset visibility"""
479
635
  ),
480
- latitude: float | None = typer.Option(None, "--latitude", help=""""""),
481
- longitude: float | None = typer.Option(None, "--longitude", help=""""""),
482
- rating: float | None = typer.Option(None, "--rating", help="""""", min=-1, max=5),
483
- time_zone: str | None = typer.Option(None, "--time-zone", help=""""""),
484
- visibility: str | None = typer.Option(None, "--visibility", help=""""""),
485
636
  ) -> None:
486
637
  """Update assets
487
638
 
@@ -517,29 +668,79 @@ def update_assets(
517
668
  print_response(result, ctx)
518
669
 
519
670
 
671
+ @app.command(
672
+ "update-bulk-asset-metadata", deprecated=False, rich_help_panel="API commands"
673
+ )
674
+ def update_bulk_asset_metadata(
675
+ ctx: typer.Context,
676
+ items: list[str] = typer.Option(
677
+ ...,
678
+ "--items",
679
+ help="""Metadata items to upsert
680
+
681
+ As a JSON string""",
682
+ ),
683
+ ) -> None:
684
+ """Upsert asset metadata
685
+
686
+ [link=https://api.immich.app/endpoints/assets/updateBulkAssetMetadata]Immich API documentation[/link]
687
+ """
688
+ kwargs = {}
689
+ json_data = {}
690
+ value_items = [json.loads(i) for i in items]
691
+ set_nested(json_data, ["items"], value_items)
692
+ asset_metadata_bulk_upsert_dto = AssetMetadataBulkUpsertDto.model_validate(
693
+ json_data
694
+ )
695
+ kwargs["asset_metadata_bulk_upsert_dto"] = asset_metadata_bulk_upsert_dto
696
+ client: "AsyncClient" = ctx.obj["client"]
697
+ result = run_command(
698
+ client, client.assets, "update_bulk_asset_metadata", ctx, **kwargs
699
+ )
700
+ print_response(result, ctx)
701
+
702
+
520
703
  @app.command("upload-asset", deprecated=False, rich_help_panel="API commands")
521
704
  def upload_asset(
522
705
  ctx: typer.Context,
523
- asset_data: Path = typer.Option(..., "--asset-data", help="""""", exists=True),
524
- device_asset_id: str = typer.Option(..., "--device-asset-id", help=""""""),
525
- device_id: str = typer.Option(..., "--device-id", help=""""""),
526
- duration: str | None = typer.Option(None, "--duration", help=""""""),
527
- file_created_at: datetime = typer.Option(..., "--file-created-at", help=""""""),
528
- file_modified_at: datetime = typer.Option(..., "--file-modified-at", help=""""""),
529
- filename: str | None = typer.Option(None, "--filename", help=""""""),
706
+ asset_data: Path = typer.Option(
707
+ ..., "--asset-data", help="""Asset file data""", exists=True
708
+ ),
709
+ device_asset_id: str = typer.Option(
710
+ ..., "--device-asset-id", help="""Device asset ID"""
711
+ ),
712
+ device_id: str = typer.Option(..., "--device-id", help="""Device ID"""),
713
+ duration: str | None = typer.Option(
714
+ None, "--duration", help="""Duration (for videos)"""
715
+ ),
716
+ file_created_at: datetime = typer.Option(
717
+ ..., "--file-created-at", help="""File creation date"""
718
+ ),
719
+ file_modified_at: datetime = typer.Option(
720
+ ..., "--file-modified-at", help="""File modification date"""
721
+ ),
722
+ filename: str | None = typer.Option(None, "--filename", help="""Filename"""),
530
723
  is_favorite: Literal["true", "false"] | None = typer.Option(
531
- None, "--is-favorite", help=""""""
724
+ None, "--is-favorite", help="""Mark as favorite"""
532
725
  ),
533
726
  key: str | None = typer.Option(None, "--key", help=""""""),
534
727
  live_photo_video_id: str | None = typer.Option(
535
- None, "--live-photo-video-id", help=""""""
728
+ None, "--live-photo-video-id", help="""Live photo video ID"""
729
+ ),
730
+ metadata: list[str] | None = typer.Option(
731
+ None,
732
+ "--metadata",
733
+ help="""Asset metadata items
734
+
735
+ As a JSON string""",
536
736
  ),
537
- metadata: list[str] = typer.Option(..., "--metadata", help="""As a JSON string"""),
538
737
  sidecar_data: Path | None = typer.Option(
539
- None, "--sidecar-data", help="""""", exists=True
738
+ None, "--sidecar-data", help="""Sidecar file data""", exists=True
540
739
  ),
541
740
  slug: str | None = typer.Option(None, "--slug", help=""""""),
542
- visibility: str | None = typer.Option(None, "--visibility", help=""""""),
741
+ visibility: str | None = typer.Option(
742
+ None, "--visibility", help="""Asset visibility"""
743
+ ),
543
744
  x_immich_checksum: str | None = typer.Option(
544
745
  None,
545
746
  "--x-immich-checksum",
@@ -571,8 +772,9 @@ def upload_asset(
571
772
  set_nested(json_data, ["is_favorite"], is_favorite.lower() == "true")
572
773
  if live_photo_video_id is not None:
573
774
  set_nested(json_data, ["live_photo_video_id"], live_photo_video_id)
574
- value_metadata = [json.loads(i) for i in metadata]
575
- set_nested(json_data, ["metadata"], value_metadata)
775
+ if metadata is not None:
776
+ value_metadata = [json.loads(i) for i in metadata]
777
+ set_nested(json_data, ["metadata"], value_metadata)
576
778
  if sidecar_data is not None:
577
779
  set_nested(
578
780
  json_data, ["sidecar_data"], (sidecar_data.name, sidecar_data.read_bytes())
@@ -589,8 +791,13 @@ def upload_asset(
589
791
  def view_asset(
590
792
  ctx: typer.Context,
591
793
  id: str = typer.Argument(..., help=""""""),
794
+ edited: Literal["true", "false"] | None = typer.Option(
795
+ None, "--edited", help="""Return edited asset if available"""
796
+ ),
592
797
  key: str | None = typer.Option(None, "--key", help=""""""),
593
- size: AssetMediaSize | None = typer.Option(None, "--size", help=""""""),
798
+ size: AssetMediaSize | None = typer.Option(
799
+ None, "--size", help="""Asset media size"""
800
+ ),
594
801
  slug: str | None = typer.Option(None, "--slug", help=""""""),
595
802
  ) -> None:
596
803
  """View asset thumbnail
@@ -598,6 +805,8 @@ def view_asset(
598
805
  [link=https://api.immich.app/endpoints/assets/viewAsset]Immich API documentation[/link]
599
806
  """
600
807
  kwargs = {}
808
+ if edited is not None:
809
+ kwargs["edited"] = edited.lower() == "true"
601
810
  kwargs["id"] = id
602
811
  if key is not None:
603
812
  kwargs["key"] = key