immich 1.2.1__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.
- immich/.openapi-generator/FILES +372 -0
- immich/.openapi-generator/VERSION +1 -0
- immich/.openapi-generator-ignore +48 -0
- immich/__init__.py +3 -0
- immich/client/__init__.py +1162 -0
- immich/client/api/__init__.py +39 -0
- immich/client/api/activities_api.py +1092 -0
- immich/client/api/albums_api.py +3228 -0
- immich/client/api/api_keys_api.py +1484 -0
- immich/client/api/assets_api.py +5834 -0
- immich/client/api/authentication_admin_api.py +254 -0
- immich/client/api/authentication_api.py +3881 -0
- immich/client/api/deprecated_api.py +2199 -0
- immich/client/api/download_api.py +603 -0
- immich/client/api/duplicates_api.py +743 -0
- immich/client/api/faces_api.py +1053 -0
- immich/client/api/jobs_api.py +783 -0
- immich/client/api/libraries_api.py +2004 -0
- immich/client/api/maintenance_admin_api.py +533 -0
- immich/client/api/map_api.py +640 -0
- immich/client/api/memories_api.py +2250 -0
- immich/client/api/notifications_admin_api.py +808 -0
- immich/client/api/notifications_api.py +1564 -0
- immich/client/api/partners_api.py +1278 -0
- immich/client/api/people_api.py +2905 -0
- immich/client/api/plugins_api.py +730 -0
- immich/client/api/queues_api.py +1292 -0
- immich/client/api/search_api.py +3198 -0
- immich/client/api/server_api.py +3466 -0
- immich/client/api/sessions_api.py +1472 -0
- immich/client/api/shared_links_api.py +2177 -0
- immich/client/api/stacks_api.py +1769 -0
- immich/client/api/sync_api.py +1512 -0
- immich/client/api/system_config_api.py +967 -0
- immich/client/api/system_metadata_api.py +964 -0
- immich/client/api/tags_api.py +2296 -0
- immich/client/api/timeline_api.py +1193 -0
- immich/client/api/trash_api.py +739 -0
- immich/client/api/users_admin_api.py +2607 -0
- immich/client/api/users_api.py +3577 -0
- immich/client/api/views_api.py +503 -0
- immich/client/api/workflows_api.py +1257 -0
- immich/client/api_client.py +756 -0
- immich/client/api_response.py +20 -0
- immich/client/configuration.py +638 -0
- immich/client/exceptions.py +222 -0
- immich/client/models/__init__.py +424 -0
- immich/client/models/activity_create_dto.py +94 -0
- immich/client/models/activity_response_dto.py +121 -0
- immich/client/models/activity_statistics_response_dto.py +85 -0
- immich/client/models/add_users_dto.py +101 -0
- immich/client/models/admin_onboarding_update_dto.py +82 -0
- immich/client/models/album_response_dto.py +199 -0
- immich/client/models/album_statistics_response_dto.py +90 -0
- immich/client/models/album_user_add_dto.py +87 -0
- immich/client/models/album_user_create_dto.py +87 -0
- immich/client/models/album_user_response_dto.py +95 -0
- immich/client/models/album_user_role.py +34 -0
- immich/client/models/albums_add_assets_dto.py +86 -0
- immich/client/models/albums_add_assets_response_dto.py +86 -0
- immich/client/models/albums_response.py +83 -0
- immich/client/models/albums_update.py +85 -0
- immich/client/models/api_key_create_dto.py +87 -0
- immich/client/models/api_key_create_response_dto.py +94 -0
- immich/client/models/api_key_response_dto.py +102 -0
- immich/client/models/api_key_update_dto.py +87 -0
- immich/client/models/asset_bulk_delete_dto.py +84 -0
- immich/client/models/asset_bulk_update_dto.py +143 -0
- immich/client/models/asset_bulk_upload_check_dto.py +98 -0
- immich/client/models/asset_bulk_upload_check_item.py +85 -0
- immich/client/models/asset_bulk_upload_check_response_dto.py +101 -0
- immich/client/models/asset_bulk_upload_check_result.py +126 -0
- immich/client/models/asset_copy_dto.py +113 -0
- immich/client/models/asset_delta_sync_dto.py +87 -0
- immich/client/models/asset_delta_sync_response_dto.py +102 -0
- immich/client/models/asset_face_create_dto.py +110 -0
- immich/client/models/asset_face_delete_dto.py +82 -0
- immich/client/models/asset_face_response_dto.py +125 -0
- immich/client/models/asset_face_update_dto.py +96 -0
- immich/client/models/asset_face_update_item.py +86 -0
- immich/client/models/asset_face_without_person_response_dto.py +111 -0
- immich/client/models/asset_full_sync_dto.py +95 -0
- immich/client/models/asset_ids_dto.py +83 -0
- immich/client/models/asset_ids_response_dto.py +109 -0
- immich/client/models/asset_job_name.py +36 -0
- immich/client/models/asset_jobs_dto.py +87 -0
- immich/client/models/asset_media_response_dto.py +84 -0
- immich/client/models/asset_media_size.py +35 -0
- immich/client/models/asset_media_status.py +35 -0
- immich/client/models/asset_metadata_key.py +33 -0
- immich/client/models/asset_metadata_response_dto.py +92 -0
- immich/client/models/asset_metadata_upsert_dto.py +101 -0
- immich/client/models/asset_metadata_upsert_item_dto.py +84 -0
- immich/client/models/asset_ocr_response_dto.py +145 -0
- immich/client/models/asset_order.py +34 -0
- immich/client/models/asset_response_dto.py +291 -0
- immich/client/models/asset_stack_response_dto.py +90 -0
- immich/client/models/asset_stats_response_dto.py +90 -0
- immich/client/models/asset_type_enum.py +36 -0
- immich/client/models/asset_visibility.py +36 -0
- immich/client/models/audio_codec.py +36 -0
- immich/client/models/auth_status_response_dto.py +100 -0
- immich/client/models/avatar_update.py +83 -0
- immich/client/models/bulk_id_error_reason.py +36 -0
- immich/client/models/bulk_id_response_dto.py +102 -0
- immich/client/models/bulk_ids_dto.py +83 -0
- immich/client/models/cast_response.py +88 -0
- immich/client/models/cast_update.py +82 -0
- immich/client/models/change_password_dto.py +101 -0
- immich/client/models/check_existing_assets_dto.py +91 -0
- immich/client/models/check_existing_assets_response_dto.py +82 -0
- immich/client/models/clip_config.py +85 -0
- immich/client/models/colorspace.py +34 -0
- immich/client/models/contributor_count_response_dto.py +85 -0
- immich/client/models/cq_mode.py +35 -0
- immich/client/models/create_album_dto.py +112 -0
- immich/client/models/create_library_dto.py +103 -0
- immich/client/models/create_profile_image_response_dto.py +95 -0
- immich/client/models/database_backup_config.py +94 -0
- immich/client/models/download_archive_info.py +85 -0
- immich/client/models/download_info_dto.py +96 -0
- immich/client/models/download_response.py +90 -0
- immich/client/models/download_response_dto.py +100 -0
- immich/client/models/download_update.py +93 -0
- immich/client/models/duplicate_detection_config.py +89 -0
- immich/client/models/duplicate_response_dto.py +98 -0
- immich/client/models/email_notifications_response.py +90 -0
- immich/client/models/email_notifications_update.py +90 -0
- immich/client/models/exif_response_dto.py +284 -0
- immich/client/models/face_dto.py +83 -0
- immich/client/models/facial_recognition_config.py +107 -0
- immich/client/models/folders_response.py +92 -0
- immich/client/models/folders_update.py +85 -0
- immich/client/models/image_format.py +34 -0
- immich/client/models/job_create_dto.py +83 -0
- immich/client/models/job_name.py +87 -0
- immich/client/models/job_settings_dto.py +83 -0
- immich/client/models/library_response_dto.py +118 -0
- immich/client/models/library_stats_response_dto.py +92 -0
- immich/client/models/license_key_dto.py +98 -0
- immich/client/models/license_response_dto.py +101 -0
- immich/client/models/log_level.py +38 -0
- immich/client/models/login_credential_dto.py +85 -0
- immich/client/models/login_response_dto.py +109 -0
- immich/client/models/logout_response_dto.py +85 -0
- immich/client/models/machine_learning_availability_checks_dto.py +90 -0
- immich/client/models/maintenance_action.py +34 -0
- immich/client/models/maintenance_auth_dto.py +82 -0
- immich/client/models/maintenance_login_dto.py +82 -0
- immich/client/models/manual_job_name.py +38 -0
- immich/client/models/map_marker_response_dto.py +111 -0
- immich/client/models/map_reverse_geocode_response_dto.py +105 -0
- immich/client/models/memories_response.py +92 -0
- immich/client/models/memories_update.py +86 -0
- immich/client/models/memory_create_dto.py +112 -0
- immich/client/models/memory_response_dto.py +142 -0
- immich/client/models/memory_search_order.py +35 -0
- immich/client/models/memory_statistics_response_dto.py +82 -0
- immich/client/models/memory_type.py +33 -0
- immich/client/models/memory_update_dto.py +91 -0
- immich/client/models/merge_person_dto.py +83 -0
- immich/client/models/metadata_search_dto.py +277 -0
- immich/client/models/notification_create_dto.py +120 -0
- immich/client/models/notification_delete_all_dto.py +83 -0
- immich/client/models/notification_dto.py +112 -0
- immich/client/models/notification_level.py +36 -0
- immich/client/models/notification_type.py +38 -0
- immich/client/models/notification_update_all_dto.py +90 -0
- immich/client/models/notification_update_dto.py +88 -0
- immich/client/models/o_auth_authorize_response_dto.py +82 -0
- immich/client/models/o_auth_callback_dto.py +90 -0
- immich/client/models/o_auth_config_dto.py +90 -0
- immich/client/models/o_auth_token_endpoint_auth_method.py +34 -0
- immich/client/models/ocr_config.py +109 -0
- immich/client/models/on_this_day_dto.py +86 -0
- immich/client/models/onboarding_dto.py +82 -0
- immich/client/models/onboarding_response_dto.py +82 -0
- immich/client/models/partner_create_dto.py +83 -0
- immich/client/models/partner_direction.py +34 -0
- immich/client/models/partner_response_dto.py +108 -0
- immich/client/models/partner_update_dto.py +82 -0
- immich/client/models/people_response.py +92 -0
- immich/client/models/people_response_dto.py +104 -0
- immich/client/models/people_update.py +85 -0
- immich/client/models/people_update_dto.py +96 -0
- immich/client/models/people_update_item.py +128 -0
- immich/client/models/permission.py +177 -0
- immich/client/models/person_create_dto.py +117 -0
- immich/client/models/person_response_dto.py +115 -0
- immich/client/models/person_statistics_response_dto.py +82 -0
- immich/client/models/person_update_dto.py +125 -0
- immich/client/models/person_with_faces_response_dto.py +133 -0
- immich/client/models/pin_code_change_dto.py +90 -0
- immich/client/models/pin_code_reset_dto.py +85 -0
- immich/client/models/pin_code_setup_dto.py +82 -0
- immich/client/models/places_response_dto.py +100 -0
- immich/client/models/plugin_action_response_dto.py +112 -0
- immich/client/models/plugin_context_type.py +35 -0
- immich/client/models/plugin_filter_response_dto.py +112 -0
- immich/client/models/plugin_response_dto.py +139 -0
- immich/client/models/plugin_trigger_response_dto.py +87 -0
- immich/client/models/plugin_trigger_type.py +34 -0
- immich/client/models/purchase_response.py +88 -0
- immich/client/models/purchase_update.py +92 -0
- immich/client/models/queue_command.py +37 -0
- immich/client/models/queue_command_dto.py +86 -0
- immich/client/models/queue_delete_dto.py +85 -0
- immich/client/models/queue_job_response_dto.py +93 -0
- immich/client/models/queue_job_status.py +38 -0
- immich/client/models/queue_name.py +49 -0
- immich/client/models/queue_response_dto.py +97 -0
- immich/client/models/queue_response_legacy_dto.py +100 -0
- immich/client/models/queue_statistics_dto.py +103 -0
- immich/client/models/queue_status_legacy_dto.py +85 -0
- immich/client/models/queue_update_dto.py +82 -0
- immich/client/models/queues_response_legacy_dto.py +242 -0
- immich/client/models/random_search_dto.py +234 -0
- immich/client/models/ratings_response.py +84 -0
- immich/client/models/ratings_update.py +82 -0
- immich/client/models/reaction_level.py +34 -0
- immich/client/models/reaction_type.py +34 -0
- immich/client/models/reverse_geocoding_state_response_dto.py +101 -0
- immich/client/models/search_album_response_dto.py +114 -0
- immich/client/models/search_asset_response_dto.py +127 -0
- immich/client/models/search_explore_item.py +94 -0
- immich/client/models/search_explore_response_dto.py +98 -0
- immich/client/models/search_facet_count_response_dto.py +85 -0
- immich/client/models/search_facet_response_dto.py +103 -0
- immich/client/models/search_response_dto.py +100 -0
- immich/client/models/search_statistics_response_dto.py +82 -0
- immich/client/models/search_suggestion_type.py +38 -0
- immich/client/models/server_about_response_dto.py +156 -0
- immich/client/models/server_apk_links_dto.py +97 -0
- immich/client/models/server_config_dto.py +118 -0
- immich/client/models/server_features_dto.py +130 -0
- immich/client/models/server_media_types_response_dto.py +90 -0
- immich/client/models/server_ping_response.py +87 -0
- immich/client/models/server_stats_response_dto.py +119 -0
- immich/client/models/server_storage_response_dto.py +108 -0
- immich/client/models/server_theme_dto.py +82 -0
- immich/client/models/server_version_history_response_dto.py +91 -0
- immich/client/models/server_version_response_dto.py +90 -0
- immich/client/models/session_create_dto.py +96 -0
- immich/client/models/session_create_response_dto.py +120 -0
- immich/client/models/session_response_dto.py +117 -0
- immich/client/models/session_unlock_dto.py +85 -0
- immich/client/models/session_update_dto.py +84 -0
- immich/client/models/set_maintenance_mode_dto.py +83 -0
- immich/client/models/shared_link_create_dto.py +142 -0
- immich/client/models/shared_link_edit_dto.py +134 -0
- immich/client/models/shared_link_response_dto.py +173 -0
- immich/client/models/shared_link_type.py +34 -0
- immich/client/models/shared_links_response.py +92 -0
- immich/client/models/shared_links_update.py +85 -0
- immich/client/models/sign_up_dto.py +90 -0
- immich/client/models/smart_search_dto.py +245 -0
- immich/client/models/source_type.py +35 -0
- immich/client/models/stack_create_dto.py +86 -0
- immich/client/models/stack_response_dto.py +100 -0
- immich/client/models/stack_update_dto.py +83 -0
- immich/client/models/statistics_search_dto.py +217 -0
- immich/client/models/sync_ack_delete_dto.py +83 -0
- immich/client/models/sync_ack_dto.py +84 -0
- immich/client/models/sync_ack_set_dto.py +83 -0
- immich/client/models/sync_album_delete_v1.py +82 -0
- immich/client/models/sync_album_to_asset_delete_v1.py +85 -0
- immich/client/models/sync_album_to_asset_v1.py +85 -0
- immich/client/models/sync_album_user_delete_v1.py +85 -0
- immich/client/models/sync_album_user_v1.py +91 -0
- immich/client/models/sync_album_v1.py +122 -0
- immich/client/models/sync_asset_delete_v1.py +82 -0
- immich/client/models/sync_asset_exif_v1.py +296 -0
- immich/client/models/sync_asset_face_delete_v1.py +82 -0
- immich/client/models/sync_asset_face_v1.py +120 -0
- immich/client/models/sync_asset_metadata_delete_v1.py +86 -0
- immich/client/models/sync_asset_metadata_v1.py +91 -0
- immich/client/models/sync_asset_v1.py +187 -0
- immich/client/models/sync_auth_user_v1.py +154 -0
- immich/client/models/sync_entity_type.py +79 -0
- immich/client/models/sync_memory_asset_delete_v1.py +85 -0
- immich/client/models/sync_memory_asset_v1.py +85 -0
- immich/client/models/sync_memory_delete_v1.py +82 -0
- immich/client/models/sync_memory_v1.py +143 -0
- immich/client/models/sync_partner_delete_v1.py +88 -0
- immich/client/models/sync_partner_v1.py +90 -0
- immich/client/models/sync_person_delete_v1.py +82 -0
- immich/client/models/sync_person_v1.py +131 -0
- immich/client/models/sync_request_type.py +52 -0
- immich/client/models/sync_stack_delete_v1.py +82 -0
- immich/client/models/sync_stack_v1.py +101 -0
- immich/client/models/sync_stream_dto.py +86 -0
- immich/client/models/sync_user_delete_v1.py +82 -0
- immich/client/models/sync_user_metadata_delete_v1.py +84 -0
- immich/client/models/sync_user_metadata_v1.py +91 -0
- immich/client/models/sync_user_v1.py +118 -0
- immich/client/models/system_config_backups_dto.py +92 -0
- immich/client/models/system_config_dto.py +302 -0
- immich/client/models/system_config_f_fmpeg_dto.py +156 -0
- immich/client/models/system_config_faces_dto.py +82 -0
- immich/client/models/system_config_generated_fullsize_image_dto.py +92 -0
- immich/client/models/system_config_generated_image_dto.py +92 -0
- immich/client/models/system_config_image_dto.py +124 -0
- immich/client/models/system_config_job_dto.py +194 -0
- immich/client/models/system_config_library_dto.py +104 -0
- immich/client/models/system_config_library_scan_dto.py +85 -0
- immich/client/models/system_config_library_watch_dto.py +82 -0
- immich/client/models/system_config_logging_dto.py +86 -0
- immich/client/models/system_config_machine_learning_dto.py +147 -0
- immich/client/models/system_config_map_dto.py +90 -0
- immich/client/models/system_config_metadata_dto.py +92 -0
- immich/client/models/system_config_new_version_check_dto.py +82 -0
- immich/client/models/system_config_nightly_tasks_dto.py +103 -0
- immich/client/models/system_config_notifications_dto.py +92 -0
- immich/client/models/system_config_o_auth_dto.py +155 -0
- immich/client/models/system_config_password_login_dto.py +82 -0
- immich/client/models/system_config_reverse_geocoding_dto.py +82 -0
- immich/client/models/system_config_server_dto.py +94 -0
- immich/client/models/system_config_smtp_dto.py +100 -0
- immich/client/models/system_config_smtp_transport_dto.py +107 -0
- immich/client/models/system_config_storage_template_dto.py +94 -0
- immich/client/models/system_config_template_emails_dto.py +94 -0
- immich/client/models/system_config_template_storage_option_dto.py +109 -0
- immich/client/models/system_config_templates_dto.py +94 -0
- immich/client/models/system_config_theme_dto.py +82 -0
- immich/client/models/system_config_trash_dto.py +86 -0
- immich/client/models/system_config_user_dto.py +83 -0
- immich/client/models/tag_bulk_assets_dto.py +86 -0
- immich/client/models/tag_bulk_assets_response_dto.py +82 -0
- immich/client/models/tag_create_dto.py +111 -0
- immich/client/models/tag_response_dto.py +107 -0
- immich/client/models/tag_update_dto.py +87 -0
- immich/client/models/tag_upsert_dto.py +82 -0
- immich/client/models/tags_response.py +92 -0
- immich/client/models/tags_update.py +85 -0
- immich/client/models/template_dto.py +82 -0
- immich/client/models/template_response_dto.py +83 -0
- immich/client/models/test_email_response_dto.py +82 -0
- immich/client/models/time_bucket_asset_response_dto.py +195 -0
- immich/client/models/time_buckets_response_dto.py +88 -0
- immich/client/models/tone_mapping.py +36 -0
- immich/client/models/transcode_hw_accel.py +37 -0
- immich/client/models/transcode_policy.py +37 -0
- immich/client/models/trash_response_dto.py +82 -0
- immich/client/models/update_album_dto.py +106 -0
- immich/client/models/update_album_user_dto.py +83 -0
- immich/client/models/update_asset_dto.py +135 -0
- immich/client/models/update_library_dto.py +95 -0
- immich/client/models/usage_by_user_dto.py +117 -0
- immich/client/models/user_admin_create_dto.py +136 -0
- immich/client/models/user_admin_delete_dto.py +82 -0
- immich/client/models/user_admin_response_dto.py +176 -0
- immich/client/models/user_admin_update_dto.py +141 -0
- immich/client/models/user_avatar_color.py +42 -0
- immich/client/models/user_license.py +91 -0
- immich/client/models/user_metadata_key.py +35 -0
- immich/client/models/user_preferences_response_dto.py +186 -0
- immich/client/models/user_preferences_update_dto.py +197 -0
- immich/client/models/user_response_dto.py +105 -0
- immich/client/models/user_status.py +35 -0
- immich/client/models/user_update_me_dto.py +98 -0
- immich/client/models/validate_access_token_response_dto.py +82 -0
- immich/client/models/validate_library_dto.py +93 -0
- immich/client/models/validate_library_import_path_response_dto.py +92 -0
- immich/client/models/validate_library_response_dto.py +103 -0
- immich/client/models/version_check_state_response_dto.py +98 -0
- immich/client/models/video_codec.py +36 -0
- immich/client/models/video_container.py +36 -0
- immich/client/models/workflow_action_item_dto.py +89 -0
- immich/client/models/workflow_action_response_dto.py +105 -0
- immich/client/models/workflow_create_dto.py +128 -0
- immich/client/models/workflow_filter_item_dto.py +89 -0
- immich/client/models/workflow_filter_response_dto.py +105 -0
- immich/client/models/workflow_response_dto.py +144 -0
- immich/client/models/workflow_update_dto.py +128 -0
- immich/client/py.typed +0 -0
- immich/client/rest.py +199 -0
- immich/client_wrapper/__init__.py +15 -0
- immich/client_wrapper/assets_api_wrapped.py +87 -0
- immich/client_wrapper/download_api_wrapped.py +111 -0
- immich/client_wrapper/users_api_wrapped.py +41 -0
- immich/py.typed +0 -0
- immich/sdk.py +365 -0
- immich/utils.py +100 -0
- immich-1.2.1.dist-info/METADATA +166 -0
- immich-1.2.1.dist-info/RECORD +387 -0
- immich-1.2.1.dist-info/WHEEL +4 -0
- immich-1.2.1.dist-info/licenses/LICENSE +9 -0
immich/client/rest.py
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Immich
|
|
5
|
+
|
|
6
|
+
Immich API
|
|
7
|
+
|
|
8
|
+
The version of the OpenAPI document: 2.4.1
|
|
9
|
+
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
10
|
+
|
|
11
|
+
Do not edit the class manually.
|
|
12
|
+
""" # noqa: E501
|
|
13
|
+
|
|
14
|
+
import io
|
|
15
|
+
import json
|
|
16
|
+
import re
|
|
17
|
+
import ssl
|
|
18
|
+
from typing import Optional, Union
|
|
19
|
+
|
|
20
|
+
import aiohttp
|
|
21
|
+
import aiohttp_retry
|
|
22
|
+
|
|
23
|
+
from immich.client.exceptions import ApiException, ApiValueError
|
|
24
|
+
|
|
25
|
+
RESTResponseType = aiohttp.ClientResponse
|
|
26
|
+
|
|
27
|
+
ALLOW_RETRY_METHODS = frozenset({"DELETE", "GET", "HEAD", "OPTIONS", "PUT", "TRACE"})
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class RESTResponse(io.IOBase):
|
|
31
|
+
def __init__(self, resp) -> None:
|
|
32
|
+
self.response = resp
|
|
33
|
+
self.status = resp.status
|
|
34
|
+
self.reason = resp.reason
|
|
35
|
+
self.data = None
|
|
36
|
+
|
|
37
|
+
async def read(self):
|
|
38
|
+
if self.data is None:
|
|
39
|
+
self.data = await self.response.read()
|
|
40
|
+
return self.data
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def headers(self):
|
|
44
|
+
"""Returns a CIMultiDictProxy of response headers."""
|
|
45
|
+
return self.response.headers
|
|
46
|
+
|
|
47
|
+
def getheaders(self):
|
|
48
|
+
"""Returns a CIMultiDictProxy of the response headers; use ``headers`` instead."""
|
|
49
|
+
return self.response.headers
|
|
50
|
+
|
|
51
|
+
def getheader(self, name, default=None):
|
|
52
|
+
"""Returns a given response header; use ``headers.get()`` instead."""
|
|
53
|
+
return self.response.headers.get(name, default)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class RESTClientObject:
|
|
57
|
+
def __init__(self, configuration) -> None:
|
|
58
|
+
# maxsize is number of requests to host that are allowed in parallel
|
|
59
|
+
self.maxsize = configuration.connection_pool_maxsize
|
|
60
|
+
|
|
61
|
+
self.ssl_context = ssl.create_default_context(
|
|
62
|
+
cafile=configuration.ssl_ca_cert,
|
|
63
|
+
cadata=configuration.ca_cert_data,
|
|
64
|
+
)
|
|
65
|
+
if configuration.cert_file:
|
|
66
|
+
self.ssl_context.load_cert_chain(
|
|
67
|
+
configuration.cert_file, keyfile=configuration.key_file
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
if not configuration.verify_ssl:
|
|
71
|
+
self.ssl_context.check_hostname = False
|
|
72
|
+
self.ssl_context.verify_mode = ssl.CERT_NONE
|
|
73
|
+
|
|
74
|
+
self.proxy = configuration.proxy
|
|
75
|
+
self.proxy_headers = configuration.proxy_headers
|
|
76
|
+
|
|
77
|
+
self.retries = configuration.retries
|
|
78
|
+
|
|
79
|
+
self.pool_manager: Optional[aiohttp.ClientSession] = None
|
|
80
|
+
self.retry_client: Optional[aiohttp_retry.RetryClient] = None
|
|
81
|
+
|
|
82
|
+
async def close(self) -> None:
|
|
83
|
+
if self.pool_manager:
|
|
84
|
+
await self.pool_manager.close()
|
|
85
|
+
if self.retry_client is not None:
|
|
86
|
+
await self.retry_client.close()
|
|
87
|
+
|
|
88
|
+
async def request(
|
|
89
|
+
self,
|
|
90
|
+
method,
|
|
91
|
+
url,
|
|
92
|
+
headers=None,
|
|
93
|
+
body=None,
|
|
94
|
+
post_params=None,
|
|
95
|
+
_request_timeout=None,
|
|
96
|
+
):
|
|
97
|
+
"""Execute request
|
|
98
|
+
|
|
99
|
+
:param method: http request method
|
|
100
|
+
:param url: http request url
|
|
101
|
+
:param headers: http request headers
|
|
102
|
+
:param body: request json body, for `application/json`
|
|
103
|
+
:param post_params: request post parameters,
|
|
104
|
+
`application/x-www-form-urlencoded`
|
|
105
|
+
and `multipart/form-data`
|
|
106
|
+
:param _request_timeout: timeout setting for this request. If one
|
|
107
|
+
number provided, it will be total request
|
|
108
|
+
timeout. It can also be a pair (tuple) of
|
|
109
|
+
(connection, read) timeouts.
|
|
110
|
+
"""
|
|
111
|
+
method = method.upper()
|
|
112
|
+
assert method in ["GET", "HEAD", "DELETE", "POST", "PUT", "PATCH", "OPTIONS"]
|
|
113
|
+
|
|
114
|
+
if post_params and body:
|
|
115
|
+
raise ApiValueError(
|
|
116
|
+
"body parameter cannot be used with post_params parameter."
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
post_params = post_params or {}
|
|
120
|
+
headers = headers or {}
|
|
121
|
+
# url already contains the URL query string
|
|
122
|
+
timeout = _request_timeout or 5 * 60
|
|
123
|
+
|
|
124
|
+
if "Content-Type" not in headers:
|
|
125
|
+
headers["Content-Type"] = "application/json"
|
|
126
|
+
|
|
127
|
+
args = {"method": method, "url": url, "timeout": timeout, "headers": headers}
|
|
128
|
+
|
|
129
|
+
if self.proxy:
|
|
130
|
+
args["proxy"] = self.proxy
|
|
131
|
+
if self.proxy_headers:
|
|
132
|
+
args["proxy_headers"] = self.proxy_headers
|
|
133
|
+
|
|
134
|
+
# For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
|
|
135
|
+
if method in ["POST", "PUT", "PATCH", "OPTIONS", "DELETE"]:
|
|
136
|
+
if re.search("json", headers["Content-Type"], re.IGNORECASE):
|
|
137
|
+
if body is not None:
|
|
138
|
+
body = json.dumps(body)
|
|
139
|
+
args["data"] = body
|
|
140
|
+
elif headers["Content-Type"] == "application/x-www-form-urlencoded":
|
|
141
|
+
args["data"] = aiohttp.FormData(post_params)
|
|
142
|
+
elif headers["Content-Type"] == "multipart/form-data":
|
|
143
|
+
# must del headers['Content-Type'], or the correct
|
|
144
|
+
# Content-Type which generated by aiohttp
|
|
145
|
+
del headers["Content-Type"]
|
|
146
|
+
data = aiohttp.FormData()
|
|
147
|
+
for param in post_params:
|
|
148
|
+
k, v = param
|
|
149
|
+
if isinstance(v, tuple) and len(v) == 3:
|
|
150
|
+
data.add_field(k, value=v[1], filename=v[0], content_type=v[2])
|
|
151
|
+
else:
|
|
152
|
+
# Ensures that dict objects are serialized
|
|
153
|
+
if isinstance(v, dict):
|
|
154
|
+
v = json.dumps(v)
|
|
155
|
+
elif isinstance(v, int):
|
|
156
|
+
v = str(v)
|
|
157
|
+
data.add_field(k, v)
|
|
158
|
+
args["data"] = data
|
|
159
|
+
|
|
160
|
+
# Pass a `bytes` or `str` parameter directly in the body to support
|
|
161
|
+
# other content types than Json when `body` argument is provided
|
|
162
|
+
# in serialized form
|
|
163
|
+
elif isinstance(body, str) or isinstance(body, bytes):
|
|
164
|
+
args["data"] = body
|
|
165
|
+
else:
|
|
166
|
+
# Cannot generate the request from given parameters
|
|
167
|
+
msg = """Cannot prepare a request message for provided
|
|
168
|
+
arguments. Please check that your arguments match
|
|
169
|
+
declared content type."""
|
|
170
|
+
raise ApiException(status=0, reason=msg)
|
|
171
|
+
|
|
172
|
+
pool_manager: Union[aiohttp.ClientSession, aiohttp_retry.RetryClient]
|
|
173
|
+
|
|
174
|
+
# https pool manager
|
|
175
|
+
if self.pool_manager is None:
|
|
176
|
+
self.pool_manager = aiohttp.ClientSession(
|
|
177
|
+
connector=aiohttp.TCPConnector(
|
|
178
|
+
limit=self.maxsize, ssl=self.ssl_context
|
|
179
|
+
),
|
|
180
|
+
trust_env=True,
|
|
181
|
+
)
|
|
182
|
+
pool_manager = self.pool_manager
|
|
183
|
+
|
|
184
|
+
if self.retries is not None and method in ALLOW_RETRY_METHODS:
|
|
185
|
+
if self.retry_client is None:
|
|
186
|
+
self.retry_client = aiohttp_retry.RetryClient(
|
|
187
|
+
client_session=self.pool_manager,
|
|
188
|
+
retry_options=aiohttp_retry.ExponentialRetry(
|
|
189
|
+
attempts=self.retries,
|
|
190
|
+
factor=2.0,
|
|
191
|
+
start_timeout=0.1,
|
|
192
|
+
max_timeout=120.0,
|
|
193
|
+
),
|
|
194
|
+
)
|
|
195
|
+
pool_manager = self.retry_client
|
|
196
|
+
|
|
197
|
+
r = await pool_manager.request(**args)
|
|
198
|
+
|
|
199
|
+
return RESTResponse(r)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from immich.client_wrapper.assets_api_wrapped import (
|
|
2
|
+
AssetsApiWrapped as AssetsApiWrapped,
|
|
3
|
+
)
|
|
4
|
+
from immich.client_wrapper.download_api_wrapped import (
|
|
5
|
+
DownloadApiWrapped as DownloadApiWrapped,
|
|
6
|
+
)
|
|
7
|
+
from immich.client_wrapper.users_api_wrapped import (
|
|
8
|
+
UsersApiWrapped as UsersApiWrapped,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"AssetsApiWrapped",
|
|
13
|
+
"DownloadApiWrapped",
|
|
14
|
+
"UsersApiWrapped",
|
|
15
|
+
]
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any, Optional
|
|
5
|
+
from uuid import UUID
|
|
6
|
+
|
|
7
|
+
from pydantic import StrictStr
|
|
8
|
+
|
|
9
|
+
from immich.client.api.assets_api import AssetsApi
|
|
10
|
+
from immich.client.models.asset_media_size import AssetMediaSize
|
|
11
|
+
from immich.utils import resolve_output_filename
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AssetsApiWrapped(AssetsApi):
|
|
15
|
+
async def download_asset_to_file(
|
|
16
|
+
self,
|
|
17
|
+
id: UUID,
|
|
18
|
+
out_dir: Path,
|
|
19
|
+
key: Optional[StrictStr] = None,
|
|
20
|
+
slug: Optional[StrictStr] = None,
|
|
21
|
+
filename: Optional[str] = None,
|
|
22
|
+
**kwargs: Any,
|
|
23
|
+
) -> Path:
|
|
24
|
+
"""
|
|
25
|
+
Download an asset to a file.
|
|
26
|
+
|
|
27
|
+
:param id: The asset ID.
|
|
28
|
+
:param out_dir: The directory to write the asset to.
|
|
29
|
+
:param key: Public share key (the last path segment of a public share URL, i.e. `/share/<key>`). When provided, the asset can be accessed via the public share link without an API key. Typically you pass either `key` or `slug`.
|
|
30
|
+
:param slug: Public share slug for custom share URLs (the last path segment of `/s/<slug>`). Allows access without authentication. Typically you pass either `slug` or `key`.
|
|
31
|
+
:param filename: The filename to use. If not provided, we use the original filename from the headers or default to "orig-" + asset_id.
|
|
32
|
+
:param kwargs: Additional arguments to pass to the `download_asset_with_http_info` method.
|
|
33
|
+
|
|
34
|
+
For exact request/response behavior, inspect `AssetsApi.download_asset_with_http_info`
|
|
35
|
+
in the generated client.
|
|
36
|
+
"""
|
|
37
|
+
resp = await super().download_asset_with_http_info(
|
|
38
|
+
id=id, key=key, slug=slug, **kwargs
|
|
39
|
+
)
|
|
40
|
+
name = resolve_output_filename(
|
|
41
|
+
resp.headers,
|
|
42
|
+
name=filename,
|
|
43
|
+
default_base=f"orig-{id}",
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
47
|
+
out_path = out_dir / name
|
|
48
|
+
out_path.write_bytes(bytes(resp.data))
|
|
49
|
+
return out_path
|
|
50
|
+
|
|
51
|
+
async def view_asset_to_file(
|
|
52
|
+
self,
|
|
53
|
+
id: UUID,
|
|
54
|
+
out_dir: Path,
|
|
55
|
+
key: Optional[StrictStr] = None,
|
|
56
|
+
size: Optional[AssetMediaSize] = None,
|
|
57
|
+
slug: Optional[StrictStr] = None,
|
|
58
|
+
filename: Optional[str] = None,
|
|
59
|
+
**kwargs: Any,
|
|
60
|
+
) -> Path:
|
|
61
|
+
"""
|
|
62
|
+
Save an asset's thumbnail to a file.
|
|
63
|
+
|
|
64
|
+
:param id: The asset ID.
|
|
65
|
+
:param out_dir: The directory to write the asset to.
|
|
66
|
+
:param key: Public share key (the last path segment of a public share URL, i.e. `/share/<key>`). When provided, the thumbnail can be fetched via the public share link without an API key. Typically you pass either `key` or `slug`.
|
|
67
|
+
:param size: Thumbnail size.
|
|
68
|
+
:param slug: Public share slug for custom share URLs (the last path segment of `/s/<slug>`). Allows access without authentication. Typically you pass either `slug` or `key`.
|
|
69
|
+
:param filename: The filename to use. If not provided, we use the original filename from the headers or default to "thumb-" + asset_id.
|
|
70
|
+
:param kwargs: Additional arguments to pass to the `view_asset_with_http_info` method.
|
|
71
|
+
|
|
72
|
+
For exact request/response behavior, inspect `AssetsApi.view_asset_with_http_info`
|
|
73
|
+
in the generated client.
|
|
74
|
+
"""
|
|
75
|
+
resp = await super().view_asset_with_http_info(
|
|
76
|
+
id=id, key=key, size=size, slug=slug, **kwargs
|
|
77
|
+
)
|
|
78
|
+
name = resolve_output_filename(
|
|
79
|
+
resp.headers,
|
|
80
|
+
name=filename,
|
|
81
|
+
default_base=f"thumb-{id}",
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
85
|
+
out_path = out_dir / name
|
|
86
|
+
out_path.write_bytes(bytes(resp.data))
|
|
87
|
+
return out_path
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import uuid
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Any, Optional
|
|
6
|
+
|
|
7
|
+
import tqdm
|
|
8
|
+
from pydantic import StrictStr
|
|
9
|
+
|
|
10
|
+
from immich.client.api.download_api import DownloadApi
|
|
11
|
+
from immich.client.models.asset_ids_dto import AssetIdsDto
|
|
12
|
+
from immich.client.models.download_info_dto import DownloadInfoDto
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class DownloadApiWrapped(DownloadApi):
|
|
16
|
+
async def download_archive_to_file(
|
|
17
|
+
self,
|
|
18
|
+
download_info: DownloadInfoDto,
|
|
19
|
+
out_dir: Path,
|
|
20
|
+
key: Optional[StrictStr] = None,
|
|
21
|
+
slug: Optional[StrictStr] = None,
|
|
22
|
+
show_progress_bars: bool = True,
|
|
23
|
+
**kwargs: Any,
|
|
24
|
+
) -> list[Path]:
|
|
25
|
+
"""
|
|
26
|
+
Download one or more asset archives and save them to ZIP files.
|
|
27
|
+
|
|
28
|
+
Note: This method intentionally downloads archives **sequentially** (not in parallel) by default.
|
|
29
|
+
Immich has to build ZIP archives server-side; parallelizing many archive requests can put significant
|
|
30
|
+
CPU/disk load on the Immich server and may lead to timeouts or degraded performance for other users.
|
|
31
|
+
If you choose to parallelize, keep concurrency low and do so at your own risk.
|
|
32
|
+
|
|
33
|
+
:param download_info: The download info (two-step flow; downloads all archives returned by `get_download_info`).
|
|
34
|
+
:param out_dir: The directory to write the ZIP archive to.
|
|
35
|
+
:param key: Public share key (the last path segment of a public share URL, i.e. `/share/<key>`). Allows access without authentication. Typically you pass either `key` or `slug`.
|
|
36
|
+
:param slug: Public share slug for custom share URLs (the last path segment of `/s/<slug>`). Allows access without authentication. Typically you pass either `slug` or `key`.
|
|
37
|
+
:param show_progress_bars: Whether to show tqdm progress bars (per-archive bytes + overall archive count).
|
|
38
|
+
:param kwargs: Additional arguments to pass to the underlying SDK calls.
|
|
39
|
+
|
|
40
|
+
:return: The list of paths to the downloaded archives.
|
|
41
|
+
|
|
42
|
+
For exact request/response behavior, inspect `DownloadApi.download_archive_without_preload_content`
|
|
43
|
+
in the generated client.
|
|
44
|
+
"""
|
|
45
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
46
|
+
|
|
47
|
+
# Normalize to a list of archive requests.
|
|
48
|
+
info = await super().get_download_info(
|
|
49
|
+
download_info, key=key, slug=slug, **kwargs
|
|
50
|
+
)
|
|
51
|
+
archive_requests: list[tuple[AssetIdsDto, int]] = [
|
|
52
|
+
(AssetIdsDto(asset_ids=archive.asset_ids), int(archive.size))
|
|
53
|
+
for archive in info.archives
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
out_paths: list[Path] = []
|
|
57
|
+
|
|
58
|
+
archives_pbar = tqdm.tqdm(
|
|
59
|
+
total=len(archive_requests),
|
|
60
|
+
desc="archives",
|
|
61
|
+
unit="archive",
|
|
62
|
+
position=0,
|
|
63
|
+
leave=True,
|
|
64
|
+
dynamic_ncols=True,
|
|
65
|
+
disable=not show_progress_bars,
|
|
66
|
+
)
|
|
67
|
+
try:
|
|
68
|
+
for asset_ids_dto, expected_size in archive_requests:
|
|
69
|
+
resp = await super().download_archive_without_preload_content(
|
|
70
|
+
asset_ids_dto=asset_ids_dto,
|
|
71
|
+
key=key,
|
|
72
|
+
slug=slug,
|
|
73
|
+
**kwargs,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
out_path = out_dir / f"archive-{uuid.uuid4()}.zip"
|
|
77
|
+
temp_path = out_path.with_suffix(out_path.suffix + ".part")
|
|
78
|
+
|
|
79
|
+
bytes_pbar = tqdm.tqdm(
|
|
80
|
+
total=expected_size or None,
|
|
81
|
+
unit="B",
|
|
82
|
+
unit_scale=True,
|
|
83
|
+
desc=str(out_path.name),
|
|
84
|
+
position=1,
|
|
85
|
+
leave=False,
|
|
86
|
+
dynamic_ncols=True,
|
|
87
|
+
disable=not show_progress_bars,
|
|
88
|
+
)
|
|
89
|
+
try:
|
|
90
|
+
async with resp:
|
|
91
|
+
with temp_path.open("wb") as f:
|
|
92
|
+
async for chunk in resp.content.iter_chunked(1024 * 1024):
|
|
93
|
+
if not chunk:
|
|
94
|
+
continue
|
|
95
|
+
f.write(chunk)
|
|
96
|
+
bytes_pbar.update(len(chunk))
|
|
97
|
+
except Exception:
|
|
98
|
+
# Clean up partial download on error
|
|
99
|
+
if temp_path.exists():
|
|
100
|
+
temp_path.unlink()
|
|
101
|
+
raise
|
|
102
|
+
finally:
|
|
103
|
+
bytes_pbar.close()
|
|
104
|
+
|
|
105
|
+
temp_path.replace(out_path)
|
|
106
|
+
out_paths.append(out_path)
|
|
107
|
+
archives_pbar.update(1)
|
|
108
|
+
finally:
|
|
109
|
+
archives_pbar.close()
|
|
110
|
+
|
|
111
|
+
return out_paths
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any, Optional
|
|
5
|
+
from uuid import UUID
|
|
6
|
+
|
|
7
|
+
from immich.client.api.users_api import UsersApi
|
|
8
|
+
from immich.utils import resolve_output_filename
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class UsersApiWrapped(UsersApi):
|
|
12
|
+
async def get_profile_image_to_file(
|
|
13
|
+
self,
|
|
14
|
+
id: UUID,
|
|
15
|
+
out_dir: Path,
|
|
16
|
+
filename: Optional[str] = None,
|
|
17
|
+
**kwargs: Any,
|
|
18
|
+
) -> Path:
|
|
19
|
+
"""
|
|
20
|
+
Download a user's profile image and save it to a file.
|
|
21
|
+
|
|
22
|
+
:param id: The user ID.
|
|
23
|
+
:param out_dir: The directory to write the profile image to.
|
|
24
|
+
:param filename: The filename to use. If not provided, we try to derive it from the headers
|
|
25
|
+
or default to "profile-" + user_id.
|
|
26
|
+
:param kwargs: Additional arguments to pass to the `get_profile_image_with_http_info` method.
|
|
27
|
+
|
|
28
|
+
For exact request/response behavior, inspect `UsersApi.get_profile_image_with_http_info`
|
|
29
|
+
in the generated client.
|
|
30
|
+
"""
|
|
31
|
+
resp = await super().get_profile_image_with_http_info(id=id, **kwargs)
|
|
32
|
+
name = resolve_output_filename(
|
|
33
|
+
resp.headers,
|
|
34
|
+
name=filename,
|
|
35
|
+
default_base=f"profile-{id}",
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
39
|
+
out_path = out_dir / name
|
|
40
|
+
out_path.write_bytes(bytes(resp.data))
|
|
41
|
+
return out_path
|
immich/py.typed
ADDED
|
File without changes
|