From a74db5505e5b7d7861f3bca6f1fbf0d4f53a64fb Mon Sep 17 00:00:00 2001 From: algolia-bot Date: Tue, 24 Sep 2024 12:09:54 +0000 Subject: [PATCH] fix(python): update deserialization templates and typing issues (generated) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/algolia/api-clients-automation/pull/3780 Co-authored-by: algolia-bot Co-authored-by: Clément Vannicatte --- algoliasearch/abtesting/client.py | 5 +- algoliasearch/abtesting/models/ab_test.py | 119 +-- .../abtesting/models/ab_test_configuration.py | 68 +- .../abtesting/models/ab_test_response.py | 52 +- .../abtesting/models/ab_tests_variant.py | 54 +- .../models/ab_tests_variant_search_params.py | 57 +- .../abtesting/models/add_ab_tests_request.py | 71 +- .../abtesting/models/add_ab_tests_variant.py | 26 +- algoliasearch/abtesting/models/currency.py | 57 +- algoliasearch/abtesting/models/effect.py | 3 + .../abtesting/models/empty_search.py | 34 +- .../abtesting/models/empty_search_filter.py | 47 +- algoliasearch/abtesting/models/error_base.py | 48 +- .../abtesting/models/filter_effects.py | 54 +- .../models/list_ab_tests_response.py | 57 +- .../models/minimum_detectable_effect.py | 49 +- algoliasearch/abtesting/models/outliers.py | 34 +- .../abtesting/models/outliers_filter.py | 47 +- .../models/schedule_ab_test_response.py | 35 +- .../models/schedule_ab_tests_request.py | 78 +- algoliasearch/abtesting/models/status.py | 3 + algoliasearch/abtesting/models/variant.py | 203 ++--- algoliasearch/analytics/client.py | 5 +- .../analytics/models/click_position.py | 49 +- .../analytics/models/currency_code.py | 41 +- .../models/daily_add_to_cart_rates.py | 68 +- .../analytics/models/daily_average_clicks.py | 60 +- .../models/daily_click_through_rates.py | 67 +- .../models/daily_conversion_rates.py | 67 +- .../analytics/models/daily_no_click_rates.py | 65 +- .../models/daily_no_results_rates.py | 62 +- .../analytics/models/daily_purchase_rates.py | 67 +- .../analytics/models/daily_revenue.py | 64 +- .../analytics/models/daily_searches.py | 38 +- .../models/daily_searches_no_clicks.py | 51 +- .../models/daily_searches_no_results.py | 52 +- algoliasearch/analytics/models/daily_users.py | 38 +- algoliasearch/analytics/models/direction.py | 1 + algoliasearch/analytics/models/error_base.py | 48 +- .../models/get_add_to_cart_rate_response.py | 80 +- .../get_average_click_position_response.py | 72 +- .../models/get_click_positions_response.py | 57 +- .../models/get_click_through_rate_response.py | 84 +- .../models/get_conversion_rate_response.py | 82 +- .../models/get_no_click_rate_response.py | 77 +- .../models/get_no_results_rate_response.py | 74 +- .../models/get_purchase_rate_response.py | 79 +- algoliasearch/analytics/models/get_revenue.py | 75 +- .../models/get_searches_count_response.py | 55 +- .../models/get_searches_no_clicks_response.py | 54 +- .../get_searches_no_results_response.py | 54 +- .../analytics/models/get_status_response.py | 34 +- .../models/get_top_countries_response.py | 49 +- .../models/get_top_filter_attribute.py | 38 +- .../get_top_filter_attributes_response.py | 54 +- .../models/get_top_filter_for_attribute.py | 50 +- .../get_top_filter_for_attribute_response.py | 54 +- .../get_top_filters_no_results_response.py | 52 +- .../get_top_filters_no_results_value.py | 46 +- .../get_top_filters_no_results_values.py | 60 +- .../analytics/models/get_top_hits_response.py | 44 +- .../models/get_top_searches_response.py | 44 +- .../models/get_users_count_response.py | 55 +- algoliasearch/analytics/models/operator.py | 6 + algoliasearch/analytics/models/order_by.py | 3 + algoliasearch/analytics/models/top_country.py | 38 +- algoliasearch/analytics/models/top_hit.py | 38 +- .../models/top_hit_with_analytics.py | 90 +- .../models/top_hit_with_revenue_analytics.py | 152 +--- .../analytics/models/top_hits_response.py | 49 +- .../top_hits_response_with_analytics.py | 51 +- ...op_hits_response_with_revenue_analytics.py | 54 +- algoliasearch/analytics/models/top_search.py | 45 +- .../models/top_search_with_analytics.py | 130 +-- .../top_search_with_revenue_analytics.py | 193 ++-- .../analytics/models/top_searches_response.py | 51 +- .../top_searches_response_with_analytics.py | 54 +- ...earches_response_with_revenue_analytics.py | 57 +- algoliasearch/ingestion/client.py | 5 +- algoliasearch/ingestion/models/action.py | 6 + algoliasearch/ingestion/models/action_type.py | 3 + .../ingestion/models/auth_algolia.py | 41 +- .../ingestion/models/auth_algolia_insights.py | 41 +- .../models/auth_algolia_insights_partial.py | 42 +- .../ingestion/models/auth_algolia_partial.py | 42 +- .../ingestion/models/auth_api_key.py | 35 +- .../ingestion/models/auth_api_key_partial.py | 33 +- algoliasearch/ingestion/models/auth_basic.py | 40 +- .../ingestion/models/auth_basic_partial.py | 38 +- .../models/auth_google_service_account.py | 43 +- .../auth_google_service_account_partial.py | 44 +- algoliasearch/ingestion/models/auth_input.py | 55 +- .../ingestion/models/auth_input_partial.py | 57 +- algoliasearch/ingestion/models/auth_o_auth.py | 49 +- .../ingestion/models/auth_o_auth_partial.py | 52 +- .../ingestion/models/authentication.py | 77 +- .../ingestion/models/authentication_create.py | 54 +- .../models/authentication_create_response.py | 50 +- .../ingestion/models/authentication_search.py | 32 +- .../models/authentication_sort_keys.py | 4 + .../ingestion/models/authentication_type.py | 5 + .../ingestion/models/authentication_update.py | 58 +- .../models/authentication_update_response.py | 50 +- .../ingestion/models/big_commerce_channel.py | 38 +- .../models/big_commerce_metafield.py | 38 +- .../ingestion/models/big_query_data_type.py | 1 + .../models/commercetools_custom_fields.py | 49 +- .../ingestion/models/delete_response.py | 35 +- algoliasearch/ingestion/models/destination.py | 84 +- .../ingestion/models/destination_create.py | 63 +- .../models/destination_create_response.py | 50 +- .../models/destination_index_name.py | 48 +- .../ingestion/models/destination_input.py | 21 +- .../ingestion/models/destination_search.py | 32 +- .../ingestion/models/destination_sort_keys.py | 3 + .../ingestion/models/destination_type.py | 1 + .../ingestion/models/destination_update.py | 65 +- .../models/destination_update_response.py | 50 +- .../ingestion/models/docker_image_type.py | 2 + .../ingestion/models/docker_registry.py | 1 + .../ingestion/models/docker_streams.py | 47 +- .../ingestion/models/docker_streams_input.py | 50 +- .../models/docker_streams_sync_mode.py | 1 + algoliasearch/ingestion/models/entity_type.py | 1 + algoliasearch/ingestion/models/error_base.py | 48 +- algoliasearch/ingestion/models/event.py | 79 +- .../ingestion/models/event_sort_keys.py | 2 + .../ingestion/models/event_status.py | 5 + algoliasearch/ingestion/models/event_type.py | 3 + .../models/list_authentications_response.py | 67 +- .../models/list_destinations_response.py | 64 +- .../ingestion/models/list_events_response.py | 76 +- .../ingestion/models/list_sources_response.py | 64 +- .../ingestion/models/list_tasks_response.py | 64 +- .../models/list_tasks_response_v1.py | 64 +- .../models/list_transformations_response.py | 67 +- .../models/mapping_field_directive.py | 40 +- .../ingestion/models/mapping_input.py | 54 +- .../ingestion/models/mapping_kit_action.py | 65 +- .../ingestion/models/mapping_type_csv.py | 4 + algoliasearch/ingestion/models/method_type.py | 1 + .../ingestion/models/on_demand_trigger.py | 41 +- .../models/on_demand_trigger_input.py | 34 +- algoliasearch/ingestion/models/order_keys.py | 1 + algoliasearch/ingestion/models/pagination.py | 59 +- algoliasearch/ingestion/models/platform.py | 2 + .../ingestion/models/platform_with_none.py | 24 +- .../ingestion/models/push_task_payload.py | 54 +- .../ingestion/models/push_task_records.py | 51 +- algoliasearch/ingestion/models/record_type.py | 1 + algoliasearch/ingestion/models/run.py | 113 +-- .../ingestion/models/run_list_response.py | 76 +- algoliasearch/ingestion/models/run_outcome.py | 2 + .../ingestion/models/run_progress.py | 37 +- .../ingestion/models/run_reason_code.py | 6 + .../ingestion/models/run_response.py | 42 +- .../ingestion/models/run_sort_keys.py | 2 + .../ingestion/models/run_source_payload.py | 56 +- .../ingestion/models/run_source_response.py | 46 +- algoliasearch/ingestion/models/run_status.py | 4 + algoliasearch/ingestion/models/run_type.py | 4 + .../ingestion/models/schedule_trigger.py | 55 +- .../models/schedule_trigger_input.py | 37 +- .../ingestion/models/shopify_input.py | 67 +- .../ingestion/models/shopify_market.py | 42 +- .../ingestion/models/shopify_metafield.py | 42 +- algoliasearch/ingestion/models/sort_keys.py | 3 + algoliasearch/ingestion/models/source.py | 80 +- .../ingestion/models/source_big_commerce.py | 97 +- .../ingestion/models/source_big_query.py | 76 +- .../ingestion/models/source_commercetools.py | 69 +- .../ingestion/models/source_create.py | 60 +- .../models/source_create_response.py | 50 +- algoliasearch/ingestion/models/source_csv.py | 69 +- .../ingestion/models/source_docker.py | 52 +- .../models/source_ga4_big_query_export.py | 54 +- .../ingestion/models/source_input.py | 65 +- algoliasearch/ingestion/models/source_json.py | 48 +- .../ingestion/models/source_search.py | 32 +- .../ingestion/models/source_shopify.py | 42 +- .../ingestion/models/source_sort_keys.py | 3 + algoliasearch/ingestion/models/source_type.py | 9 + .../ingestion/models/source_update.py | 58 +- .../models/source_update_commercetools.py | 66 +- .../ingestion/models/source_update_docker.py | 50 +- .../ingestion/models/source_update_input.py | 60 +- .../models/source_update_response.py | 50 +- .../ingestion/models/source_update_shopify.py | 33 +- .../ingestion/models/source_watch_response.py | 73 +- .../ingestion/models/streaming_input.py | 46 +- .../ingestion/models/streaming_trigger.py | 34 +- .../ingestion/models/subscription_trigger.py | 34 +- algoliasearch/ingestion/models/task.py | 126 +-- algoliasearch/ingestion/models/task_create.py | 92 +- .../ingestion/models/task_create_response.py | 42 +- .../ingestion/models/task_create_trigger.py | 45 +- .../ingestion/models/task_create_v1.py | 100 +-- algoliasearch/ingestion/models/task_input.py | 31 +- algoliasearch/ingestion/models/task_search.py | 32 +- .../ingestion/models/task_sort_keys.py | 4 + algoliasearch/ingestion/models/task_update.py | 76 +- .../ingestion/models/task_update_response.py | 42 +- .../ingestion/models/task_update_v1.py | 84 +- algoliasearch/ingestion/models/task_v1.py | 118 +-- .../ingestion/models/transformation.py | 77 +- .../ingestion/models/transformation_create.py | 56 +- .../models/transformation_create_response.py | 46 +- .../ingestion/models/transformation_error.py | 40 +- .../ingestion/models/transformation_search.py | 32 +- .../ingestion/models/transformation_try.py | 61 +- .../models/transformation_try_response.py | 48 +- .../models/transformation_update_response.py | 46 +- algoliasearch/ingestion/models/trigger.py | 45 +- .../ingestion/models/trigger_type.py | 3 + .../ingestion/models/trigger_update_input.py | 33 +- algoliasearch/ingestion/models/window.py | 44 +- algoliasearch/insights/client.py | 5 +- .../models/added_to_cart_object_ids.py | 128 +-- .../added_to_cart_object_ids_after_search.py | 138 +-- .../insights/models/clicked_filters.py | 83 +- .../insights/models/clicked_object_ids.py | 84 +- .../models/clicked_object_ids_after_search.py | 97 +- .../insights/models/converted_filters.py | 83 +- .../insights/models/converted_object_ids.py | 84 +- .../converted_object_ids_after_search.py | 91 +- algoliasearch/insights/models/discount.py | 31 +- algoliasearch/insights/models/error_base.py | 48 +- algoliasearch/insights/models/events_items.py | 93 +- .../insights/models/events_response.py | 40 +- .../insights/models/insights_events.py | 55 +- algoliasearch/insights/models/object_data.py | 63 +- .../models/object_data_after_search.py | 77 +- algoliasearch/insights/models/price.py | 31 +- .../insights/models/purchased_object_ids.py | 128 +-- .../purchased_object_ids_after_search.py | 130 +-- algoliasearch/insights/models/value.py | 31 +- .../insights/models/viewed_filters.py | 83 +- .../insights/models/viewed_object_ids.py | 84 +- algoliasearch/monitoring/client.py | 5 +- algoliasearch/monitoring/models/error_base.py | 48 +- algoliasearch/monitoring/models/incident.py | 39 +- .../monitoring/models/incident_entry.py | 49 +- .../monitoring/models/incidents_response.py | 60 +- .../monitoring/models/indexing_metric.py | 60 +- .../models/indexing_time_response.py | 44 +- .../models/infrastructure_response.py | 44 +- .../monitoring/models/inventory_response.py | 48 +- .../monitoring/models/latency_metric.py | 58 +- .../monitoring/models/latency_response.py | 44 +- algoliasearch/monitoring/models/metric.py | 5 + algoliasearch/monitoring/models/metrics.py | 174 ++-- algoliasearch/monitoring/models/period.py | 4 + .../monitoring/models/probes_metric.py | 37 +- algoliasearch/monitoring/models/region.py | 14 + algoliasearch/monitoring/models/server.py | 67 +- algoliasearch/monitoring/models/status.py | 3 + .../monitoring/models/status_response.py | 34 +- algoliasearch/monitoring/models/time_entry.py | 37 +- algoliasearch/personalization/client.py | 5 +- .../models/delete_user_profile_response.py | 44 +- .../personalization/models/error_base.py | 48 +- .../personalization/models/event_scoring.py | 44 +- .../personalization/models/event_type.py | 2 + .../personalization/models/facet_scoring.py | 40 +- .../models/get_user_token_response.py | 53 +- .../models/personalization_strategy_params.py | 85 +- .../set_personalization_strategy_response.py | 33 +- algoliasearch/query_suggestions/client.py | 5 +- .../query_suggestions/models/base_response.py | 38 +- .../query_suggestions/models/config_status.py | 71 +- .../query_suggestions/models/configuration.py | 89 +- .../models/configuration_response.py | 101 +-- .../models/configuration_with_index.py | 96 +- .../query_suggestions/models/error_base.py | 48 +- .../query_suggestions/models/facet.py | 38 +- .../query_suggestions/models/languages.py | 36 +- .../query_suggestions/models/log_file.py | 56 +- .../query_suggestions/models/log_level.py | 2 + .../query_suggestions/models/source_index.py | 93 +- algoliasearch/recommend/client.py | 5 +- .../models/advanced_syntax_features.py | 1 + .../recommend/models/alternatives_as_exact.py | 2 + .../recommend/models/around_precision.py | 27 +- .../recommend/models/around_radius.py | 31 +- .../recommend/models/auto_facet_filter.py | 39 +- .../recommend/models/boolean_string.py | 1 + .../recommend/models/bought_together_query.py | 83 +- algoliasearch/recommend/models/condition.py | 46 +- algoliasearch/recommend/models/consequence.py | 97 +- .../recommend/models/deleted_at_response.py | 44 +- algoliasearch/recommend/models/distinct.py | 36 +- algoliasearch/recommend/models/error_base.py | 48 +- .../models/exact_on_single_word_query.py | 2 + algoliasearch/recommend/models/exhaustive.py | 70 +- .../recommend/models/facet_filters.py | 24 +- .../recommend/models/facet_ordering.py | 66 +- algoliasearch/recommend/models/facet_stats.py | 57 +- .../recommend/models/fallback_params.py | 831 ++++++------------ .../models/get_recommend_task_response.py | 34 +- .../models/get_recommendations_params.py | 54 +- .../models/get_recommendations_response.py | 53 +- .../models/hide_consequence_object.py | 33 +- .../recommend/models/highlight_result.py | 44 +- .../models/highlight_result_option.py | 54 +- .../recommend/models/ignore_plurals.py | 35 +- .../recommend/models/index_settings_facets.py | 34 +- .../recommend/models/looking_similar_query.py | 95 +- algoliasearch/recommend/models/match_level.py | 2 + .../recommend/models/matched_geo_location.py | 52 +- .../recommend/models/numeric_filters.py | 24 +- .../recommend/models/optional_filters.py | 24 +- .../recommend/models/params_consequence.py | 69 +- .../recommend/models/personalization.py | 49 +- .../models/promote_consequence_object.py | 45 +- algoliasearch/recommend/models/query_type.py | 2 + algoliasearch/recommend/models/range.py | 41 +- .../recommend/models/ranking_info.py | 136 +-- .../models/re_ranking_apply_filter.py | 26 +- .../recommend/models/recommend_hit.py | 139 +-- .../recommend/models/recommend_models.py | 3 + .../recommend/models/recommend_rule.py | 92 +- .../models/recommend_search_params.py | 831 ++++++------------ .../recommend/models/recommendations_hit.py | 26 +- .../models/recommendations_request.py | 55 +- .../models/recommendations_results.py | 315 +++---- .../models/recommended_for_you_query.py | 89 +- algoliasearch/recommend/models/redirect.py | 53 +- .../models/redirect_rule_index_data.py | 32 +- .../models/redirect_rule_index_metadata.py | 62 +- .../recommend/models/redirect_url.py | 30 +- .../recommend/models/related_query.py | 95 +- .../recommend/models/remove_stop_words.py | 30 +- .../models/remove_words_if_no_results.py | 3 + .../recommend/models/rendering_content.py | 54 +- .../recommend/models/rule_metadata.py | 35 +- .../models/search_recommend_rules_params.py | 88 +- .../models/search_recommend_rules_response.py | 73 +- .../recommend/models/snippet_result.py | 44 +- .../recommend/models/snippet_result_option.py | 39 +- .../recommend/models/sort_remaining_by.py | 2 + .../recommend/models/supported_language.py | 67 ++ algoliasearch/recommend/models/tag_filters.py | 24 +- algoliasearch/recommend/models/task_status.py | 1 + .../recommend/models/trending_facet_hit.py | 58 +- .../recommend/models/trending_facets_query.py | 96 +- .../recommend/models/trending_items_query.py | 105 +-- .../recommend/models/typo_tolerance.py | 27 +- .../recommend/models/typo_tolerance_enum.py | 1 + algoliasearch/recommend/models/value.py | 47 +- algoliasearch/search/client.py | 5 +- algoliasearch/search/models/acl.py | 14 + algoliasearch/search/models/action.py | 6 + .../search/models/add_api_key_response.py | 41 +- .../search/models/advanced_syntax_features.py | 1 + .../search/models/alternatives_as_exact.py | 2 + algoliasearch/search/models/anchoring.py | 3 + algoliasearch/search/models/api_key.py | 91 +- .../search/models/api_key_operation.py | 2 + .../search/models/around_precision.py | 27 +- algoliasearch/search/models/around_radius.py | 31 +- .../search/models/assign_user_id_params.py | 33 +- .../search/models/attribute_to_update.py | 24 +- .../search/models/automatic_facet_filter.py | 51 +- .../search/models/automatic_facet_filters.py | 26 +- .../models/batch_assign_user_ids_params.py | 38 +- .../models/batch_dictionary_entries_params.py | 67 +- .../batch_dictionary_entries_request.py | 50 +- algoliasearch/search/models/batch_params.py | 53 +- algoliasearch/search/models/batch_request.py | 39 +- algoliasearch/search/models/batch_response.py | 43 +- .../search/models/batch_write_params.py | 50 +- algoliasearch/search/models/boolean_string.py | 1 + algoliasearch/search/models/browse_params.py | 26 +- .../search/models/browse_params_object.py | 729 ++++++--------- .../search/models/browse_response.py | 335 +++---- .../search/models/built_in_operation.py | 46 +- .../search/models/built_in_operation_type.py | 6 + .../search/models/built_in_operation_value.py | 37 +- algoliasearch/search/models/condition.py | 75 +- algoliasearch/search/models/consequence.py | 107 +-- .../search/models/consequence_hide.py | 35 +- .../search/models/consequence_params.py | 760 ++++++---------- .../search/models/consequence_query.py | 24 +- .../search/models/consequence_query_object.py | 57 +- .../search/models/created_at_response.py | 36 +- .../search/models/delete_api_key_response.py | 36 +- .../search/models/delete_by_params.py | 128 +-- .../search/models/delete_source_response.py | 36 +- .../search/models/deleted_at_response.py | 44 +- .../search/models/dictionary_action.py | 1 + .../search/models/dictionary_entry.py | 95 +- .../search/models/dictionary_entry_state.py | 1 + .../search/models/dictionary_entry_type.py | 1 + .../search/models/dictionary_language.py | 35 +- .../models/dictionary_settings_params.py | 42 +- .../search/models/dictionary_type.py | 2 + algoliasearch/search/models/distinct.py | 36 +- algoliasearch/search/models/edit.py | 49 +- algoliasearch/search/models/edit_type.py | 1 + algoliasearch/search/models/error_base.py | 48 +- .../models/exact_on_single_word_query.py | 2 + algoliasearch/search/models/exhaustive.py | 70 +- algoliasearch/search/models/facet_filters.py | 24 +- algoliasearch/search/models/facet_hits.py | 49 +- algoliasearch/search/models/facet_ordering.py | 64 +- algoliasearch/search/models/facet_stats.py | 57 +- algoliasearch/search/models/facets.py | 34 +- algoliasearch/search/models/fetched_index.py | 106 +-- .../search/models/get_api_key_response.py | 102 +-- .../get_dictionary_settings_response.py | 42 +- .../search/models/get_logs_response.py | 50 +- .../search/models/get_objects_params.py | 53 +- .../search/models/get_objects_request.py | 51 +- .../search/models/get_objects_response.py | 31 +- .../search/models/get_task_response.py | 34 +- .../models/get_top_user_ids_response.py | 34 +- .../models/has_pending_mappings_response.py | 41 +- .../search/models/highlight_result.py | 44 +- .../search/models/highlight_result_option.py | 54 +- algoliasearch/search/models/hit.py | 127 +-- algoliasearch/search/models/ignore_plurals.py | 35 +- algoliasearch/search/models/index_settings.py | 570 +++++------- algoliasearch/search/models/languages.py | 72 +- .../search/models/list_api_keys_response.py | 49 +- .../search/models/list_clusters_response.py | 36 +- .../search/models/list_indices_response.py | 57 +- .../search/models/list_user_ids_response.py | 49 +- algoliasearch/search/models/log.py | 132 +-- algoliasearch/search/models/log_query.py | 49 +- algoliasearch/search/models/log_type.py | 3 + algoliasearch/search/models/match_level.py | 2 + .../search/models/matched_geo_location.py | 52 +- algoliasearch/search/models/mode.py | 1 + .../search/models/multiple_batch_request.py | 49 +- .../search/models/multiple_batch_response.py | 42 +- .../search/models/numeric_filters.py | 24 +- .../search/models/operation_index_params.py | 48 +- algoliasearch/search/models/operation_type.py | 1 + .../search/models/optional_filters.py | 24 +- .../search/models/personalization.py | 49 +- algoliasearch/search/models/promote.py | 26 +- .../search/models/promote_object_id.py | 42 +- .../search/models/promote_object_ids.py | 47 +- algoliasearch/search/models/query_type.py | 2 + algoliasearch/search/models/range.py | 41 +- algoliasearch/search/models/ranking_info.py | 136 +-- .../search/models/re_ranking_apply_filter.py | 26 +- algoliasearch/search/models/redirect.py | 53 +- .../search/models/redirect_rule_index_data.py | 32 +- .../models/redirect_rule_index_metadata.py | 62 +- algoliasearch/search/models/redirect_url.py | 30 +- .../search/models/remove_stop_words.py | 30 +- .../search/models/remove_user_id_response.py | 36 +- .../models/remove_words_if_no_results.py | 3 + .../search/models/rendering_content.py | 54 +- .../models/replace_all_objects_response.py | 78 +- .../search/models/replace_source_response.py | 36 +- algoliasearch/search/models/rule.py | 112 +-- .../search/models/save_object_response.py | 51 +- .../search/models/save_synonym_response.py | 51 +- algoliasearch/search/models/scope_type.py | 2 + .../search_dictionary_entries_params.py | 56 +- .../search_dictionary_entries_response.py | 73 +- .../models/search_for_facet_values_request.py | 57 +- .../search_for_facet_values_response.py | 66 +- .../search/models/search_for_facets.py | 750 ++++++---------- .../search/models/search_for_hits.py | 738 ++++++---------- .../search/models/search_method_params.py | 52 +- algoliasearch/search/models/search_params.py | 26 +- .../search/models/search_params_object.py | 722 ++++++--------- .../search/models/search_params_string.py | 33 +- algoliasearch/search/models/search_query.py | 26 +- .../search/models/search_response.py | 377 +++----- .../search/models/search_responses.py | 50 +- algoliasearch/search/models/search_result.py | 28 +- .../search/models/search_rules_params.py | 72 +- .../search/models/search_rules_response.py | 65 +- .../search/models/search_strategy.py | 1 + .../search/models/search_synonyms_params.py | 56 +- .../search/models/search_synonyms_response.py | 69 +- .../search/models/search_user_ids_params.py | 59 +- .../search/models/search_user_ids_response.py | 78 +- .../models/secured_api_key_restrictions.py | 81 +- .../search/models/semantic_search.py | 35 +- .../search/models/settings_response.py | 577 +++++------- algoliasearch/search/models/snippet_result.py | 44 +- .../search/models/snippet_result_option.py | 39 +- .../search/models/sort_remaining_by.py | 2 + algoliasearch/search/models/source.py | 38 +- .../search/models/standard_entries.py | 52 +- .../search/models/supported_language.py | 67 ++ algoliasearch/search/models/synonym_hit.py | 82 +- algoliasearch/search/models/synonym_type.py | 4 + algoliasearch/search/models/tag_filters.py | 24 +- algoliasearch/search/models/task_status.py | 1 + algoliasearch/search/models/time_range.py | 41 +- algoliasearch/search/models/typo_tolerance.py | 27 +- .../search/models/typo_tolerance_enum.py | 1 + .../search/models/update_api_key_response.py | 41 +- .../search/models/updated_at_response.py | 44 +- .../updated_at_with_object_id_response.py | 53 +- .../search/models/updated_rule_response.py | 53 +- .../search/models/user_highlight_result.py | 54 +- algoliasearch/search/models/user_hit.py | 78 +- algoliasearch/search/models/user_id.py | 62 +- algoliasearch/search/models/value.py | 47 +- 506 files changed, 11395 insertions(+), 19530 deletions(-) diff --git a/algoliasearch/abtesting/client.py b/algoliasearch/abtesting/client.py index f43bd57b8..afee1dca3 100644 --- a/algoliasearch/abtesting/client.py +++ b/algoliasearch/abtesting/client.py @@ -12,11 +12,12 @@ from urllib.parse import quote from pydantic import Field, StrictInt, StrictStr +from typing_extensions import Annotated if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.abtesting.config import AbtestingConfig from algoliasearch.abtesting.models.ab_test import ABTest diff --git a/algoliasearch/abtesting/models/ab_test.py b/algoliasearch/abtesting/models/ab_test.py index ba5557d3e..f50884cb5 100644 --- a/algoliasearch/abtesting/models/ab_test.py +++ b/algoliasearch/abtesting/models/ab_test.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,83 +28,61 @@ class ABTest(BaseModel): ABTest """ - ab_test_id: StrictInt = Field( - description="Unique A/B test identifier.", alias="abTestID" - ) - click_significance: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, alias="clickSignificance" - ) - conversion_significance: Optional[Union[StrictFloat, StrictInt]] = Field( + ab_test_id: int = Field(alias="abTestID") + """ Unique A/B test identifier. """ + click_significance: Optional[float] = Field(default=None, alias="clickSignificance") + conversion_significance: Optional[float] = Field( default=None, alias="conversionSignificance" ) - add_to_cart_significance: Optional[Union[StrictFloat, StrictInt]] = Field( + add_to_cart_significance: Optional[float] = Field( default=None, alias="addToCartSignificance" ) - purchase_significance: Optional[Union[StrictFloat, StrictInt]] = Field( + purchase_significance: Optional[float] = Field( default=None, alias="purchaseSignificance" ) - revenue_significance: Optional[Dict[str, Union[StrictFloat, StrictInt]]] = Field( + revenue_significance: Optional[Dict[str, float]] = Field( default=None, alias="revenueSignificance" ) - updated_at: StrictStr = Field( - description="Date and time when the A/B test was last updated, in RFC 3339 format.", - alias="updatedAt", - ) - created_at: StrictStr = Field( - description="Date and time when the A/B test was created, in RFC 3339 format.", - alias="createdAt", - ) - end_at: StrictStr = Field( - description="End date and time of the A/B test, in RFC 3339 format.", - alias="endAt", - ) - name: StrictStr = Field(description="A/B test name.") - status: Status - variants: List[Variant] = Field( - description="A/B test variants. The first variant is your _control_ index, typically your production index. The second variant is an index with changed settings that you want to test against the control. " + updated_at: str = Field(alias="updatedAt") + """ Date and time when the A/B test was last updated, in RFC 3339 format. """ + created_at: str = Field(alias="createdAt") + """ Date and time when the A/B test was created, in RFC 3339 format. """ + end_at: str = Field(alias="endAt") + """ End date and time of the A/B test, in RFC 3339 format. """ + name: str = Field(alias="name") + """ A/B test name. """ + status: Status = Field(alias="status") + variants: List[Variant] = Field(alias="variants") + """ A/B test variants. The first variant is your _control_ index, typically your production index. The second variant is an index with changed settings that you want to test against the control. """ + configuration: Optional[ABTestConfiguration] = Field( + default=None, alias="configuration" ) - configuration: Optional[ABTestConfiguration] = None model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ABTest from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.variants: - for _item in self.variants: - if _item: - _items.append(_item.to_dict()) - _dict["variants"] = _items - if self.configuration: - _dict["configuration"] = self.configuration.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ABTest from a dict""" if obj is None: return None @@ -112,29 +90,16 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "abTestID": obj.get("abTestID"), - "clickSignificance": obj.get("clickSignificance"), - "conversionSignificance": obj.get("conversionSignificance"), - "addToCartSignificance": obj.get("addToCartSignificance"), - "purchaseSignificance": obj.get("purchaseSignificance"), - "revenueSignificance": obj.get("revenueSignificance"), - "updatedAt": obj.get("updatedAt"), - "createdAt": obj.get("createdAt"), - "endAt": obj.get("endAt"), - "name": obj.get("name"), - "status": obj.get("status"), - "variants": ( - [Variant.from_dict(_item) for _item in obj.get("variants")] - if obj.get("variants") is not None - else None - ), - "configuration": ( - ABTestConfiguration.from_dict(obj.get("configuration")) - if obj.get("configuration") is not None - else None - ), - } + obj["status"] = obj.get("status") + obj["variants"] = ( + [Variant.from_dict(_item) for _item in obj["variants"]] + if obj.get("variants") is not None + else None ) - return _obj + obj["configuration"] = ( + ABTestConfiguration.from_dict(obj["configuration"]) + if obj.get("configuration") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/ab_test_configuration.py b/algoliasearch/abtesting/models/ab_test_configuration.py index 669366f31..62b211f99 100644 --- a/algoliasearch/abtesting/models/ab_test_configuration.py +++ b/algoliasearch/abtesting/models/ab_test_configuration.py @@ -30,50 +30,37 @@ class ABTestConfiguration(BaseModel): A/B test configuration. """ - outliers: Outliers + outliers: Outliers = Field(alias="outliers") empty_search: Optional[EmptySearch] = Field(default=None, alias="emptySearch") minimum_detectable_effect: Optional[MinimumDetectableEffect] = Field( default=None, alias="minimumDetectableEffect" ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ABTestConfiguration from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.outliers: - _dict["outliers"] = self.outliers.to_dict() - if self.empty_search: - _dict["emptySearch"] = self.empty_search.to_dict() - if self.minimum_detectable_effect: - _dict["minimumDetectableEffect"] = self.minimum_detectable_effect.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ABTestConfiguration from a dict""" if obj is None: return None @@ -81,25 +68,20 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "outliers": ( - Outliers.from_dict(obj.get("outliers")) - if obj.get("outliers") is not None - else None - ), - "emptySearch": ( - EmptySearch.from_dict(obj.get("emptySearch")) - if obj.get("emptySearch") is not None - else None - ), - "minimumDetectableEffect": ( - MinimumDetectableEffect.from_dict( - obj.get("minimumDetectableEffect") - ) - if obj.get("minimumDetectableEffect") is not None - else None - ), - } + obj["outliers"] = ( + Outliers.from_dict(obj["outliers"]) + if obj.get("outliers") is not None + else None + ) + obj["emptySearch"] = ( + EmptySearch.from_dict(obj["emptySearch"]) + if obj.get("emptySearch") is not None + else None ) - return _obj + obj["minimumDetectableEffect"] = ( + MinimumDetectableEffect.from_dict(obj["minimumDetectableEffect"]) + if obj.get("minimumDetectableEffect") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/ab_test_response.py b/algoliasearch/abtesting/models/ab_test_response.py index 28015747b..ab977ff7c 100644 --- a/algoliasearch/abtesting/models/ab_test_response.py +++ b/algoliasearch/abtesting/models/ab_test_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,49 +23,38 @@ class ABTestResponse(BaseModel): ABTestResponse """ - index: StrictStr = Field( - description="Index name of the A/B test variant (case-sensitive)." - ) - ab_test_id: StrictInt = Field( - description="Unique A/B test identifier.", alias="abTestID" - ) - task_id: StrictInt = Field( - description="Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. ", - alias="taskID", - ) + index: str = Field(alias="index") + """ Index name of the A/B test variant (case-sensitive). """ + ab_test_id: int = Field(alias="abTestID") + """ Unique A/B test identifier. """ + task_id: int = Field(alias="taskID") + """ Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ABTestResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ABTestResponse from a dict""" if obj is None: return None @@ -73,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "index": obj.get("index"), - "abTestID": obj.get("abTestID"), - "taskID": obj.get("taskID"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/ab_tests_variant.py b/algoliasearch/abtesting/models/ab_tests_variant.py index 39f6c766b..2eb6901cc 100644 --- a/algoliasearch/abtesting/models/ab_tests_variant.py +++ b/algoliasearch/abtesting/models/ab_tests_variant.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class AbTestsVariant(BaseModel): @@ -23,49 +23,38 @@ class AbTestsVariant(BaseModel): AbTestsVariant """ - index: StrictStr = Field( - description="Index name of the A/B test variant (case-sensitive)." - ) - traffic_percentage: Annotated[int, Field(le=100, strict=True, ge=0)] = Field( - description="Percentage of search requests each variant receives.", - alias="trafficPercentage", - ) - description: Optional[StrictStr] = Field( - default=None, description="Description for this variant." - ) + index: str = Field(alias="index") + """ Index name of the A/B test variant (case-sensitive). """ + traffic_percentage: int = Field(alias="trafficPercentage") + """ Percentage of search requests each variant receives. """ + description: Optional[str] = Field(default=None, alias="description") + """ Description for this variant. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AbTestsVariant from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AbTestsVariant from a dict""" if obj is None: return None @@ -73,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "index": obj.get("index"), - "trafficPercentage": obj.get("trafficPercentage"), - "description": obj.get("description"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/ab_tests_variant_search_params.py b/algoliasearch/abtesting/models/ab_tests_variant_search_params.py index b8fedb253..518174154 100644 --- a/algoliasearch/abtesting/models/ab_tests_variant_search_params.py +++ b/algoliasearch/abtesting/models/ab_tests_variant_search_params.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class AbTestsVariantSearchParams(BaseModel): @@ -23,50 +23,39 @@ class AbTestsVariantSearchParams(BaseModel): AbTestsVariantSearchParams """ - index: StrictStr = Field( - description="Index name of the A/B test variant (case-sensitive)." - ) - traffic_percentage: Annotated[int, Field(le=100, strict=True, ge=0)] = Field( - description="Percentage of search requests each variant receives.", - alias="trafficPercentage", - ) - description: Optional[StrictStr] = Field( - default=None, description="Description for this variant." - ) - custom_search_parameters: Dict[str, Any] = Field(alias="customSearchParameters") + index: str = Field(alias="index") + """ Index name of the A/B test variant (case-sensitive). """ + traffic_percentage: int = Field(alias="trafficPercentage") + """ Percentage of search requests each variant receives. """ + description: Optional[str] = Field(default=None, alias="description") + """ Description for this variant. """ + custom_search_parameters: object = Field(alias="customSearchParameters") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AbTestsVariantSearchParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AbTestsVariantSearchParams from a dict""" if obj is None: return None @@ -74,12 +63,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "index": obj.get("index"), - "trafficPercentage": obj.get("trafficPercentage"), - "description": obj.get("description"), - "customSearchParameters": obj.get("customSearchParameters"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/add_ab_tests_request.py b/algoliasearch/abtesting/models/add_ab_tests_request.py index ac0668055..e6586885f 100644 --- a/algoliasearch/abtesting/models/add_ab_tests_request.py +++ b/algoliasearch/abtesting/models/add_ab_tests_request.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.abtesting.models.add_ab_tests_variant import AddABTestsVariant @@ -26,53 +26,38 @@ class AddABTestsRequest(BaseModel): AddABTestsRequest """ - name: StrictStr = Field(description="A/B test name.") - variants: Annotated[List[AddABTestsVariant], Field(min_length=2, max_length=2)] = ( - Field(description="A/B test variants.") - ) - end_at: StrictStr = Field( - description="End date and time of the A/B test, in RFC 3339 format.", - alias="endAt", - ) + name: str = Field(alias="name") + """ A/B test name. """ + variants: List[AddABTestsVariant] = Field(alias="variants") + """ A/B test variants. """ + end_at: str = Field(alias="endAt") + """ End date and time of the A/B test, in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AddABTestsRequest from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.variants: - for _item in self.variants: - if _item: - _items.append(_item.to_dict()) - _dict["variants"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AddABTestsRequest from a dict""" if obj is None: return None @@ -80,18 +65,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "name": obj.get("name"), - "variants": ( - [ - AddABTestsVariant.from_dict(_item) - for _item in obj.get("variants") - ] - if obj.get("variants") is not None - else None - ), - "endAt": obj.get("endAt"), - } + obj["variants"] = ( + [AddABTestsVariant.from_dict(_item) for _item in obj["variants"]] + if obj.get("variants") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/add_ab_tests_variant.py b/algoliasearch/abtesting/models/add_ab_tests_variant.py index 4f4967395..3f506ca96 100644 --- a/algoliasearch/abtesting/models/add_ab_tests_variant.py +++ b/algoliasearch/abtesting/models/add_ab_tests_variant.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -29,9 +29,12 @@ class AddABTestsVariant(BaseModel): AddABTestsVariant """ - oneof_schema_1_validator: Optional[AbTestsVariant] = None - oneof_schema_2_validator: Optional[AbTestsVariantSearchParams] = None + oneof_schema_1_validator: Optional[AbTestsVariant] = Field(default=None) + + oneof_schema_2_validator: Optional[AbTestsVariantSearchParams] = Field(default=None) + actual_instance: Optional[Union[AbTestsVariant, AbTestsVariantSearchParams]] = None + one_of_schemas: Set[str] = {"AbTestsVariant", "AbTestsVariantSearchParams"} def __init__(self, *args, **kwargs) -> None: if args: @@ -57,7 +60,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of AddABTestsVariant from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -89,17 +93,23 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[Union[Dict[str, Any], AbTestsVariant, AbTestsVariantSearchParams]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/abtesting/models/currency.py b/algoliasearch/abtesting/models/currency.py index 95ae88f65..8659a9fef 100644 --- a/algoliasearch/abtesting/models/currency.py +++ b/algoliasearch/abtesting/models/currency.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,51 +23,40 @@ class Currency(BaseModel): Currency """ - currency: Optional[StrictStr] = Field(default=None, description="Currency code.") - revenue: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, description="Revenue for this currency." - ) - mean: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, description="Mean for this currency." - ) - standard_deviation: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, - description="Standard deviation for this currency.", - alias="standardDeviation", - ) + currency: Optional[str] = Field(default=None, alias="currency") + """ Currency code. """ + revenue: Optional[float] = Field(default=None, alias="revenue") + """ Revenue for this currency. """ + mean: Optional[float] = Field(default=None, alias="mean") + """ Mean for this currency. """ + standard_deviation: Optional[float] = Field(default=None, alias="standardDeviation") + """ Standard deviation for this currency. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Currency from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Currency from a dict""" if obj is None: return None @@ -75,12 +64,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "currency": obj.get("currency"), - "revenue": obj.get("revenue"), - "mean": obj.get("mean"), - "standardDeviation": obj.get("standardDeviation"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/effect.py b/algoliasearch/abtesting/models/effect.py index 590d58dca..a6569231c 100644 --- a/algoliasearch/abtesting/models/effect.py +++ b/algoliasearch/abtesting/models/effect.py @@ -25,8 +25,11 @@ class Effect(str, Enum): allowed enum values """ ADDTOCARTRATE = "addToCartRate" + CLICKTHROUGHRATE = "clickThroughRate" + CONVERSIONRATE = "conversionRate" + PURCHASERATE = "purchaseRate" @classmethod diff --git a/algoliasearch/abtesting/models/empty_search.py b/algoliasearch/abtesting/models/empty_search.py index 336f866c5..4b753e4e4 100644 --- a/algoliasearch/abtesting/models/empty_search.py +++ b/algoliasearch/abtesting/models/empty_search.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,34 @@ class EmptySearch(BaseModel): Configuration for handling empty searches. """ - exclude: Optional[StrictBool] = Field( - default=None, - description="Whether to exclude empty searches when calculating A/B test results.", - ) + exclude: Optional[bool] = Field(default=None, alias="exclude") + """ Whether to exclude empty searches when calculating A/B test results. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of EmptySearch from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of EmptySearch from a dict""" if obj is None: return None @@ -67,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"exclude": obj.get("exclude")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/empty_search_filter.py b/algoliasearch/abtesting/models/empty_search_filter.py index 2c005f40f..eff8cb848 100644 --- a/algoliasearch/abtesting/models/empty_search_filter.py +++ b/algoliasearch/abtesting/models/empty_search_filter.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,49 +23,38 @@ class EmptySearchFilter(BaseModel): Empty searches removed from the A/B test as a result of configuration settings. """ - users_count: Optional[StrictInt] = Field( - default=None, - description="Number of users removed from the A/B test.", - alias="usersCount", - ) - tracked_searches_count: Optional[StrictInt] = Field( - default=None, - description="Number of tracked searches removed from the A/B test.", - alias="trackedSearchesCount", + users_count: Optional[int] = Field(default=None, alias="usersCount") + """ Number of users removed from the A/B test. """ + tracked_searches_count: Optional[int] = Field( + default=None, alias="trackedSearchesCount" ) + """ Number of tracked searches removed from the A/B test. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of EmptySearchFilter from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of EmptySearchFilter from a dict""" if obj is None: return None @@ -73,10 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "usersCount": obj.get("usersCount"), - "trackedSearchesCount": obj.get("trackedSearchesCount"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/error_base.py b/algoliasearch/abtesting/models/error_base.py index 4317b330d..075d8a3ac 100644 --- a/algoliasearch/abtesting/models/error_base.py +++ b/algoliasearch/abtesting/models/error_base.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, ClassVar, Dict, List, Optional +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,50 +23,34 @@ class ErrorBase(BaseModel): Error. """ - message: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["message"] + message: Optional[str] = Field(default=None, alias="message") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + extra="allow", ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ErrorBase from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={ - "additional_properties", - }, exclude_none=True, exclude_unset=True, ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ErrorBase from a dict""" if obj is None: return None @@ -74,10 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"message": obj.get("message")}) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/filter_effects.py b/algoliasearch/abtesting/models/filter_effects.py index a8e0d3a79..e1d64daf0 100644 --- a/algoliasearch/abtesting/models/filter_effects.py +++ b/algoliasearch/abtesting/models/filter_effects.py @@ -27,45 +27,34 @@ class FilterEffects(BaseModel): A/B test filter effects resulting from configuration settings. """ - outliers: Optional[OutliersFilter] = None + outliers: Optional[OutliersFilter] = Field(default=None, alias="outliers") empty_search: Optional[EmptySearchFilter] = Field(default=None, alias="emptySearch") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of FilterEffects from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.outliers: - _dict["outliers"] = self.outliers.to_dict() - if self.empty_search: - _dict["emptySearch"] = self.empty_search.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of FilterEffects from a dict""" if obj is None: return None @@ -73,18 +62,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "outliers": ( - OutliersFilter.from_dict(obj.get("outliers")) - if obj.get("outliers") is not None - else None - ), - "emptySearch": ( - EmptySearchFilter.from_dict(obj.get("emptySearch")) - if obj.get("emptySearch") is not None - else None - ), - } + obj["outliers"] = ( + OutliersFilter.from_dict(obj["outliers"]) + if obj.get("outliers") is not None + else None ) - return _obj + obj["emptySearch"] = ( + EmptySearchFilter.from_dict(obj["emptySearch"]) + if obj.get("emptySearch") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/list_ab_tests_response.py b/algoliasearch/abtesting/models/list_ab_tests_response.py index 372678dce..3d77b3256 100644 --- a/algoliasearch/abtesting/models/list_ab_tests_response.py +++ b/algoliasearch/abtesting/models/list_ab_tests_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,48 +26,38 @@ class ListABTestsResponse(BaseModel): ListABTestsResponse """ - abtests: Optional[List[ABTest]] = Field(description="A/B tests.") - count: StrictInt = Field(description="Number of A/B tests.") - total: StrictInt = Field(description="Number of retrievable A/B tests.") + abtests: List[ABTest] = Field(alias="abtests") + """ A/B tests. """ + count: int = Field(alias="count") + """ Number of A/B tests. """ + total: int = Field(alias="total") + """ Number of retrievable A/B tests. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ListABTestsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.abtests: - for _item in self.abtests: - if _item: - _items.append(_item.to_dict()) - _dict["abtests"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ListABTestsResponse from a dict""" if obj is None: return None @@ -75,15 +65,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "abtests": ( - [ABTest.from_dict(_item) for _item in obj.get("abtests")] - if obj.get("abtests") is not None - else None - ), - "count": obj.get("count"), - "total": obj.get("total"), - } + obj["abtests"] = ( + [ABTest.from_dict(_item) for _item in obj["abtests"]] + if obj.get("abtests") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/minimum_detectable_effect.py b/algoliasearch/abtesting/models/minimum_detectable_effect.py index 29f35ad52..3bffeb8db 100644 --- a/algoliasearch/abtesting/models/minimum_detectable_effect.py +++ b/algoliasearch/abtesting/models/minimum_detectable_effect.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.abtesting.models.effect import Effect @@ -26,49 +26,35 @@ class MinimumDetectableEffect(BaseModel): Configuration for the smallest difference between test variants you want to detect. """ - size: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - default=None, - description="Smallest difference in an observable metric between variants. For example, to detect a 10% difference between variants, set this value to 0.1. ", - ) - effect: Optional[Effect] = None + size: Optional[float] = Field(default=None, alias="size") + """ Smallest difference in an observable metric between variants. For example, to detect a 10% difference between variants, set this value to 0.1. """ + effect: Optional[Effect] = Field(default=None, alias="effect") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of MinimumDetectableEffect from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of MinimumDetectableEffect from a dict""" if obj is None: return None @@ -76,7 +62,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"size": obj.get("size"), "effect": obj.get("effect")} - ) - return _obj + obj["effect"] = obj.get("effect") + + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/outliers.py b/algoliasearch/abtesting/models/outliers.py index db2df2756..503b75106 100644 --- a/algoliasearch/abtesting/models/outliers.py +++ b/algoliasearch/abtesting/models/outliers.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,34 @@ class Outliers(BaseModel): Configuration for handling outliers. """ - exclude: Optional[StrictBool] = Field( - default=True, - description="Whether to exclude outliers when calculating A/B test results.", - ) + exclude: Optional[bool] = Field(default=None, alias="exclude") + """ Whether to exclude outliers when calculating A/B test results. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Outliers from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Outliers from a dict""" if obj is None: return None @@ -67,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"exclude": obj.get("exclude")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/outliers_filter.py b/algoliasearch/abtesting/models/outliers_filter.py index 3f47d9b86..21cd53b43 100644 --- a/algoliasearch/abtesting/models/outliers_filter.py +++ b/algoliasearch/abtesting/models/outliers_filter.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,49 +23,38 @@ class OutliersFilter(BaseModel): Outliers removed from the A/B test as a result of configuration settings. """ - users_count: Optional[StrictInt] = Field( - default=None, - description="Number of users removed from the A/B test.", - alias="usersCount", - ) - tracked_searches_count: Optional[StrictInt] = Field( - default=None, - description="Number of tracked searches removed from the A/B test.", - alias="trackedSearchesCount", + users_count: Optional[int] = Field(default=None, alias="usersCount") + """ Number of users removed from the A/B test. """ + tracked_searches_count: Optional[int] = Field( + default=None, alias="trackedSearchesCount" ) + """ Number of tracked searches removed from the A/B test. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of OutliersFilter from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of OutliersFilter from a dict""" if obj is None: return None @@ -73,10 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "usersCount": obj.get("usersCount"), - "trackedSearchesCount": obj.get("trackedSearchesCount"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/schedule_ab_test_response.py b/algoliasearch/abtesting/models/schedule_ab_test_response.py index 53383d8be..e8ecbfe0c 100644 --- a/algoliasearch/abtesting/models/schedule_ab_test_response.py +++ b/algoliasearch/abtesting/models/schedule_ab_test_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,42 +23,34 @@ class ScheduleABTestResponse(BaseModel): ScheduleABTestResponse """ - ab_test_schedule_id: StrictInt = Field( - description="Unique scheduled A/B test identifier.", alias="abTestScheduleID" - ) + ab_test_schedule_id: int = Field(alias="abTestScheduleID") + """ Unique scheduled A/B test identifier. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ScheduleABTestResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ScheduleABTestResponse from a dict""" if obj is None: return None @@ -66,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"abTestScheduleID": obj.get("abTestScheduleID")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/schedule_ab_tests_request.py b/algoliasearch/abtesting/models/schedule_ab_tests_request.py index e3ef5edac..0a0b3ebb7 100644 --- a/algoliasearch/abtesting/models/schedule_ab_tests_request.py +++ b/algoliasearch/abtesting/models/schedule_ab_tests_request.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.abtesting.models.add_ab_tests_variant import AddABTestsVariant @@ -26,57 +26,40 @@ class ScheduleABTestsRequest(BaseModel): ScheduleABTestsRequest """ - name: StrictStr = Field(description="A/B test name.") - variants: Annotated[List[AddABTestsVariant], Field(min_length=2, max_length=2)] = ( - Field(description="A/B test variants.") - ) - scheduled_at: StrictStr = Field( - description="Date and time when the A/B test is scheduled to start, in RFC 3339 format.", - alias="scheduledAt", - ) - end_at: StrictStr = Field( - description="End date and time of the A/B test, in RFC 3339 format.", - alias="endAt", - ) + name: str = Field(alias="name") + """ A/B test name. """ + variants: List[AddABTestsVariant] = Field(alias="variants") + """ A/B test variants. """ + scheduled_at: str = Field(alias="scheduledAt") + """ Date and time when the A/B test is scheduled to start, in RFC 3339 format. """ + end_at: str = Field(alias="endAt") + """ End date and time of the A/B test, in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ScheduleABTestsRequest from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.variants: - for _item in self.variants: - if _item: - _items.append(_item.to_dict()) - _dict["variants"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ScheduleABTestsRequest from a dict""" if obj is None: return None @@ -84,19 +67,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "name": obj.get("name"), - "variants": ( - [ - AddABTestsVariant.from_dict(_item) - for _item in obj.get("variants") - ] - if obj.get("variants") is not None - else None - ), - "scheduledAt": obj.get("scheduledAt"), - "endAt": obj.get("endAt"), - } + obj["variants"] = ( + [AddABTestsVariant.from_dict(_item) for _item in obj["variants"]] + if obj.get("variants") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/abtesting/models/status.py b/algoliasearch/abtesting/models/status.py index e4bce2aae..9d14491a9 100644 --- a/algoliasearch/abtesting/models/status.py +++ b/algoliasearch/abtesting/models/status.py @@ -25,8 +25,11 @@ class Status(str, Enum): allowed enum values """ ACTIVE = "active" + STOPPED = "stopped" + EXPIRED = "expired" + FAILED = "failed" @classmethod diff --git a/algoliasearch/abtesting/models/variant.py b/algoliasearch/abtesting/models/variant.py index 1f12eee8e..708e32314 100644 --- a/algoliasearch/abtesting/models/variant.py +++ b/algoliasearch/abtesting/models/variant.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.abtesting.models.currency import Currency @@ -27,122 +27,77 @@ class Variant(BaseModel): Variant """ - add_to_cart_count: StrictInt = Field( - description="Number of add-to-cart events for this variant.", - alias="addToCartCount", - ) - add_to_cart_rate: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, - description="[Add-to-cart rate](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#add-to-cart-rate) for this variant. ", - alias="addToCartRate", - ) - average_click_position: Optional[StrictInt] = Field( - default=None, - description="[Average click position](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#click-position) for this variant. ", - alias="averageClickPosition", - ) - click_count: StrictInt = Field( - description="Number of click events for this variant.", alias="clickCount" - ) - click_through_rate: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, - description="[Click-through rate](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#click-through-rate) for this variant. ", - alias="clickThroughRate", - ) - conversion_count: StrictInt = Field( - description="Number of click events for this variant.", alias="conversionCount" - ) - conversion_rate: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, - description="[Conversion rate](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#conversion-rate) for this variant. ", - alias="conversionRate", - ) - currencies: Optional[Dict[str, Currency]] = Field( - default=None, description="A/B test currencies." - ) - description: StrictStr = Field(description="Description for this variant.") - estimated_sample_size: Optional[StrictInt] = Field( - default=None, - description="Estimated number of searches required to achieve the desired statistical significance. The A/B test configuration must include a `mininmumDetectableEffect` setting for this number to be included in the response. ", - alias="estimatedSampleSize", - ) + add_to_cart_count: int = Field(alias="addToCartCount") + """ Number of add-to-cart events for this variant. """ + add_to_cart_rate: Optional[float] = Field(default=None, alias="addToCartRate") + """ [Add-to-cart rate](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#add-to-cart-rate) for this variant. """ + average_click_position: Optional[int] = Field( + default=None, alias="averageClickPosition" + ) + """ [Average click position](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#click-position) for this variant. """ + click_count: int = Field(alias="clickCount") + """ Number of click events for this variant. """ + click_through_rate: Optional[float] = Field(default=None, alias="clickThroughRate") + """ [Click-through rate](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#click-through-rate) for this variant. """ + conversion_count: int = Field(alias="conversionCount") + """ Number of click events for this variant. """ + conversion_rate: Optional[float] = Field(default=None, alias="conversionRate") + """ [Conversion rate](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#conversion-rate) for this variant. """ + currencies: Optional[Dict[str, Currency]] = Field(default=None, alias="currencies") + """ A/B test currencies. """ + description: str = Field(alias="description") + """ Description for this variant. """ + estimated_sample_size: Optional[int] = Field( + default=None, alias="estimatedSampleSize" + ) + """ Estimated number of searches required to achieve the desired statistical significance. The A/B test configuration must include a `mininmumDetectableEffect` setting for this number to be included in the response. """ filter_effects: Optional[FilterEffects] = Field(default=None, alias="filterEffects") - index: StrictStr = Field( - description="Index name of the A/B test variant (case-sensitive)." - ) - no_result_count: Optional[StrictInt] = Field( - description="Number of [searches without results](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#searches-without-results) for this variant.", - alias="noResultCount", - ) - purchase_count: StrictInt = Field( - description="Number of purchase events for this variant.", alias="purchaseCount" - ) - purchase_rate: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, - description="[Purchase rate](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#purchase-rate) for this variant. ", - alias="purchaseRate", - ) - search_count: Optional[StrictInt] = Field( - description="Number of searches for this variant.", alias="searchCount" - ) - tracked_search_count: Optional[StrictInt] = Field( - default=0, - description="Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true.", - alias="trackedSearchCount", - ) - traffic_percentage: Annotated[int, Field(le=100, strict=True, ge=0)] = Field( - description="Percentage of search requests each variant receives.", - alias="trafficPercentage", - ) - user_count: Optional[StrictInt] = Field( - description="Number of users that made searches to this variant.", - alias="userCount", - ) - tracked_user_count: Optional[StrictInt] = Field( - description="Number of users that made tracked searches to this variant.", - alias="trackedUserCount", - ) + index: str = Field(alias="index") + """ Index name of the A/B test variant (case-sensitive). """ + no_result_count: int = Field(alias="noResultCount") + """ Number of [searches without results](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#searches-without-results) for this variant. """ + purchase_count: int = Field(alias="purchaseCount") + """ Number of purchase events for this variant. """ + purchase_rate: Optional[float] = Field(default=None, alias="purchaseRate") + """ [Purchase rate](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#purchase-rate) for this variant. """ + search_count: int = Field(alias="searchCount") + """ Number of searches for this variant. """ + tracked_search_count: Optional[int] = Field( + default=None, alias="trackedSearchCount" + ) + """ Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true. """ + traffic_percentage: int = Field(alias="trafficPercentage") + """ Percentage of search requests each variant receives. """ + user_count: int = Field(alias="userCount") + """ Number of users that made searches to this variant. """ + tracked_user_count: int = Field(alias="trackedUserCount") + """ Number of users that made tracked searches to this variant. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Variant from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _field_dict = {} - if self.currencies: - for _key in self.currencies: - if self.currencies[_key]: - _field_dict[_key] = self.currencies[_key].to_dict() - _dict["currencies"] = _field_dict - if self.filter_effects: - _dict["filterEffects"] = self.filter_effects.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Variant from a dict""" if obj is None: return None @@ -150,39 +105,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "addToCartCount": obj.get("addToCartCount"), - "addToCartRate": obj.get("addToCartRate"), - "averageClickPosition": obj.get("averageClickPosition"), - "clickCount": obj.get("clickCount"), - "clickThroughRate": obj.get("clickThroughRate"), - "conversionCount": obj.get("conversionCount"), - "conversionRate": obj.get("conversionRate"), - "currencies": ( - dict( - (_k, Currency.from_dict(_v)) - for _k, _v in obj.get("currencies").items() - ) - if obj.get("currencies") is not None - else None - ), - "description": obj.get("description"), - "estimatedSampleSize": obj.get("estimatedSampleSize"), - "filterEffects": ( - FilterEffects.from_dict(obj.get("filterEffects")) - if obj.get("filterEffects") is not None - else None - ), - "index": obj.get("index"), - "noResultCount": obj.get("noResultCount"), - "purchaseCount": obj.get("purchaseCount"), - "purchaseRate": obj.get("purchaseRate"), - "searchCount": obj.get("searchCount"), - "trackedSearchCount": obj.get("trackedSearchCount"), - "trafficPercentage": obj.get("trafficPercentage"), - "userCount": obj.get("userCount"), - "trackedUserCount": obj.get("trackedUserCount"), - } + obj["currencies"] = ( + dict((_k, Currency.from_dict(_v)) for _k, _v in obj["currencies"].items()) + if obj.get("currencies") is not None + else None ) - return _obj + obj["filterEffects"] = ( + FilterEffects.from_dict(obj["filterEffects"]) + if obj.get("filterEffects") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/client.py b/algoliasearch/analytics/client.py index 81a6eadf4..e710db951 100644 --- a/algoliasearch/analytics/client.py +++ b/algoliasearch/analytics/client.py @@ -12,11 +12,12 @@ from urllib.parse import quote from pydantic import Field, StrictBool, StrictInt, StrictStr +from typing_extensions import Annotated if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.analytics.config import AnalyticsConfig from algoliasearch.analytics.models.direction import Direction diff --git a/algoliasearch/analytics/models/click_position.py b/algoliasearch/analytics/models/click_position.py index 641e30e03..e2d67f5f5 100644 --- a/algoliasearch/analytics/models/click_position.py +++ b/algoliasearch/analytics/models/click_position.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class ClickPosition(BaseModel): @@ -23,50 +23,36 @@ class ClickPosition(BaseModel): Click position. """ - position: Optional[ - Annotated[List[StrictInt], Field(min_length=2, max_length=2)] - ] = Field( - default=None, - description="Range of positions in the search results, using the pattern `[start,end]`. For positions 11 and up, click events are summed over the specified range. `-1` indicates the end of the list of search results. ", - ) - click_count: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=0, - description="Number of times this search has been clicked at that position.", - alias="clickCount", - ) + position: Optional[List[int]] = Field(default=None, alias="position") + """ Range of positions in the search results, using the pattern `[start,end]`. For positions 11 and up, click events are summed over the specified range. `-1` indicates the end of the list of search results. """ + click_count: Optional[int] = Field(default=None, alias="clickCount") + """ Number of times this search has been clicked at that position. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ClickPosition from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ClickPosition from a dict""" if obj is None: return None @@ -74,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"position": obj.get("position"), "clickCount": obj.get("clickCount")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/currency_code.py b/algoliasearch/analytics/models/currency_code.py index c719464f4..e5f6d02b8 100644 --- a/algoliasearch/analytics/models/currency_code.py +++ b/algoliasearch/analytics/models/currency_code.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,44 +23,36 @@ class CurrencyCode(BaseModel): Currency code. """ - currency: Optional[StrictStr] = Field(default=None, description="Currency code.") - revenue: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, - description="Revenue associated with this search in this currency.", - ) + currency: Optional[str] = Field(default=None, alias="currency") + """ Currency code. """ + revenue: Optional[float] = Field(default=None, alias="revenue") + """ Revenue associated with this search in this currency. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of CurrencyCode from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of CurrencyCode from a dict""" if obj is None: return None @@ -68,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"currency": obj.get("currency"), "revenue": obj.get("revenue")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/daily_add_to_cart_rates.py b/algoliasearch/analytics/models/daily_add_to_cart_rates.py index 0a0281059..7cc1999bb 100644 --- a/algoliasearch/analytics/models/daily_add_to_cart_rates.py +++ b/algoliasearch/analytics/models/daily_add_to_cart_rates.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class DailyAddToCartRates(BaseModel): @@ -23,58 +23,40 @@ class DailyAddToCartRates(BaseModel): DailyAddToCartRates """ - rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Add-to-cart rate, calculated as number of tracked searches with at least one add-to-cart event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. " - ) - tracked_search_count: StrictInt = Field( - description="Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true.", - alias="trackedSearchCount", - ) - add_to_cart_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of add-to-cart events from this search.", - alias="addToCartCount", - ) - var_date: StrictStr = Field( - description="Date in the format YYYY-MM-DD.", alias="date" - ) + rate: float = Field(alias="rate") + """ Add-to-cart rate, calculated as number of tracked searches with at least one add-to-cart event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + tracked_search_count: int = Field(alias="trackedSearchCount") + """ Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true. """ + add_to_cart_count: int = Field(alias="addToCartCount") + """ Number of add-to-cart events from this search. """ + var_date: str = Field(alias="date") + """ Date in the format YYYY-MM-DD. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DailyAddToCartRates from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DailyAddToCartRates from a dict""" if obj is None: return None @@ -82,12 +64,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "rate": obj.get("rate"), - "trackedSearchCount": obj.get("trackedSearchCount"), - "addToCartCount": obj.get("addToCartCount"), - "date": obj.get("date"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/daily_average_clicks.py b/algoliasearch/analytics/models/daily_average_clicks.py index 2a4555ab5..ef5dfa73b 100644 --- a/algoliasearch/analytics/models/daily_average_clicks.py +++ b/algoliasearch/analytics/models/daily_average_clicks.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class DailyAverageClicks(BaseModel): @@ -23,53 +23,38 @@ class DailyAverageClicks(BaseModel): DailyAverageClicks """ - average: Optional[ - Union[ - Annotated[float, Field(strict=True, ge=1)], - Annotated[int, Field(strict=True, ge=1)], - ] - ] = Field( - description="Average position of a clicked search result in the list of search results. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. " - ) - click_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of clicks associated with this search.", alias="clickCount" - ) - var_date: StrictStr = Field( - description="Date in the format YYYY-MM-DD.", alias="date" - ) + average: float = Field(alias="average") + """ Average position of a clicked search result in the list of search results. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + click_count: int = Field(alias="clickCount") + """ Number of clicks associated with this search. """ + var_date: str = Field(alias="date") + """ Date in the format YYYY-MM-DD. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DailyAverageClicks from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DailyAverageClicks from a dict""" if obj is None: return None @@ -77,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "average": obj.get("average"), - "clickCount": obj.get("clickCount"), - "date": obj.get("date"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/daily_click_through_rates.py b/algoliasearch/analytics/models/daily_click_through_rates.py index c058811f9..648d5e333 100644 --- a/algoliasearch/analytics/models/daily_click_through_rates.py +++ b/algoliasearch/analytics/models/daily_click_through_rates.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class DailyClickThroughRates(BaseModel): @@ -23,57 +23,40 @@ class DailyClickThroughRates(BaseModel): DailyClickThroughRates """ - rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Click-through rate, calculated as number of tracked searches with at least one click event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. " - ) - click_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of clicks associated with this search.", alias="clickCount" - ) - tracked_search_count: StrictInt = Field( - description="Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true.", - alias="trackedSearchCount", - ) - var_date: StrictStr = Field( - description="Date in the format YYYY-MM-DD.", alias="date" - ) + rate: float = Field(alias="rate") + """ Click-through rate, calculated as number of tracked searches with at least one click event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + click_count: int = Field(alias="clickCount") + """ Number of clicks associated with this search. """ + tracked_search_count: int = Field(alias="trackedSearchCount") + """ Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true. """ + var_date: str = Field(alias="date") + """ Date in the format YYYY-MM-DD. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DailyClickThroughRates from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DailyClickThroughRates from a dict""" if obj is None: return None @@ -81,12 +64,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "rate": obj.get("rate"), - "clickCount": obj.get("clickCount"), - "trackedSearchCount": obj.get("trackedSearchCount"), - "date": obj.get("date"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/daily_conversion_rates.py b/algoliasearch/analytics/models/daily_conversion_rates.py index c40d388ba..3d32b010a 100644 --- a/algoliasearch/analytics/models/daily_conversion_rates.py +++ b/algoliasearch/analytics/models/daily_conversion_rates.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class DailyConversionRates(BaseModel): @@ -23,57 +23,40 @@ class DailyConversionRates(BaseModel): DailyConversionRates """ - rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Conversion rate, calculated as number of tracked searches with at least one conversion event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. " - ) - tracked_search_count: StrictInt = Field( - description="Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true.", - alias="trackedSearchCount", - ) - conversion_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of conversions from this search.", alias="conversionCount" - ) - var_date: StrictStr = Field( - description="Date in the format YYYY-MM-DD.", alias="date" - ) + rate: float = Field(alias="rate") + """ Conversion rate, calculated as number of tracked searches with at least one conversion event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + tracked_search_count: int = Field(alias="trackedSearchCount") + """ Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true. """ + conversion_count: int = Field(alias="conversionCount") + """ Number of conversions from this search. """ + var_date: str = Field(alias="date") + """ Date in the format YYYY-MM-DD. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DailyConversionRates from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DailyConversionRates from a dict""" if obj is None: return None @@ -81,12 +64,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "rate": obj.get("rate"), - "trackedSearchCount": obj.get("trackedSearchCount"), - "conversionCount": obj.get("conversionCount"), - "date": obj.get("date"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/daily_no_click_rates.py b/algoliasearch/analytics/models/daily_no_click_rates.py index 6ea5cdbe6..76a2f04a8 100644 --- a/algoliasearch/analytics/models/daily_no_click_rates.py +++ b/algoliasearch/analytics/models/daily_no_click_rates.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class DailyNoClickRates(BaseModel): @@ -23,55 +23,40 @@ class DailyNoClickRates(BaseModel): DailyNoClickRates """ - rate: Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] = Field( - description="No click rate, calculated as number of tracked searches without any click divided by the number of tracked searches." - ) - count: StrictInt = Field( - description="Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true." - ) - no_click_count: Annotated[int, Field(strict=True, ge=1)] = Field( - description="Number of times this search was returned as a result without any click.", - alias="noClickCount", - ) - var_date: StrictStr = Field( - description="Date in the format YYYY-MM-DD.", alias="date" - ) + rate: float = Field(alias="rate") + """ No click rate, calculated as number of tracked searches without any click divided by the number of tracked searches. """ + count: int = Field(alias="count") + """ Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true. """ + no_click_count: int = Field(alias="noClickCount") + """ Number of times this search was returned as a result without any click. """ + var_date: str = Field(alias="date") + """ Date in the format YYYY-MM-DD. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DailyNoClickRates from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DailyNoClickRates from a dict""" if obj is None: return None @@ -79,12 +64,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "rate": obj.get("rate"), - "count": obj.get("count"), - "noClickCount": obj.get("noClickCount"), - "date": obj.get("date"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/daily_no_results_rates.py b/algoliasearch/analytics/models/daily_no_results_rates.py index e80708849..52d546adf 100644 --- a/algoliasearch/analytics/models/daily_no_results_rates.py +++ b/algoliasearch/analytics/models/daily_no_results_rates.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class DailyNoResultsRates(BaseModel): @@ -23,52 +23,40 @@ class DailyNoResultsRates(BaseModel): DailyNoResultsRates """ - var_date: StrictStr = Field( - description="Date in the format YYYY-MM-DD.", alias="date" - ) - no_result_count: StrictInt = Field( - description="Number of searches without any results.", alias="noResultCount" - ) - count: StrictInt = Field(description="Number of searches.") - rate: Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] = Field( - description="No results rate, calculated as number of searches with zero results divided by the total number of searches." - ) + var_date: str = Field(alias="date") + """ Date in the format YYYY-MM-DD. """ + no_result_count: int = Field(alias="noResultCount") + """ Number of searches without any results. """ + count: int = Field(alias="count") + """ Number of searches. """ + rate: float = Field(alias="rate") + """ No results rate, calculated as number of searches with zero results divided by the total number of searches. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DailyNoResultsRates from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DailyNoResultsRates from a dict""" if obj is None: return None @@ -76,12 +64,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "date": obj.get("date"), - "noResultCount": obj.get("noResultCount"), - "count": obj.get("count"), - "rate": obj.get("rate"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/daily_purchase_rates.py b/algoliasearch/analytics/models/daily_purchase_rates.py index f2e5ec1bf..5a5398a82 100644 --- a/algoliasearch/analytics/models/daily_purchase_rates.py +++ b/algoliasearch/analytics/models/daily_purchase_rates.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class DailyPurchaseRates(BaseModel): @@ -23,57 +23,40 @@ class DailyPurchaseRates(BaseModel): DailyPurchaseRates """ - rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Purchase rate, calculated as number of tracked searches with at least one purchase event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. " - ) - tracked_search_count: StrictInt = Field( - description="Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true.", - alias="trackedSearchCount", - ) - purchase_count: StrictInt = Field( - description="Number of purchase events from this search.", alias="purchaseCount" - ) - var_date: StrictStr = Field( - description="Date in the format YYYY-MM-DD.", alias="date" - ) + rate: float = Field(alias="rate") + """ Purchase rate, calculated as number of tracked searches with at least one purchase event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + tracked_search_count: int = Field(alias="trackedSearchCount") + """ Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true. """ + purchase_count: int = Field(alias="purchaseCount") + """ Number of purchase events from this search. """ + var_date: str = Field(alias="date") + """ Date in the format YYYY-MM-DD. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DailyPurchaseRates from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DailyPurchaseRates from a dict""" if obj is None: return None @@ -81,12 +64,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "rate": obj.get("rate"), - "trackedSearchCount": obj.get("trackedSearchCount"), - "purchaseCount": obj.get("purchaseCount"), - "date": obj.get("date"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/daily_revenue.py b/algoliasearch/analytics/models/daily_revenue.py index 8b527f5ba..1b52eca70 100644 --- a/algoliasearch/analytics/models/daily_revenue.py +++ b/algoliasearch/analytics/models/daily_revenue.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,51 +26,36 @@ class DailyRevenue(BaseModel): DailyRevenue """ - currencies: Dict[str, CurrencyCode] = Field( - description="Revenue associated with this search, broken-down by currencies." - ) - var_date: StrictStr = Field( - description="Date in the format YYYY-MM-DD.", alias="date" - ) + currencies: Dict[str, CurrencyCode] = Field(alias="currencies") + """ Revenue associated with this search, broken-down by currencies. """ + var_date: str = Field(alias="date") + """ Date in the format YYYY-MM-DD. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DailyRevenue from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _field_dict = {} - if self.currencies: - for _key in self.currencies: - if self.currencies[_key]: - _field_dict[_key] = self.currencies[_key].to_dict() - _dict["currencies"] = _field_dict - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DailyRevenue from a dict""" if obj is None: return None @@ -78,17 +63,12 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "currencies": ( - dict( - (_k, CurrencyCode.from_dict(_v)) - for _k, _v in obj.get("currencies").items() - ) - if obj.get("currencies") is not None - else None - ), - "date": obj.get("date"), - } + obj["currencies"] = ( + dict( + (_k, CurrencyCode.from_dict(_v)) for _k, _v in obj["currencies"].items() + ) + if obj.get("currencies") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/daily_searches.py b/algoliasearch/analytics/models/daily_searches.py index 13ed323b5..bb243dda7 100644 --- a/algoliasearch/analytics/models/daily_searches.py +++ b/algoliasearch/analytics/models/daily_searches.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,36 @@ class DailySearches(BaseModel): DailySearches """ - var_date: StrictStr = Field( - description="Date in the format YYYY-MM-DD.", alias="date" - ) - count: StrictInt = Field(description="Number of occurrences.") + var_date: str = Field(alias="date") + """ Date in the format YYYY-MM-DD. """ + count: int = Field(alias="count") + """ Number of occurrences. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DailySearches from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DailySearches from a dict""" if obj is None: return None @@ -67,5 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"date": obj.get("date"), "count": obj.get("count")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/daily_searches_no_clicks.py b/algoliasearch/analytics/models/daily_searches_no_clicks.py index fcea06a5c..58d89a344 100644 --- a/algoliasearch/analytics/models/daily_searches_no_clicks.py +++ b/algoliasearch/analytics/models/daily_searches_no_clicks.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class DailySearchesNoClicks(BaseModel): @@ -23,44 +23,38 @@ class DailySearchesNoClicks(BaseModel): DailySearchesNoClicks """ - search: StrictStr = Field(description="Search query.") - count: Annotated[int, Field(strict=True, ge=1)] = Field( - description="Number of tracked searches." - ) - nb_hits: StrictInt = Field(description="Number of results (hits).", alias="nbHits") + search: str = Field(alias="search") + """ Search query. """ + count: int = Field(alias="count") + """ Number of tracked searches. """ + nb_hits: int = Field(alias="nbHits") + """ Number of results (hits). """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DailySearchesNoClicks from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DailySearchesNoClicks from a dict""" if obj is None: return None @@ -68,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "search": obj.get("search"), - "count": obj.get("count"), - "nbHits": obj.get("nbHits"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/daily_searches_no_results.py b/algoliasearch/analytics/models/daily_searches_no_results.py index ae9bb3dfd..14cbb2b06 100644 --- a/algoliasearch/analytics/models/daily_searches_no_results.py +++ b/algoliasearch/analytics/models/daily_searches_no_results.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class DailySearchesNoResults(BaseModel): @@ -23,45 +23,38 @@ class DailySearchesNoResults(BaseModel): DailySearchesNoResults """ - search: StrictStr = Field(description="Search query.") - count: StrictInt = Field(description="Number of occurrences.") - with_filter_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of searches for this term with applied filters.", - alias="withFilterCount", - ) + search: str = Field(alias="search") + """ Search query. """ + count: int = Field(alias="count") + """ Number of occurrences. """ + with_filter_count: int = Field(alias="withFilterCount") + """ Number of searches for this term with applied filters. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DailySearchesNoResults from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DailySearchesNoResults from a dict""" if obj is None: return None @@ -69,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "search": obj.get("search"), - "count": obj.get("count"), - "withFilterCount": obj.get("withFilterCount"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/daily_users.py b/algoliasearch/analytics/models/daily_users.py index 8b6448efb..f79a7e727 100644 --- a/algoliasearch/analytics/models/daily_users.py +++ b/algoliasearch/analytics/models/daily_users.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,36 @@ class DailyUsers(BaseModel): DailyUsers """ - var_date: StrictStr = Field( - description="Date in the format YYYY-MM-DD.", alias="date" - ) - count: StrictInt = Field(description="Number of unique users.") + var_date: str = Field(alias="date") + """ Date in the format YYYY-MM-DD. """ + count: int = Field(alias="count") + """ Number of unique users. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DailyUsers from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DailyUsers from a dict""" if obj is None: return None @@ -67,5 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"date": obj.get("date"), "count": obj.get("count")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/direction.py b/algoliasearch/analytics/models/direction.py index 019d3b55c..afa2e14b0 100644 --- a/algoliasearch/analytics/models/direction.py +++ b/algoliasearch/analytics/models/direction.py @@ -25,6 +25,7 @@ class Direction(str, Enum): allowed enum values """ ASC = "asc" + DESC = "desc" @classmethod diff --git a/algoliasearch/analytics/models/error_base.py b/algoliasearch/analytics/models/error_base.py index 4317b330d..075d8a3ac 100644 --- a/algoliasearch/analytics/models/error_base.py +++ b/algoliasearch/analytics/models/error_base.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, ClassVar, Dict, List, Optional +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,50 +23,34 @@ class ErrorBase(BaseModel): Error. """ - message: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["message"] + message: Optional[str] = Field(default=None, alias="message") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + extra="allow", ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ErrorBase from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={ - "additional_properties", - }, exclude_none=True, exclude_unset=True, ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ErrorBase from a dict""" if obj is None: return None @@ -74,10 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"message": obj.get("message")}) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_add_to_cart_rate_response.py b/algoliasearch/analytics/models/get_add_to_cart_rate_response.py index c49a05328..97e376593 100644 --- a/algoliasearch/analytics/models/get_add_to_cart_rate_response.py +++ b/algoliasearch/analytics/models/get_add_to_cart_rate_response.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.analytics.models.daily_add_to_cart_rates import DailyAddToCartRates @@ -26,62 +26,40 @@ class GetAddToCartRateResponse(BaseModel): GetAddToCartRateResponse """ - rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Add-to-cart rate, calculated as number of tracked searches with at least one add-to-cart event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. " - ) - tracked_search_count: StrictInt = Field( - description="Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true.", - alias="trackedSearchCount", - ) - add_to_cart_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of add-to-cart events from this search.", - alias="addToCartCount", - ) - dates: List[DailyAddToCartRates] = Field(description="Daily add-to-cart rates.") + rate: float = Field(alias="rate") + """ Add-to-cart rate, calculated as number of tracked searches with at least one add-to-cart event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + tracked_search_count: int = Field(alias="trackedSearchCount") + """ Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true. """ + add_to_cart_count: int = Field(alias="addToCartCount") + """ Number of add-to-cart events from this search. """ + dates: List[DailyAddToCartRates] = Field(alias="dates") + """ Daily add-to-cart rates. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetAddToCartRateResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.dates: - for _item in self.dates: - if _item: - _items.append(_item.to_dict()) - _dict["dates"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetAddToCartRateResponse from a dict""" if obj is None: return None @@ -89,16 +67,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "rate": obj.get("rate"), - "trackedSearchCount": obj.get("trackedSearchCount"), - "addToCartCount": obj.get("addToCartCount"), - "dates": ( - [DailyAddToCartRates.from_dict(_item) for _item in obj.get("dates")] - if obj.get("dates") is not None - else None - ), - } + obj["dates"] = ( + [DailyAddToCartRates.from_dict(_item) for _item in obj["dates"]] + if obj.get("dates") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_average_click_position_response.py b/algoliasearch/analytics/models/get_average_click_position_response.py index cda7ee594..e229417aa 100644 --- a/algoliasearch/analytics/models/get_average_click_position_response.py +++ b/algoliasearch/analytics/models/get_average_click_position_response.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.analytics.models.daily_average_clicks import DailyAverageClicks @@ -26,59 +26,38 @@ class GetAverageClickPositionResponse(BaseModel): GetAverageClickPositionResponse """ - average: Optional[ - Union[ - Annotated[float, Field(strict=True, ge=1)], - Annotated[int, Field(strict=True, ge=1)], - ] - ] = Field( - description="Average position of a clicked search result in the list of search results. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. " - ) - click_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of clicks associated with this search.", alias="clickCount" - ) - dates: List[DailyAverageClicks] = Field( - description="Daily average click positions." - ) + average: float = Field(alias="average") + """ Average position of a clicked search result in the list of search results. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + click_count: int = Field(alias="clickCount") + """ Number of clicks associated with this search. """ + dates: List[DailyAverageClicks] = Field(alias="dates") + """ Daily average click positions. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetAverageClickPositionResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.dates: - for _item in self.dates: - if _item: - _items.append(_item.to_dict()) - _dict["dates"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetAverageClickPositionResponse from a dict""" if obj is None: return None @@ -86,15 +65,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "average": obj.get("average"), - "clickCount": obj.get("clickCount"), - "dates": ( - [DailyAverageClicks.from_dict(_item) for _item in obj.get("dates")] - if obj.get("dates") is not None - else None - ), - } + obj["dates"] = ( + [DailyAverageClicks.from_dict(_item) for _item in obj["dates"]] + if obj.get("dates") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_click_positions_response.py b/algoliasearch/analytics/models/get_click_positions_response.py index 5c2f16292..21908c479 100644 --- a/algoliasearch/analytics/models/get_click_positions_response.py +++ b/algoliasearch/analytics/models/get_click_positions_response.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.analytics.models.click_position import ClickPosition @@ -26,50 +26,34 @@ class GetClickPositionsResponse(BaseModel): GetClickPositionsResponse """ - positions: Annotated[List[ClickPosition], Field(min_length=12, max_length=12)] = ( - Field( - description="List of positions in the search results and clicks associated with this search." - ) - ) + positions: List[ClickPosition] = Field(alias="positions") + """ List of positions in the search results and clicks associated with this search. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetClickPositionsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.positions: - for _item in self.positions: - if _item: - _items.append(_item.to_dict()) - _dict["positions"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetClickPositionsResponse from a dict""" if obj is None: return None @@ -77,13 +61,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "positions": ( - [ClickPosition.from_dict(_item) for _item in obj.get("positions")] - if obj.get("positions") is not None - else None - ) - } + obj["positions"] = ( + [ClickPosition.from_dict(_item) for _item in obj["positions"]] + if obj.get("positions") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_click_through_rate_response.py b/algoliasearch/analytics/models/get_click_through_rate_response.py index dec368f79..d2358b31a 100644 --- a/algoliasearch/analytics/models/get_click_through_rate_response.py +++ b/algoliasearch/analytics/models/get_click_through_rate_response.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.analytics.models.daily_click_through_rates import ( @@ -28,63 +28,40 @@ class GetClickThroughRateResponse(BaseModel): GetClickThroughRateResponse """ - rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Click-through rate, calculated as number of tracked searches with at least one click event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. " - ) - click_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of clicks associated with this search.", alias="clickCount" - ) - tracked_search_count: StrictInt = Field( - description="Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true.", - alias="trackedSearchCount", - ) - dates: List[DailyClickThroughRates] = Field( - description="Daily click-through rates." - ) + rate: float = Field(alias="rate") + """ Click-through rate, calculated as number of tracked searches with at least one click event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + click_count: int = Field(alias="clickCount") + """ Number of clicks associated with this search. """ + tracked_search_count: int = Field(alias="trackedSearchCount") + """ Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true. """ + dates: List[DailyClickThroughRates] = Field(alias="dates") + """ Daily click-through rates. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetClickThroughRateResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.dates: - for _item in self.dates: - if _item: - _items.append(_item.to_dict()) - _dict["dates"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetClickThroughRateResponse from a dict""" if obj is None: return None @@ -92,19 +69,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "rate": obj.get("rate"), - "clickCount": obj.get("clickCount"), - "trackedSearchCount": obj.get("trackedSearchCount"), - "dates": ( - [ - DailyClickThroughRates.from_dict(_item) - for _item in obj.get("dates") - ] - if obj.get("dates") is not None - else None - ), - } + obj["dates"] = ( + [DailyClickThroughRates.from_dict(_item) for _item in obj["dates"]] + if obj.get("dates") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_conversion_rate_response.py b/algoliasearch/analytics/models/get_conversion_rate_response.py index f43b898eb..d3bf1881d 100644 --- a/algoliasearch/analytics/models/get_conversion_rate_response.py +++ b/algoliasearch/analytics/models/get_conversion_rate_response.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.analytics.models.daily_conversion_rates import DailyConversionRates @@ -26,61 +26,40 @@ class GetConversionRateResponse(BaseModel): GetConversionRateResponse """ - rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Conversion rate, calculated as number of tracked searches with at least one conversion event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. " - ) - tracked_search_count: StrictInt = Field( - description="Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true.", - alias="trackedSearchCount", - ) - conversion_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of conversions from this search.", alias="conversionCount" - ) - dates: List[DailyConversionRates] = Field(description="Daily conversion rates.") + rate: float = Field(alias="rate") + """ Conversion rate, calculated as number of tracked searches with at least one conversion event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + tracked_search_count: int = Field(alias="trackedSearchCount") + """ Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true. """ + conversion_count: int = Field(alias="conversionCount") + """ Number of conversions from this search. """ + dates: List[DailyConversionRates] = Field(alias="dates") + """ Daily conversion rates. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetConversionRateResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.dates: - for _item in self.dates: - if _item: - _items.append(_item.to_dict()) - _dict["dates"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetConversionRateResponse from a dict""" if obj is None: return None @@ -88,19 +67,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "rate": obj.get("rate"), - "trackedSearchCount": obj.get("trackedSearchCount"), - "conversionCount": obj.get("conversionCount"), - "dates": ( - [ - DailyConversionRates.from_dict(_item) - for _item in obj.get("dates") - ] - if obj.get("dates") is not None - else None - ), - } + obj["dates"] = ( + [DailyConversionRates.from_dict(_item) for _item in obj["dates"]] + if obj.get("dates") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_no_click_rate_response.py b/algoliasearch/analytics/models/get_no_click_rate_response.py index beab6085a..fb0b473ec 100644 --- a/algoliasearch/analytics/models/get_no_click_rate_response.py +++ b/algoliasearch/analytics/models/get_no_click_rate_response.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Union +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.analytics.models.daily_no_click_rates import DailyNoClickRates @@ -26,59 +26,40 @@ class GetNoClickRateResponse(BaseModel): GetNoClickRateResponse """ - rate: Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] = Field( - description="No click rate, calculated as number of tracked searches without any click divided by the number of tracked searches." - ) - count: StrictInt = Field( - description="Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true." - ) - no_click_count: Annotated[int, Field(strict=True, ge=1)] = Field( - description="Number of times this search was returned as a result without any click.", - alias="noClickCount", - ) - dates: List[DailyNoClickRates] = Field(description="Daily no click rates.") + rate: float = Field(alias="rate") + """ No click rate, calculated as number of tracked searches without any click divided by the number of tracked searches. """ + count: int = Field(alias="count") + """ Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true. """ + no_click_count: int = Field(alias="noClickCount") + """ Number of times this search was returned as a result without any click. """ + dates: List[DailyNoClickRates] = Field(alias="dates") + """ Daily no click rates. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetNoClickRateResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.dates: - for _item in self.dates: - if _item: - _items.append(_item.to_dict()) - _dict["dates"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetNoClickRateResponse from a dict""" if obj is None: return None @@ -86,16 +67,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "rate": obj.get("rate"), - "count": obj.get("count"), - "noClickCount": obj.get("noClickCount"), - "dates": ( - [DailyNoClickRates.from_dict(_item) for _item in obj.get("dates")] - if obj.get("dates") is not None - else None - ), - } + obj["dates"] = ( + [DailyNoClickRates.from_dict(_item) for _item in obj["dates"]] + if obj.get("dates") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_no_results_rate_response.py b/algoliasearch/analytics/models/get_no_results_rate_response.py index 253c12400..d302738b7 100644 --- a/algoliasearch/analytics/models/get_no_results_rate_response.py +++ b/algoliasearch/analytics/models/get_no_results_rate_response.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Union +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.analytics.models.daily_no_results_rates import DailyNoResultsRates @@ -26,56 +26,40 @@ class GetNoResultsRateResponse(BaseModel): GetNoResultsRateResponse """ - rate: Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] = Field( - description="No results rate, calculated as number of searches with zero results divided by the total number of searches." - ) - count: StrictInt = Field(description="Number of searches.") - no_result_count: StrictInt = Field( - description="Number of searches without any results.", alias="noResultCount" - ) - dates: List[DailyNoResultsRates] = Field(description="Daily no results rates.") + rate: float = Field(alias="rate") + """ No results rate, calculated as number of searches with zero results divided by the total number of searches. """ + count: int = Field(alias="count") + """ Number of searches. """ + no_result_count: int = Field(alias="noResultCount") + """ Number of searches without any results. """ + dates: List[DailyNoResultsRates] = Field(alias="dates") + """ Daily no results rates. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetNoResultsRateResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.dates: - for _item in self.dates: - if _item: - _items.append(_item.to_dict()) - _dict["dates"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetNoResultsRateResponse from a dict""" if obj is None: return None @@ -83,16 +67,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "rate": obj.get("rate"), - "count": obj.get("count"), - "noResultCount": obj.get("noResultCount"), - "dates": ( - [DailyNoResultsRates.from_dict(_item) for _item in obj.get("dates")] - if obj.get("dates") is not None - else None - ), - } + obj["dates"] = ( + [DailyNoResultsRates.from_dict(_item) for _item in obj["dates"]] + if obj.get("dates") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_purchase_rate_response.py b/algoliasearch/analytics/models/get_purchase_rate_response.py index 666b57762..c73a0fa0d 100644 --- a/algoliasearch/analytics/models/get_purchase_rate_response.py +++ b/algoliasearch/analytics/models/get_purchase_rate_response.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.analytics.models.daily_purchase_rates import DailyPurchaseRates @@ -26,61 +26,40 @@ class GetPurchaseRateResponse(BaseModel): GetPurchaseRateResponse """ - rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Purchase rate, calculated as number of tracked searches with at least one purchase event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. " - ) - tracked_search_count: StrictInt = Field( - description="Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true.", - alias="trackedSearchCount", - ) - purchase_count: StrictInt = Field( - description="Number of purchase events from this search.", alias="purchaseCount" - ) - dates: List[DailyPurchaseRates] = Field(description="Daily purchase rates.") + rate: float = Field(alias="rate") + """ Purchase rate, calculated as number of tracked searches with at least one purchase event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + tracked_search_count: int = Field(alias="trackedSearchCount") + """ Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true. """ + purchase_count: int = Field(alias="purchaseCount") + """ Number of purchase events from this search. """ + dates: List[DailyPurchaseRates] = Field(alias="dates") + """ Daily purchase rates. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetPurchaseRateResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.dates: - for _item in self.dates: - if _item: - _items.append(_item.to_dict()) - _dict["dates"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetPurchaseRateResponse from a dict""" if obj is None: return None @@ -88,16 +67,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "rate": obj.get("rate"), - "trackedSearchCount": obj.get("trackedSearchCount"), - "purchaseCount": obj.get("purchaseCount"), - "dates": ( - [DailyPurchaseRates.from_dict(_item) for _item in obj.get("dates")] - if obj.get("dates") is not None - else None - ), - } + obj["dates"] = ( + [DailyPurchaseRates.from_dict(_item) for _item in obj["dates"]] + if obj.get("dates") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_revenue.py b/algoliasearch/analytics/models/get_revenue.py index 9a37afda6..cda71e22f 100644 --- a/algoliasearch/analytics/models/get_revenue.py +++ b/algoliasearch/analytics/models/get_revenue.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -27,55 +27,36 @@ class GetRevenue(BaseModel): GetRevenue """ - currencies: Dict[str, CurrencyCode] = Field( - description="Revenue associated with this search, broken-down by currencies." - ) - dates: List[DailyRevenue] = Field(description="Daily revenue.") + currencies: Dict[str, CurrencyCode] = Field(alias="currencies") + """ Revenue associated with this search, broken-down by currencies. """ + dates: List[DailyRevenue] = Field(alias="dates") + """ Daily revenue. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetRevenue from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _field_dict = {} - if self.currencies: - for _key in self.currencies: - if self.currencies[_key]: - _field_dict[_key] = self.currencies[_key].to_dict() - _dict["currencies"] = _field_dict - _items = [] - if self.dates: - for _item in self.dates: - if _item: - _items.append(_item.to_dict()) - _dict["dates"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetRevenue from a dict""" if obj is None: return None @@ -83,21 +64,17 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "currencies": ( - dict( - (_k, CurrencyCode.from_dict(_v)) - for _k, _v in obj.get("currencies").items() - ) - if obj.get("currencies") is not None - else None - ), - "dates": ( - [DailyRevenue.from_dict(_item) for _item in obj.get("dates")] - if obj.get("dates") is not None - else None - ), - } + obj["currencies"] = ( + dict( + (_k, CurrencyCode.from_dict(_v)) for _k, _v in obj["currencies"].items() + ) + if obj.get("currencies") is not None + else None ) - return _obj + obj["dates"] = ( + [DailyRevenue.from_dict(_item) for _item in obj["dates"]] + if obj.get("dates") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_searches_count_response.py b/algoliasearch/analytics/models/get_searches_count_response.py index 22e29a468..2d1e3d9ec 100644 --- a/algoliasearch/analytics/models/get_searches_count_response.py +++ b/algoliasearch/analytics/models/get_searches_count_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,47 +26,36 @@ class GetSearchesCountResponse(BaseModel): GetSearchesCountResponse """ - count: StrictInt = Field(description="Number of occurrences.") - dates: List[DailySearches] = Field(description="Daily number of searches.") + count: int = Field(alias="count") + """ Number of occurrences. """ + dates: List[DailySearches] = Field(alias="dates") + """ Daily number of searches. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetSearchesCountResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.dates: - for _item in self.dates: - if _item: - _items.append(_item.to_dict()) - _dict["dates"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetSearchesCountResponse from a dict""" if obj is None: return None @@ -74,14 +63,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "count": obj.get("count"), - "dates": ( - [DailySearches.from_dict(_item) for _item in obj.get("dates")] - if obj.get("dates") is not None - else None - ), - } + obj["dates"] = ( + [DailySearches.from_dict(_item) for _item in obj["dates"]] + if obj.get("dates") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_searches_no_clicks_response.py b/algoliasearch/analytics/models/get_searches_no_clicks_response.py index 68cb00ea8..6aac28d9c 100644 --- a/algoliasearch/analytics/models/get_searches_no_clicks_response.py +++ b/algoliasearch/analytics/models/get_searches_no_clicks_response.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -28,48 +28,34 @@ class GetSearchesNoClicksResponse(BaseModel): GetSearchesNoClicksResponse """ - searches: List[DailySearchesNoClicks] = Field( - description="Searches without any clicks." - ) + searches: List[DailySearchesNoClicks] = Field(alias="searches") + """ Searches without any clicks. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetSearchesNoClicksResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.searches: - for _item in self.searches: - if _item: - _items.append(_item.to_dict()) - _dict["searches"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetSearchesNoClicksResponse from a dict""" if obj is None: return None @@ -77,16 +63,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "searches": ( - [ - DailySearchesNoClicks.from_dict(_item) - for _item in obj.get("searches") - ] - if obj.get("searches") is not None - else None - ) - } + obj["searches"] = ( + [DailySearchesNoClicks.from_dict(_item) for _item in obj["searches"]] + if obj.get("searches") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_searches_no_results_response.py b/algoliasearch/analytics/models/get_searches_no_results_response.py index 5455c0e27..69950be9d 100644 --- a/algoliasearch/analytics/models/get_searches_no_results_response.py +++ b/algoliasearch/analytics/models/get_searches_no_results_response.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -28,48 +28,34 @@ class GetSearchesNoResultsResponse(BaseModel): GetSearchesNoResultsResponse """ - searches: List[DailySearchesNoResults] = Field( - description="Searches without results." - ) + searches: List[DailySearchesNoResults] = Field(alias="searches") + """ Searches without results. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetSearchesNoResultsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.searches: - for _item in self.searches: - if _item: - _items.append(_item.to_dict()) - _dict["searches"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetSearchesNoResultsResponse from a dict""" if obj is None: return None @@ -77,16 +63,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "searches": ( - [ - DailySearchesNoResults.from_dict(_item) - for _item in obj.get("searches") - ] - if obj.get("searches") is not None - else None - ) - } + obj["searches"] = ( + [DailySearchesNoResults.from_dict(_item) for _item in obj["searches"]] + if obj.get("searches") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_status_response.py b/algoliasearch/analytics/models/get_status_response.py index 423350ee6..558e35d9c 100644 --- a/algoliasearch/analytics/models/get_status_response.py +++ b/algoliasearch/analytics/models/get_status_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,34 @@ class GetStatusResponse(BaseModel): GetStatusResponse """ - updated_at: Optional[StrictStr] = Field( - description="Date and time when the object was updated, in RFC 3339 format. ", - alias="updatedAt", - ) + updated_at: str = Field(alias="updatedAt") + """ Date and time when the object was updated, in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetStatusResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetStatusResponse from a dict""" if obj is None: return None @@ -67,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"updatedAt": obj.get("updatedAt")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_top_countries_response.py b/algoliasearch/analytics/models/get_top_countries_response.py index b09b8a559..200b13ec4 100644 --- a/algoliasearch/analytics/models/get_top_countries_response.py +++ b/algoliasearch/analytics/models/get_top_countries_response.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -26,46 +26,34 @@ class GetTopCountriesResponse(BaseModel): GetTopCountriesResponse """ - countries: List[TopCountry] = Field(description="Countries and number of searches.") + countries: List[TopCountry] = Field(alias="countries") + """ Countries and number of searches. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetTopCountriesResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.countries: - for _item in self.countries: - if _item: - _items.append(_item.to_dict()) - _dict["countries"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetTopCountriesResponse from a dict""" if obj is None: return None @@ -73,13 +61,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "countries": ( - [TopCountry.from_dict(_item) for _item in obj.get("countries")] - if obj.get("countries") is not None - else None - ) - } + obj["countries"] = ( + [TopCountry.from_dict(_item) for _item in obj["countries"]] + if obj.get("countries") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_top_filter_attribute.py b/algoliasearch/analytics/models/get_top_filter_attribute.py index 4e7a69ac7..d4e66a4b4 100644 --- a/algoliasearch/analytics/models/get_top_filter_attribute.py +++ b/algoliasearch/analytics/models/get_top_filter_attribute.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,41 +23,36 @@ class GetTopFilterAttribute(BaseModel): GetTopFilterAttribute """ - attribute: StrictStr = Field(description="Attribute name.") - count: StrictInt = Field(description="Number of occurrences.") + attribute: str = Field(alias="attribute") + """ Attribute name. """ + count: int = Field(alias="count") + """ Number of occurrences. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetTopFilterAttribute from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetTopFilterAttribute from a dict""" if obj is None: return None @@ -65,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"attribute": obj.get("attribute"), "count": obj.get("count")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_top_filter_attributes_response.py b/algoliasearch/analytics/models/get_top_filter_attributes_response.py index c61f7e5dd..2ac563a7b 100644 --- a/algoliasearch/analytics/models/get_top_filter_attributes_response.py +++ b/algoliasearch/analytics/models/get_top_filter_attributes_response.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -28,48 +28,34 @@ class GetTopFilterAttributesResponse(BaseModel): GetTopFilterAttributesResponse """ - attributes: List[GetTopFilterAttribute] = Field( - description="Most frequent filters." - ) + attributes: List[GetTopFilterAttribute] = Field(alias="attributes") + """ Most frequent filters. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetTopFilterAttributesResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.attributes: - for _item in self.attributes: - if _item: - _items.append(_item.to_dict()) - _dict["attributes"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetTopFilterAttributesResponse from a dict""" if obj is None: return None @@ -77,16 +63,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "attributes": ( - [ - GetTopFilterAttribute.from_dict(_item) - for _item in obj.get("attributes") - ] - if obj.get("attributes") is not None - else None - ) - } + obj["attributes"] = ( + [GetTopFilterAttribute.from_dict(_item) for _item in obj["attributes"]] + if obj.get("attributes") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_top_filter_for_attribute.py b/algoliasearch/analytics/models/get_top_filter_for_attribute.py index 99ea61056..1b7558075 100644 --- a/algoliasearch/analytics/models/get_top_filter_for_attribute.py +++ b/algoliasearch/analytics/models/get_top_filter_for_attribute.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,43 +26,39 @@ class GetTopFilterForAttribute(BaseModel): GetTopFilterForAttribute """ - attribute: StrictStr = Field(description="Attribute name.") - operator: Operator - value: StrictStr = Field(description="Attribute value.") - count: StrictInt = Field(description="Number of occurrences.") + attribute: str = Field(alias="attribute") + """ Attribute name. """ + operator: Operator = Field(alias="operator") + value: str = Field(alias="value") + """ Attribute value. """ + count: int = Field(alias="count") + """ Number of occurrences. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetTopFilterForAttribute from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetTopFilterForAttribute from a dict""" if obj is None: return None @@ -70,12 +66,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "attribute": obj.get("attribute"), - "operator": obj.get("operator"), - "value": obj.get("value"), - "count": obj.get("count"), - } - ) - return _obj + obj["operator"] = obj.get("operator") + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_top_filter_for_attribute_response.py b/algoliasearch/analytics/models/get_top_filter_for_attribute_response.py index d72220d1a..ae2b3dd53 100644 --- a/algoliasearch/analytics/models/get_top_filter_for_attribute_response.py +++ b/algoliasearch/analytics/models/get_top_filter_for_attribute_response.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -28,48 +28,34 @@ class GetTopFilterForAttributeResponse(BaseModel): GetTopFilterForAttributeResponse """ - values: List[GetTopFilterForAttribute] = Field( - description="Filter values for an attribute." - ) + values: List[GetTopFilterForAttribute] = Field(alias="values") + """ Filter values for an attribute. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetTopFilterForAttributeResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.values: - for _item in self.values: - if _item: - _items.append(_item.to_dict()) - _dict["values"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetTopFilterForAttributeResponse from a dict""" if obj is None: return None @@ -77,16 +63,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "values": ( - [ - GetTopFilterForAttribute.from_dict(_item) - for _item in obj.get("values") - ] - if obj.get("values") is not None - else None - ) - } + obj["values"] = ( + [GetTopFilterForAttribute.from_dict(_item) for _item in obj["values"]] + if obj.get("values") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_top_filters_no_results_response.py b/algoliasearch/analytics/models/get_top_filters_no_results_response.py index 2c313b33d..912db29ea 100644 --- a/algoliasearch/analytics/models/get_top_filters_no_results_response.py +++ b/algoliasearch/analytics/models/get_top_filters_no_results_response.py @@ -28,48 +28,34 @@ class GetTopFiltersNoResultsResponse(BaseModel): GetTopFiltersNoResultsResponse """ - values: Optional[List[GetTopFiltersNoResultsValues]] = Field( - description="Filters for searches without any results. If null, the search term specified with the `search` parameter is not a search without results, or the `search` parameter is absent from the request. " - ) + values: List[GetTopFiltersNoResultsValues] = Field(alias="values") + """ Filters for searches without any results. If null, the search term specified with the `search` parameter is not a search without results, or the `search` parameter is absent from the request. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetTopFiltersNoResultsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.values: - for _item in self.values: - if _item: - _items.append(_item.to_dict()) - _dict["values"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetTopFiltersNoResultsResponse from a dict""" if obj is None: return None @@ -77,16 +63,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "values": ( - [ - GetTopFiltersNoResultsValues.from_dict(_item) - for _item in obj.get("values") - ] - if obj.get("values") is not None - else None - ) - } + obj["values"] = ( + [GetTopFiltersNoResultsValues.from_dict(_item) for _item in obj["values"]] + if obj.get("values") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_top_filters_no_results_value.py b/algoliasearch/analytics/models/get_top_filters_no_results_value.py index 2eb2baf1f..f9b93e8f7 100644 --- a/algoliasearch/analytics/models/get_top_filters_no_results_value.py +++ b/algoliasearch/analytics/models/get_top_filters_no_results_value.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,42 +26,37 @@ class GetTopFiltersNoResultsValue(BaseModel): GetTopFiltersNoResultsValue """ - attribute: StrictStr = Field(description="Attribute name.") - operator: Operator - value: StrictStr = Field(description="Attribute value.") + attribute: str = Field(alias="attribute") + """ Attribute name. """ + operator: Operator = Field(alias="operator") + value: str = Field(alias="value") + """ Attribute value. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetTopFiltersNoResultsValue from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetTopFiltersNoResultsValue from a dict""" if obj is None: return None @@ -69,11 +64,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "attribute": obj.get("attribute"), - "operator": obj.get("operator"), - "value": obj.get("value"), - } - ) - return _obj + obj["operator"] = obj.get("operator") + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_top_filters_no_results_values.py b/algoliasearch/analytics/models/get_top_filters_no_results_values.py index 66c7a8ae4..737c0f196 100644 --- a/algoliasearch/analytics/models/get_top_filters_no_results_values.py +++ b/algoliasearch/analytics/models/get_top_filters_no_results_values.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,49 +28,36 @@ class GetTopFiltersNoResultsValues(BaseModel): GetTopFiltersNoResultsValues """ - count: StrictInt = Field(description="Number of occurrences.") - values: List[GetTopFiltersNoResultsValue] = Field( - description="Filters with no results." - ) + count: int = Field(alias="count") + """ Number of occurrences. """ + values: List[GetTopFiltersNoResultsValue] = Field(alias="values") + """ Filters with no results. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetTopFiltersNoResultsValues from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.values: - for _item in self.values: - if _item: - _items.append(_item.to_dict()) - _dict["values"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetTopFiltersNoResultsValues from a dict""" if obj is None: return None @@ -78,17 +65,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "count": obj.get("count"), - "values": ( - [ - GetTopFiltersNoResultsValue.from_dict(_item) - for _item in obj.get("values") - ] - if obj.get("values") is not None - else None - ), - } + obj["values"] = ( + [GetTopFiltersNoResultsValue.from_dict(_item) for _item in obj["values"]] + if obj.get("values") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/get_top_hits_response.py b/algoliasearch/analytics/models/get_top_hits_response.py index 325af9f8a..b8e3798c6 100644 --- a/algoliasearch/analytics/models/get_top_hits_response.py +++ b/algoliasearch/analytics/models/get_top_hits_response.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -32,9 +32,16 @@ class GetTopHitsResponse(BaseModel): GetTopHitsResponse """ - oneof_schema_1_validator: Optional[TopHitsResponse] = None - oneof_schema_2_validator: Optional[TopHitsResponseWithAnalytics] = None - oneof_schema_3_validator: Optional[TopHitsResponseWithRevenueAnalytics] = None + oneof_schema_1_validator: Optional[TopHitsResponse] = Field(default=None) + + oneof_schema_2_validator: Optional[TopHitsResponseWithAnalytics] = Field( + default=None + ) + + oneof_schema_3_validator: Optional[TopHitsResponseWithRevenueAnalytics] = Field( + default=None + ) + actual_instance: Optional[ Union[ TopHitsResponse, @@ -42,6 +49,11 @@ class GetTopHitsResponse(BaseModel): TopHitsResponseWithRevenueAnalytics, ] ] = None + one_of_schemas: Set[str] = { + "TopHitsResponse", + "TopHitsResponseWithAnalytics", + "TopHitsResponseWithRevenueAnalytics", + } def __init__(self, *args, **kwargs) -> None: if args: @@ -73,7 +85,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of GetTopHitsResponse from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -113,17 +126,30 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[ + Union[ + Dict[str, Any], + TopHitsResponse, + TopHitsResponseWithAnalytics, + TopHitsResponseWithRevenueAnalytics, + ] + ]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/analytics/models/get_top_searches_response.py b/algoliasearch/analytics/models/get_top_searches_response.py index 39d095b25..e4d11b28b 100644 --- a/algoliasearch/analytics/models/get_top_searches_response.py +++ b/algoliasearch/analytics/models/get_top_searches_response.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -32,9 +32,16 @@ class GetTopSearchesResponse(BaseModel): GetTopSearchesResponse """ - oneof_schema_1_validator: Optional[TopSearchesResponse] = None - oneof_schema_2_validator: Optional[TopSearchesResponseWithAnalytics] = None - oneof_schema_3_validator: Optional[TopSearchesResponseWithRevenueAnalytics] = None + oneof_schema_1_validator: Optional[TopSearchesResponse] = Field(default=None) + + oneof_schema_2_validator: Optional[TopSearchesResponseWithAnalytics] = Field( + default=None + ) + + oneof_schema_3_validator: Optional[TopSearchesResponseWithRevenueAnalytics] = Field( + default=None + ) + actual_instance: Optional[ Union[ TopSearchesResponse, @@ -42,6 +49,11 @@ class GetTopSearchesResponse(BaseModel): TopSearchesResponseWithRevenueAnalytics, ] ] = None + one_of_schemas: Set[str] = { + "TopSearchesResponse", + "TopSearchesResponseWithAnalytics", + "TopSearchesResponseWithRevenueAnalytics", + } def __init__(self, *args, **kwargs) -> None: if args: @@ -73,7 +85,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of GetTopSearchesResponse from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -115,17 +128,30 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[ + Union[ + Dict[str, Any], + TopSearchesResponse, + TopSearchesResponseWithAnalytics, + TopSearchesResponseWithRevenueAnalytics, + ] + ]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/analytics/models/get_users_count_response.py b/algoliasearch/analytics/models/get_users_count_response.py index c6c469f0b..d7bd8e473 100644 --- a/algoliasearch/analytics/models/get_users_count_response.py +++ b/algoliasearch/analytics/models/get_users_count_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,47 +26,36 @@ class GetUsersCountResponse(BaseModel): GetUsersCountResponse """ - count: StrictInt = Field(description="Number of unique users.") - dates: List[DailyUsers] = Field(description="Daily number of unique users.") + count: int = Field(alias="count") + """ Number of unique users. """ + dates: List[DailyUsers] = Field(alias="dates") + """ Daily number of unique users. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetUsersCountResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.dates: - for _item in self.dates: - if _item: - _items.append(_item.to_dict()) - _dict["dates"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetUsersCountResponse from a dict""" if obj is None: return None @@ -74,14 +63,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "count": obj.get("count"), - "dates": ( - [DailyUsers.from_dict(_item) for _item in obj.get("dates")] - if obj.get("dates") is not None - else None - ), - } + obj["dates"] = ( + [DailyUsers.from_dict(_item) for _item in obj["dates"]] + if obj.get("dates") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/operator.py b/algoliasearch/analytics/models/operator.py index 318d0191b..da14cffc4 100644 --- a/algoliasearch/analytics/models/operator.py +++ b/algoliasearch/analytics/models/operator.py @@ -25,11 +25,17 @@ class Operator(str, Enum): allowed enum values """ COLON = ":" + LESS_THAN = "<" + LESS_THAN_EQUAL = "<=" + EQUAL = "=" + EXCLAMATION_EQUAL = "!=" + GREATER_THAN = ">" + GREATER_THAN_EQUAL = ">=" @classmethod diff --git a/algoliasearch/analytics/models/order_by.py b/algoliasearch/analytics/models/order_by.py index 34c6f3483..2108f1074 100644 --- a/algoliasearch/analytics/models/order_by.py +++ b/algoliasearch/analytics/models/order_by.py @@ -25,8 +25,11 @@ class OrderBy(str, Enum): allowed enum values """ SEARCHCOUNT = "searchCount" + CLICKTHROUGHRATE = "clickThroughRate" + CONVERSIONRATE = "conversionRate" + AVERAGECLICKPOSITION = "averageClickPosition" @classmethod diff --git a/algoliasearch/analytics/models/top_country.py b/algoliasearch/analytics/models/top_country.py index 8f63734f2..f8fbccb9a 100644 --- a/algoliasearch/analytics/models/top_country.py +++ b/algoliasearch/analytics/models/top_country.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,41 +23,36 @@ class TopCountry(BaseModel): TopCountry """ - country: StrictStr = Field(description="Country code.") - count: StrictInt = Field(description="Number of occurrences.") + country: str = Field(alias="country") + """ Country code. """ + count: int = Field(alias="count") + """ Number of occurrences. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TopCountry from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TopCountry from a dict""" if obj is None: return None @@ -65,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"country": obj.get("country"), "count": obj.get("count")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/top_hit.py b/algoliasearch/analytics/models/top_hit.py index e190637b0..c035e446b 100644 --- a/algoliasearch/analytics/models/top_hit.py +++ b/algoliasearch/analytics/models/top_hit.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,36 @@ class TopHit(BaseModel): TopHit """ - hit: StrictStr = Field( - description="Object ID of a record that's returned as a search result." - ) - count: StrictInt = Field(description="Number of occurrences.") + hit: str = Field(alias="hit") + """ Object ID of a record that's returned as a search result. """ + count: int = Field(alias="count") + """ Number of occurrences. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TopHit from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TopHit from a dict""" if obj is None: return None @@ -67,5 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"hit": obj.get("hit"), "count": obj.get("count")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/top_hit_with_analytics.py b/algoliasearch/analytics/models/top_hit_with_analytics.py index 582c4ddc1..64b5ecf25 100644 --- a/algoliasearch/analytics/models/top_hit_with_analytics.py +++ b/algoliasearch/analytics/models/top_hit_with_analytics.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class TopHitWithAnalytics(BaseModel): @@ -23,71 +23,46 @@ class TopHitWithAnalytics(BaseModel): TopHitWithAnalytics """ - hit: StrictStr = Field( - description="Object ID of a record that's returned as a search result." - ) - count: StrictInt = Field(description="Number of occurrences.") - click_through_rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Click-through rate, calculated as number of tracked searches with at least one click event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. ", - alias="clickThroughRate", - ) - conversion_rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Conversion rate, calculated as number of tracked searches with at least one conversion event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. ", - alias="conversionRate", - ) - tracked_hit_count: StrictInt = Field( - description="Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true.", - alias="trackedHitCount", - ) - click_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of clicks associated with this search.", alias="clickCount" - ) - conversion_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of conversions from this search.", alias="conversionCount" - ) + hit: str = Field(alias="hit") + """ Object ID of a record that's returned as a search result. """ + count: int = Field(alias="count") + """ Number of occurrences. """ + click_through_rate: float = Field(alias="clickThroughRate") + """ Click-through rate, calculated as number of tracked searches with at least one click event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + conversion_rate: float = Field(alias="conversionRate") + """ Conversion rate, calculated as number of tracked searches with at least one conversion event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + tracked_hit_count: int = Field(alias="trackedHitCount") + """ Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true. """ + click_count: int = Field(alias="clickCount") + """ Number of clicks associated with this search. """ + conversion_count: int = Field(alias="conversionCount") + """ Number of conversions from this search. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TopHitWithAnalytics from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TopHitWithAnalytics from a dict""" if obj is None: return None @@ -95,15 +70,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "hit": obj.get("hit"), - "count": obj.get("count"), - "clickThroughRate": obj.get("clickThroughRate"), - "conversionRate": obj.get("conversionRate"), - "trackedHitCount": obj.get("trackedHitCount"), - "clickCount": obj.get("clickCount"), - "conversionCount": obj.get("conversionCount"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/top_hit_with_revenue_analytics.py b/algoliasearch/analytics/models/top_hit_with_revenue_analytics.py index 8841ff2f7..a166649c2 100644 --- a/algoliasearch/analytics/models/top_hit_with_revenue_analytics.py +++ b/algoliasearch/analytics/models/top_hit_with_revenue_analytics.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.analytics.models.currency_code import CurrencyCode @@ -26,105 +26,56 @@ class TopHitWithRevenueAnalytics(BaseModel): TopHitWithRevenueAnalytics """ - hit: StrictStr = Field( - description="Object ID of a record that's returned as a search result." - ) - count: StrictInt = Field(description="Number of occurrences.") - click_through_rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Click-through rate, calculated as number of tracked searches with at least one click event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. ", - alias="clickThroughRate", - ) - conversion_rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Conversion rate, calculated as number of tracked searches with at least one conversion event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. ", - alias="conversionRate", - ) - tracked_hit_count: StrictInt = Field( - description="Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true.", - alias="trackedHitCount", - ) - click_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of clicks associated with this search.", alias="clickCount" - ) - conversion_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of conversions from this search.", alias="conversionCount" - ) - add_to_cart_rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Add-to-cart rate, calculated as number of tracked searches with at least one add-to-cart event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. ", - alias="addToCartRate", - ) - add_to_cart_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of add-to-cart events from this search.", - alias="addToCartCount", - ) - purchase_rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Purchase rate, calculated as number of tracked searches with at least one purchase event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. ", - alias="purchaseRate", - ) - purchase_count: StrictInt = Field( - description="Number of purchase events from this search.", alias="purchaseCount" - ) - currencies: Dict[str, CurrencyCode] = Field( - description="Revenue associated with this search, broken-down by currencies." - ) + hit: str = Field(alias="hit") + """ Object ID of a record that's returned as a search result. """ + count: int = Field(alias="count") + """ Number of occurrences. """ + click_through_rate: float = Field(alias="clickThroughRate") + """ Click-through rate, calculated as number of tracked searches with at least one click event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + conversion_rate: float = Field(alias="conversionRate") + """ Conversion rate, calculated as number of tracked searches with at least one conversion event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + tracked_hit_count: int = Field(alias="trackedHitCount") + """ Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true. """ + click_count: int = Field(alias="clickCount") + """ Number of clicks associated with this search. """ + conversion_count: int = Field(alias="conversionCount") + """ Number of conversions from this search. """ + add_to_cart_rate: float = Field(alias="addToCartRate") + """ Add-to-cart rate, calculated as number of tracked searches with at least one add-to-cart event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + add_to_cart_count: int = Field(alias="addToCartCount") + """ Number of add-to-cart events from this search. """ + purchase_rate: float = Field(alias="purchaseRate") + """ Purchase rate, calculated as number of tracked searches with at least one purchase event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + purchase_count: int = Field(alias="purchaseCount") + """ Number of purchase events from this search. """ + currencies: Dict[str, CurrencyCode] = Field(alias="currencies") + """ Revenue associated with this search, broken-down by currencies. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TopHitWithRevenueAnalytics from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _field_dict = {} - if self.currencies: - for _key in self.currencies: - if self.currencies[_key]: - _field_dict[_key] = self.currencies[_key].to_dict() - _dict["currencies"] = _field_dict - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TopHitWithRevenueAnalytics from a dict""" if obj is None: return None @@ -132,27 +83,12 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "hit": obj.get("hit"), - "count": obj.get("count"), - "clickThroughRate": obj.get("clickThroughRate"), - "conversionRate": obj.get("conversionRate"), - "trackedHitCount": obj.get("trackedHitCount"), - "clickCount": obj.get("clickCount"), - "conversionCount": obj.get("conversionCount"), - "addToCartRate": obj.get("addToCartRate"), - "addToCartCount": obj.get("addToCartCount"), - "purchaseRate": obj.get("purchaseRate"), - "purchaseCount": obj.get("purchaseCount"), - "currencies": ( - dict( - (_k, CurrencyCode.from_dict(_v)) - for _k, _v in obj.get("currencies").items() - ) - if obj.get("currencies") is not None - else None - ), - } + obj["currencies"] = ( + dict( + (_k, CurrencyCode.from_dict(_v)) for _k, _v in obj["currencies"].items() + ) + if obj.get("currencies") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/top_hits_response.py b/algoliasearch/analytics/models/top_hits_response.py index bf680e2d2..8e2098b8d 100644 --- a/algoliasearch/analytics/models/top_hits_response.py +++ b/algoliasearch/analytics/models/top_hits_response.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -26,46 +26,34 @@ class TopHitsResponse(BaseModel): TopHitsResponse """ - hits: List[TopHit] = Field(description="Most frequent search results.") + hits: List[TopHit] = Field(alias="hits") + """ Most frequent search results. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TopHitsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.hits: - for _item in self.hits: - if _item: - _items.append(_item.to_dict()) - _dict["hits"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TopHitsResponse from a dict""" if obj is None: return None @@ -73,13 +61,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "hits": ( - [TopHit.from_dict(_item) for _item in obj.get("hits")] - if obj.get("hits") is not None - else None - ) - } + obj["hits"] = ( + [TopHit.from_dict(_item) for _item in obj["hits"]] + if obj.get("hits") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/top_hits_response_with_analytics.py b/algoliasearch/analytics/models/top_hits_response_with_analytics.py index 092b572bc..499374ed3 100644 --- a/algoliasearch/analytics/models/top_hits_response_with_analytics.py +++ b/algoliasearch/analytics/models/top_hits_response_with_analytics.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -26,48 +26,34 @@ class TopHitsResponseWithAnalytics(BaseModel): TopHitsResponseWithAnalytics """ - hits: List[TopHitWithAnalytics] = Field( - description="Most frequent search results with click and conversion metrics." - ) + hits: List[TopHitWithAnalytics] = Field(alias="hits") + """ Most frequent search results with click and conversion metrics. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TopHitsResponseWithAnalytics from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.hits: - for _item in self.hits: - if _item: - _items.append(_item.to_dict()) - _dict["hits"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TopHitsResponseWithAnalytics from a dict""" if obj is None: return None @@ -75,13 +61,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "hits": ( - [TopHitWithAnalytics.from_dict(_item) for _item in obj.get("hits")] - if obj.get("hits") is not None - else None - ) - } + obj["hits"] = ( + [TopHitWithAnalytics.from_dict(_item) for _item in obj["hits"]] + if obj.get("hits") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/top_hits_response_with_revenue_analytics.py b/algoliasearch/analytics/models/top_hits_response_with_revenue_analytics.py index 393b0076f..dd77747c1 100644 --- a/algoliasearch/analytics/models/top_hits_response_with_revenue_analytics.py +++ b/algoliasearch/analytics/models/top_hits_response_with_revenue_analytics.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -28,48 +28,34 @@ class TopHitsResponseWithRevenueAnalytics(BaseModel): TopHitsResponseWithRevenueAnalytics """ - hits: List[TopHitWithRevenueAnalytics] = Field( - description="Most frequent search results with click, conversion, and revenue metrics." - ) + hits: List[TopHitWithRevenueAnalytics] = Field(alias="hits") + """ Most frequent search results with click, conversion, and revenue metrics. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TopHitsResponseWithRevenueAnalytics from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.hits: - for _item in self.hits: - if _item: - _items.append(_item.to_dict()) - _dict["hits"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TopHitsResponseWithRevenueAnalytics from a dict""" if obj is None: return None @@ -77,16 +63,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "hits": ( - [ - TopHitWithRevenueAnalytics.from_dict(_item) - for _item in obj.get("hits") - ] - if obj.get("hits") is not None - else None - ) - } + obj["hits"] = ( + [TopHitWithRevenueAnalytics.from_dict(_item) for _item in obj["hits"]] + if obj.get("hits") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/top_search.py b/algoliasearch/analytics/models/top_search.py index 87ea26806..dd1ddb989 100644 --- a/algoliasearch/analytics/models/top_search.py +++ b/algoliasearch/analytics/models/top_search.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,42 +23,38 @@ class TopSearch(BaseModel): TopSearch """ - search: StrictStr = Field(description="Search query.") - count: StrictInt = Field(description="Number of searches.") - nb_hits: StrictInt = Field(description="Number of results (hits).", alias="nbHits") + search: str = Field(alias="search") + """ Search query. """ + count: int = Field(alias="count") + """ Number of searches. """ + nb_hits: int = Field(alias="nbHits") + """ Number of results (hits). """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TopSearch from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TopSearch from a dict""" if obj is None: return None @@ -66,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "search": obj.get("search"), - "count": obj.get("count"), - "nbHits": obj.get("nbHits"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/top_search_with_analytics.py b/algoliasearch/analytics/models/top_search_with_analytics.py index 8007f20b7..7a2da7adf 100644 --- a/algoliasearch/analytics/models/top_search_with_analytics.py +++ b/algoliasearch/analytics/models/top_search_with_analytics.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.analytics.models.click_position import ClickPosition @@ -26,91 +26,52 @@ class TopSearchWithAnalytics(BaseModel): TopSearchWithAnalytics """ - search: StrictStr = Field(description="Search query.") - count: StrictInt = Field(description="Number of searches.") - click_through_rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Click-through rate, calculated as number of tracked searches with at least one click event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. ", - alias="clickThroughRate", - ) - average_click_position: Optional[ - Union[ - Annotated[float, Field(strict=True, ge=1)], - Annotated[int, Field(strict=True, ge=1)], - ] - ] = Field( - description="Average position of a clicked search result in the list of search results. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. ", - alias="averageClickPosition", - ) - click_positions: Annotated[ - List[ClickPosition], Field(min_length=12, max_length=12) - ] = Field( - description="List of positions in the search results and clicks associated with this search.", - alias="clickPositions", - ) - conversion_rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Conversion rate, calculated as number of tracked searches with at least one conversion event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. ", - alias="conversionRate", - ) - tracked_search_count: StrictInt = Field( - description="Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true.", - alias="trackedSearchCount", - ) - click_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of clicks associated with this search.", alias="clickCount" - ) - conversion_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of conversions from this search.", alias="conversionCount" - ) - nb_hits: StrictInt = Field(description="Number of results (hits).", alias="nbHits") + search: str = Field(alias="search") + """ Search query. """ + count: int = Field(alias="count") + """ Number of searches. """ + click_through_rate: float = Field(alias="clickThroughRate") + """ Click-through rate, calculated as number of tracked searches with at least one click event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + average_click_position: float = Field(alias="averageClickPosition") + """ Average position of a clicked search result in the list of search results. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + click_positions: List[ClickPosition] = Field(alias="clickPositions") + """ List of positions in the search results and clicks associated with this search. """ + conversion_rate: float = Field(alias="conversionRate") + """ Conversion rate, calculated as number of tracked searches with at least one conversion event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + tracked_search_count: int = Field(alias="trackedSearchCount") + """ Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true. """ + click_count: int = Field(alias="clickCount") + """ Number of clicks associated with this search. """ + conversion_count: int = Field(alias="conversionCount") + """ Number of conversions from this search. """ + nb_hits: int = Field(alias="nbHits") + """ Number of results (hits). """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TopSearchWithAnalytics from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.click_positions: - for _item in self.click_positions: - if _item: - _items.append(_item.to_dict()) - _dict["clickPositions"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TopSearchWithAnalytics from a dict""" if obj is None: return None @@ -118,25 +79,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "search": obj.get("search"), - "count": obj.get("count"), - "clickThroughRate": obj.get("clickThroughRate"), - "averageClickPosition": obj.get("averageClickPosition"), - "clickPositions": ( - [ - ClickPosition.from_dict(_item) - for _item in obj.get("clickPositions") - ] - if obj.get("clickPositions") is not None - else None - ), - "conversionRate": obj.get("conversionRate"), - "trackedSearchCount": obj.get("trackedSearchCount"), - "clickCount": obj.get("clickCount"), - "conversionCount": obj.get("conversionCount"), - "nbHits": obj.get("nbHits"), - } + obj["clickPositions"] = ( + [ClickPosition.from_dict(_item) for _item in obj["clickPositions"]] + if obj.get("clickPositions") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/top_search_with_revenue_analytics.py b/algoliasearch/analytics/models/top_search_with_revenue_analytics.py index db35fc4dc..1b9f35cfc 100644 --- a/algoliasearch/analytics/models/top_search_with_revenue_analytics.py +++ b/algoliasearch/analytics/models/top_search_with_revenue_analytics.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.analytics.models.click_position import ClickPosition @@ -27,125 +27,62 @@ class TopSearchWithRevenueAnalytics(BaseModel): TopSearchWithRevenueAnalytics """ - search: StrictStr = Field(description="Search query.") - count: StrictInt = Field(description="Number of searches.") - click_through_rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Click-through rate, calculated as number of tracked searches with at least one click event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. ", - alias="clickThroughRate", - ) - average_click_position: Optional[ - Union[ - Annotated[float, Field(strict=True, ge=1)], - Annotated[int, Field(strict=True, ge=1)], - ] - ] = Field( - description="Average position of a clicked search result in the list of search results. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. ", - alias="averageClickPosition", - ) - click_positions: Annotated[ - List[ClickPosition], Field(min_length=12, max_length=12) - ] = Field( - description="List of positions in the search results and clicks associated with this search.", - alias="clickPositions", - ) - conversion_rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Conversion rate, calculated as number of tracked searches with at least one conversion event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. ", - alias="conversionRate", - ) - tracked_search_count: StrictInt = Field( - description="Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true.", - alias="trackedSearchCount", - ) - click_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of clicks associated with this search.", alias="clickCount" - ) - conversion_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of conversions from this search.", alias="conversionCount" - ) - nb_hits: StrictInt = Field(description="Number of results (hits).", alias="nbHits") - currencies: Dict[str, CurrencyCode] = Field( - description="Revenue associated with this search, broken-down by currencies." - ) - add_to_cart_rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Add-to-cart rate, calculated as number of tracked searches with at least one add-to-cart event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. ", - alias="addToCartRate", - ) - add_to_cart_count: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of add-to-cart events from this search.", - alias="addToCartCount", - ) - purchase_rate: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - description="Purchase rate, calculated as number of tracked searches with at least one purchase event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. ", - alias="purchaseRate", - ) - purchase_count: StrictInt = Field( - description="Number of purchase events from this search.", alias="purchaseCount" - ) + search: str = Field(alias="search") + """ Search query. """ + count: int = Field(alias="count") + """ Number of searches. """ + click_through_rate: float = Field(alias="clickThroughRate") + """ Click-through rate, calculated as number of tracked searches with at least one click event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + average_click_position: float = Field(alias="averageClickPosition") + """ Average position of a clicked search result in the list of search results. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + click_positions: List[ClickPosition] = Field(alias="clickPositions") + """ List of positions in the search results and clicks associated with this search. """ + conversion_rate: float = Field(alias="conversionRate") + """ Conversion rate, calculated as number of tracked searches with at least one conversion event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + tracked_search_count: int = Field(alias="trackedSearchCount") + """ Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true. """ + click_count: int = Field(alias="clickCount") + """ Number of clicks associated with this search. """ + conversion_count: int = Field(alias="conversionCount") + """ Number of conversions from this search. """ + nb_hits: int = Field(alias="nbHits") + """ Number of results (hits). """ + currencies: Dict[str, CurrencyCode] = Field(alias="currencies") + """ Revenue associated with this search, broken-down by currencies. """ + add_to_cart_rate: float = Field(alias="addToCartRate") + """ Add-to-cart rate, calculated as number of tracked searches with at least one add-to-cart event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + add_to_cart_count: int = Field(alias="addToCartCount") + """ Number of add-to-cart events from this search. """ + purchase_rate: float = Field(alias="purchaseRate") + """ Purchase rate, calculated as number of tracked searches with at least one purchase event divided by the number of tracked searches. If null, Algolia didn't receive any search requests with `clickAnalytics` set to true. """ + purchase_count: int = Field(alias="purchaseCount") + """ Number of purchase events from this search. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TopSearchWithRevenueAnalytics from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.click_positions: - for _item in self.click_positions: - if _item: - _items.append(_item.to_dict()) - _dict["clickPositions"] = _items - _field_dict = {} - if self.currencies: - for _key in self.currencies: - if self.currencies[_key]: - _field_dict[_key] = self.currencies[_key].to_dict() - _dict["currencies"] = _field_dict - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TopSearchWithRevenueAnalytics from a dict""" if obj is None: return None @@ -153,37 +90,17 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "search": obj.get("search"), - "count": obj.get("count"), - "clickThroughRate": obj.get("clickThroughRate"), - "averageClickPosition": obj.get("averageClickPosition"), - "clickPositions": ( - [ - ClickPosition.from_dict(_item) - for _item in obj.get("clickPositions") - ] - if obj.get("clickPositions") is not None - else None - ), - "conversionRate": obj.get("conversionRate"), - "trackedSearchCount": obj.get("trackedSearchCount"), - "clickCount": obj.get("clickCount"), - "conversionCount": obj.get("conversionCount"), - "nbHits": obj.get("nbHits"), - "currencies": ( - dict( - (_k, CurrencyCode.from_dict(_v)) - for _k, _v in obj.get("currencies").items() - ) - if obj.get("currencies") is not None - else None - ), - "addToCartRate": obj.get("addToCartRate"), - "addToCartCount": obj.get("addToCartCount"), - "purchaseRate": obj.get("purchaseRate"), - "purchaseCount": obj.get("purchaseCount"), - } + obj["clickPositions"] = ( + [ClickPosition.from_dict(_item) for _item in obj["clickPositions"]] + if obj.get("clickPositions") is not None + else None ) - return _obj + obj["currencies"] = ( + dict( + (_k, CurrencyCode.from_dict(_v)) for _k, _v in obj["currencies"].items() + ) + if obj.get("currencies") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/top_searches_response.py b/algoliasearch/analytics/models/top_searches_response.py index 6d4961c23..193775b9b 100644 --- a/algoliasearch/analytics/models/top_searches_response.py +++ b/algoliasearch/analytics/models/top_searches_response.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -26,48 +26,34 @@ class TopSearchesResponse(BaseModel): TopSearchesResponse """ - searches: List[TopSearch] = Field( - description="Most popular searches and their number of search results (hits)." - ) + searches: List[TopSearch] = Field(alias="searches") + """ Most popular searches and their number of search results (hits). """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TopSearchesResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.searches: - for _item in self.searches: - if _item: - _items.append(_item.to_dict()) - _dict["searches"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TopSearchesResponse from a dict""" if obj is None: return None @@ -75,13 +61,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "searches": ( - [TopSearch.from_dict(_item) for _item in obj.get("searches")] - if obj.get("searches") is not None - else None - ) - } + obj["searches"] = ( + [TopSearch.from_dict(_item) for _item in obj["searches"]] + if obj.get("searches") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/top_searches_response_with_analytics.py b/algoliasearch/analytics/models/top_searches_response_with_analytics.py index d47f13e6e..1ebf8a523 100644 --- a/algoliasearch/analytics/models/top_searches_response_with_analytics.py +++ b/algoliasearch/analytics/models/top_searches_response_with_analytics.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -28,48 +28,34 @@ class TopSearchesResponseWithAnalytics(BaseModel): TopSearchesResponseWithAnalytics """ - searches: List[TopSearchWithAnalytics] = Field( - description="Most popular searches and their associated click and conversion metrics." - ) + searches: List[TopSearchWithAnalytics] = Field(alias="searches") + """ Most popular searches and their associated click and conversion metrics. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TopSearchesResponseWithAnalytics from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.searches: - for _item in self.searches: - if _item: - _items.append(_item.to_dict()) - _dict["searches"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TopSearchesResponseWithAnalytics from a dict""" if obj is None: return None @@ -77,16 +63,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "searches": ( - [ - TopSearchWithAnalytics.from_dict(_item) - for _item in obj.get("searches") - ] - if obj.get("searches") is not None - else None - ) - } + obj["searches"] = ( + [TopSearchWithAnalytics.from_dict(_item) for _item in obj["searches"]] + if obj.get("searches") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/analytics/models/top_searches_response_with_revenue_analytics.py b/algoliasearch/analytics/models/top_searches_response_with_revenue_analytics.py index 2864ee175..30db54843 100644 --- a/algoliasearch/analytics/models/top_searches_response_with_revenue_analytics.py +++ b/algoliasearch/analytics/models/top_searches_response_with_revenue_analytics.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -28,48 +28,34 @@ class TopSearchesResponseWithRevenueAnalytics(BaseModel): TopSearchesResponseWithRevenueAnalytics """ - searches: List[TopSearchWithRevenueAnalytics] = Field( - description="Most popular searches, including their click and revenue metrics." - ) + searches: List[TopSearchWithRevenueAnalytics] = Field(alias="searches") + """ Most popular searches, including their click and revenue metrics. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TopSearchesResponseWithRevenueAnalytics from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.searches: - for _item in self.searches: - if _item: - _items.append(_item.to_dict()) - _dict["searches"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TopSearchesResponseWithRevenueAnalytics from a dict""" if obj is None: return None @@ -77,16 +63,13 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "searches": ( - [ - TopSearchWithRevenueAnalytics.from_dict(_item) - for _item in obj.get("searches") - ] - if obj.get("searches") is not None - else None - ) - } + obj["searches"] = ( + [ + TopSearchWithRevenueAnalytics.from_dict(_item) + for _item in obj["searches"] + ] + if obj.get("searches") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/client.py b/algoliasearch/ingestion/client.py index 0ffe02f61..99968abc6 100644 --- a/algoliasearch/ingestion/client.py +++ b/algoliasearch/ingestion/client.py @@ -13,11 +13,12 @@ from warnings import warn from pydantic import Field, StrictBool, StrictStr +from typing_extensions import Annotated if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.http.api_response import ApiResponse from algoliasearch.http.request_options import RequestOptions diff --git a/algoliasearch/ingestion/models/action.py b/algoliasearch/ingestion/models/action.py index 18092e4c6..dd0a0b7ba 100644 --- a/algoliasearch/ingestion/models/action.py +++ b/algoliasearch/ingestion/models/action.py @@ -25,11 +25,17 @@ class Action(str, Enum): allowed enum values """ ADDOBJECT = "addObject" + UPDATEOBJECT = "updateObject" + PARTIALUPDATEOBJECT = "partialUpdateObject" + PARTIALUPDATEOBJECTNOCREATE = "partialUpdateObjectNoCreate" + DELETEOBJECT = "deleteObject" + DELETE = "delete" + CLEAR = "clear" @classmethod diff --git a/algoliasearch/ingestion/models/action_type.py b/algoliasearch/ingestion/models/action_type.py index 6b9212cbf..33ab4f906 100644 --- a/algoliasearch/ingestion/models/action_type.py +++ b/algoliasearch/ingestion/models/action_type.py @@ -25,8 +25,11 @@ class ActionType(str, Enum): allowed enum values """ REPLACE = "replace" + SAVE = "save" + PARTIAL = "partial" + APPEND = "append" @classmethod diff --git a/algoliasearch/ingestion/models/auth_algolia.py b/algoliasearch/ingestion/models/auth_algolia.py index d698ca6b0..5c1c0d03b 100644 --- a/algoliasearch/ingestion/models/auth_algolia.py +++ b/algoliasearch/ingestion/models/auth_algolia.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,44 +23,36 @@ class AuthAlgolia(BaseModel): Credentials for authenticating with Algolia. """ - app_id: StrictStr = Field(description="Algolia application ID.", alias="appID") - api_key: StrictStr = Field( - description="Algolia API key with the ACL: `addObject`, `deleteObject`, `settings`, `editSettings`, `listIndexes`, `deleteIndex`. This field is `null` in the API response. ", - alias="apiKey", - ) + app_id: str = Field(alias="appID") + """ Algolia application ID. """ + api_key: str = Field(alias="apiKey") + """ Algolia API key with the ACL: `addObject`, `deleteObject`, `settings`, `editSettings`, `listIndexes`, `deleteIndex`. This field is `null` in the API response. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthAlgolia from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthAlgolia from a dict""" if obj is None: return None @@ -68,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"appID": obj.get("appID"), "apiKey": obj.get("apiKey")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/auth_algolia_insights.py b/algoliasearch/ingestion/models/auth_algolia_insights.py index b40458fcf..6b67ae1a9 100644 --- a/algoliasearch/ingestion/models/auth_algolia_insights.py +++ b/algoliasearch/ingestion/models/auth_algolia_insights.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,44 +23,36 @@ class AuthAlgoliaInsights(BaseModel): Credentials for authenticating with the Algolia Insights API. """ - app_id: StrictStr = Field(description="Algolia application ID.", alias="appID") - api_key: StrictStr = Field( - description="Algolia API key with the ACL: `search`. This field is `null` in the API response. ", - alias="apiKey", - ) + app_id: str = Field(alias="appID") + """ Algolia application ID. """ + api_key: str = Field(alias="apiKey") + """ Algolia API key with the ACL: `search`. This field is `null` in the API response. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthAlgoliaInsights from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthAlgoliaInsights from a dict""" if obj is None: return None @@ -68,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"appID": obj.get("appID"), "apiKey": obj.get("apiKey")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/auth_algolia_insights_partial.py b/algoliasearch/ingestion/models/auth_algolia_insights_partial.py index 146864087..3c2136969 100644 --- a/algoliasearch/ingestion/models/auth_algolia_insights_partial.py +++ b/algoliasearch/ingestion/models/auth_algolia_insights_partial.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,47 +23,36 @@ class AuthAlgoliaInsightsPartial(BaseModel): Credentials for authenticating with the Algolia Insights API. """ - app_id: Optional[StrictStr] = Field( - default=None, description="Algolia application ID.", alias="appID" - ) - api_key: Optional[StrictStr] = Field( - default=None, - description="Algolia API key with the ACL: `search`. This field is `null` in the API response. ", - alias="apiKey", - ) + app_id: Optional[str] = Field(default=None, alias="appID") + """ Algolia application ID. """ + api_key: Optional[str] = Field(default=None, alias="apiKey") + """ Algolia API key with the ACL: `search`. This field is `null` in the API response. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthAlgoliaInsightsPartial from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthAlgoliaInsightsPartial from a dict""" if obj is None: return None @@ -71,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"appID": obj.get("appID"), "apiKey": obj.get("apiKey")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/auth_algolia_partial.py b/algoliasearch/ingestion/models/auth_algolia_partial.py index 28c95778e..ed12a3e1a 100644 --- a/algoliasearch/ingestion/models/auth_algolia_partial.py +++ b/algoliasearch/ingestion/models/auth_algolia_partial.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,47 +23,36 @@ class AuthAlgoliaPartial(BaseModel): Credentials for authenticating with Algolia. """ - app_id: Optional[StrictStr] = Field( - default=None, description="Algolia application ID.", alias="appID" - ) - api_key: Optional[StrictStr] = Field( - default=None, - description="Algolia API key with the ACL: `addObject`, `deleteObject`, `settings`, `editSettings`, `listIndexes`, `deleteIndex`. This field is `null` in the API response. ", - alias="apiKey", - ) + app_id: Optional[str] = Field(default=None, alias="appID") + """ Algolia application ID. """ + api_key: Optional[str] = Field(default=None, alias="apiKey") + """ Algolia API key with the ACL: `addObject`, `deleteObject`, `settings`, `editSettings`, `listIndexes`, `deleteIndex`. This field is `null` in the API response. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthAlgoliaPartial from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthAlgoliaPartial from a dict""" if obj is None: return None @@ -71,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"appID": obj.get("appID"), "apiKey": obj.get("apiKey")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/auth_api_key.py b/algoliasearch/ingestion/models/auth_api_key.py index 99369a701..f36fa8df3 100644 --- a/algoliasearch/ingestion/models/auth_api_key.py +++ b/algoliasearch/ingestion/models/auth_api_key.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,42 +23,34 @@ class AuthAPIKey(BaseModel): Credentials for authenticating with an API key. """ - key: StrictStr = Field( - description="API key. This field is `null` in the API response." - ) + key: str = Field(alias="key") + """ API key. This field is `null` in the API response. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthAPIKey from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthAPIKey from a dict""" if obj is None: return None @@ -66,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"key": obj.get("key")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/auth_api_key_partial.py b/algoliasearch/ingestion/models/auth_api_key_partial.py index ccb80c088..e8e4177e0 100644 --- a/algoliasearch/ingestion/models/auth_api_key_partial.py +++ b/algoliasearch/ingestion/models/auth_api_key_partial.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,42 +23,34 @@ class AuthAPIKeyPartial(BaseModel): Credentials for authenticating with an API key. """ - key: Optional[StrictStr] = Field( - default=None, description="API key. This field is `null` in the API response." - ) + key: Optional[str] = Field(default=None, alias="key") + """ API key. This field is `null` in the API response. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthAPIKeyPartial from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthAPIKeyPartial from a dict""" if obj is None: return None @@ -66,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"key": obj.get("key")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/auth_basic.py b/algoliasearch/ingestion/models/auth_basic.py index c8b0809f9..efdd3cbea 100644 --- a/algoliasearch/ingestion/models/auth_basic.py +++ b/algoliasearch/ingestion/models/auth_basic.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,36 @@ class AuthBasic(BaseModel): Credentials for authenticating with user name and password. """ - username: StrictStr = Field(description="Username.") - password: StrictStr = Field( - description="Password. This field is `null` in the API response." - ) + username: str = Field(alias="username") + """ Username. """ + password: str = Field(alias="password") + """ Password. This field is `null` in the API response. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthBasic from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthBasic from a dict""" if obj is None: return None @@ -67,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"username": obj.get("username"), "password": obj.get("password")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/auth_basic_partial.py b/algoliasearch/ingestion/models/auth_basic_partial.py index 0e390fa26..850450c60 100644 --- a/algoliasearch/ingestion/models/auth_basic_partial.py +++ b/algoliasearch/ingestion/models/auth_basic_partial.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,36 @@ class AuthBasicPartial(BaseModel): Credentials for authenticating with user name and password. """ - username: Optional[StrictStr] = Field(default=None, description="Username.") - password: Optional[StrictStr] = Field( - default=None, description="Password. This field is `null` in the API response." - ) + username: Optional[str] = Field(default=None, alias="username") + """ Username. """ + password: Optional[str] = Field(default=None, alias="password") + """ Password. This field is `null` in the API response. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthBasicPartial from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthBasicPartial from a dict""" if obj is None: return None @@ -67,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"username": obj.get("username"), "password": obj.get("password")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/auth_google_service_account.py b/algoliasearch/ingestion/models/auth_google_service_account.py index 4a779ecdc..2f14251b3 100644 --- a/algoliasearch/ingestion/models/auth_google_service_account.py +++ b/algoliasearch/ingestion/models/auth_google_service_account.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,46 +23,36 @@ class AuthGoogleServiceAccount(BaseModel): Credentials for authenticating with a Google service account, such as BigQuery. """ - client_email: StrictStr = Field( - description="Email address of the Google service account.", alias="clientEmail" - ) - private_key: StrictStr = Field( - description="Private key of the Google service account. This field is `null` in the API response.", - alias="privateKey", - ) + client_email: str = Field(alias="clientEmail") + """ Email address of the Google service account. """ + private_key: str = Field(alias="privateKey") + """ Private key of the Google service account. This field is `null` in the API response. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthGoogleServiceAccount from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthGoogleServiceAccount from a dict""" if obj is None: return None @@ -70,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"clientEmail": obj.get("clientEmail"), "privateKey": obj.get("privateKey")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/auth_google_service_account_partial.py b/algoliasearch/ingestion/models/auth_google_service_account_partial.py index b29e489ea..7f75f9818 100644 --- a/algoliasearch/ingestion/models/auth_google_service_account_partial.py +++ b/algoliasearch/ingestion/models/auth_google_service_account_partial.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,49 +23,36 @@ class AuthGoogleServiceAccountPartial(BaseModel): Credentials for authenticating with a Google service account, such as BigQuery. """ - client_email: Optional[StrictStr] = Field( - default=None, - description="Email address of the Google service account.", - alias="clientEmail", - ) - private_key: Optional[StrictStr] = Field( - default=None, - description="Private key of the Google service account. This field is `null` in the API response.", - alias="privateKey", - ) + client_email: Optional[str] = Field(default=None, alias="clientEmail") + """ Email address of the Google service account. """ + private_key: Optional[str] = Field(default=None, alias="privateKey") + """ Private key of the Google service account. This field is `null` in the API response. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthGoogleServiceAccountPartial from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthGoogleServiceAccountPartial from a dict""" if obj is None: return None @@ -73,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"clientEmail": obj.get("clientEmail"), "privateKey": obj.get("privateKey")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/auth_input.py b/algoliasearch/ingestion/models/auth_input.py index 3c9e91a49..63fcdffa5 100644 --- a/algoliasearch/ingestion/models/auth_input.py +++ b/algoliasearch/ingestion/models/auth_input.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -33,12 +33,18 @@ class AuthInput(BaseModel): AuthInput """ - oneof_schema_1_validator: Optional[AuthGoogleServiceAccount] = None - oneof_schema_2_validator: Optional[AuthBasic] = None - oneof_schema_3_validator: Optional[AuthAPIKey] = None - oneof_schema_4_validator: Optional[AuthOAuth] = None - oneof_schema_5_validator: Optional[AuthAlgolia] = None - oneof_schema_6_validator: Optional[AuthAlgoliaInsights] = None + oneof_schema_1_validator: Optional[AuthGoogleServiceAccount] = Field(default=None) + + oneof_schema_2_validator: Optional[AuthBasic] = Field(default=None) + + oneof_schema_3_validator: Optional[AuthAPIKey] = Field(default=None) + + oneof_schema_4_validator: Optional[AuthOAuth] = Field(default=None) + + oneof_schema_5_validator: Optional[AuthAlgolia] = Field(default=None) + + oneof_schema_6_validator: Optional[AuthAlgoliaInsights] = Field(default=None) + actual_instance: Optional[ Union[ AuthAPIKey, @@ -49,6 +55,14 @@ class AuthInput(BaseModel): AuthOAuth, ] ] = None + one_of_schemas: Set[str] = { + "AuthAPIKey", + "AuthAlgolia", + "AuthAlgoliaInsights", + "AuthBasic", + "AuthGoogleServiceAccount", + "AuthOAuth", + } def __init__(self, *args, **kwargs) -> None: if args: @@ -83,7 +97,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of AuthInput from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -139,17 +154,33 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[ + Union[ + Dict[str, Any], + AuthAPIKey, + AuthAlgolia, + AuthAlgoliaInsights, + AuthBasic, + AuthGoogleServiceAccount, + AuthOAuth, + ] + ]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/ingestion/models/auth_input_partial.py b/algoliasearch/ingestion/models/auth_input_partial.py index 0a4f259c5..b792f1840 100644 --- a/algoliasearch/ingestion/models/auth_input_partial.py +++ b/algoliasearch/ingestion/models/auth_input_partial.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -35,12 +35,20 @@ class AuthInputPartial(BaseModel): AuthInputPartial """ - oneof_schema_1_validator: Optional[AuthGoogleServiceAccountPartial] = None - oneof_schema_2_validator: Optional[AuthBasicPartial] = None - oneof_schema_3_validator: Optional[AuthAPIKeyPartial] = None - oneof_schema_4_validator: Optional[AuthOAuthPartial] = None - oneof_schema_5_validator: Optional[AuthAlgoliaPartial] = None - oneof_schema_6_validator: Optional[AuthAlgoliaInsightsPartial] = None + oneof_schema_1_validator: Optional[AuthGoogleServiceAccountPartial] = Field( + default=None + ) + + oneof_schema_2_validator: Optional[AuthBasicPartial] = Field(default=None) + + oneof_schema_3_validator: Optional[AuthAPIKeyPartial] = Field(default=None) + + oneof_schema_4_validator: Optional[AuthOAuthPartial] = Field(default=None) + + oneof_schema_5_validator: Optional[AuthAlgoliaPartial] = Field(default=None) + + oneof_schema_6_validator: Optional[AuthAlgoliaInsightsPartial] = Field(default=None) + actual_instance: Optional[ Union[ AuthAPIKeyPartial, @@ -51,6 +59,14 @@ class AuthInputPartial(BaseModel): AuthOAuthPartial, ] ] = None + one_of_schemas: Set[str] = { + "AuthAPIKeyPartial", + "AuthAlgoliaInsightsPartial", + "AuthAlgoliaPartial", + "AuthBasicPartial", + "AuthGoogleServiceAccountPartial", + "AuthOAuthPartial", + } def __init__(self, *args, **kwargs) -> None: if args: @@ -85,7 +101,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of AuthInputPartial from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -143,17 +160,33 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[ + Union[ + Dict[str, Any], + AuthAPIKeyPartial, + AuthAlgoliaInsightsPartial, + AuthAlgoliaPartial, + AuthBasicPartial, + AuthGoogleServiceAccountPartial, + AuthOAuthPartial, + ] + ]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/ingestion/models/auth_o_auth.py b/algoliasearch/ingestion/models/auth_o_auth.py index 7d0f5b2f8..990556ded 100644 --- a/algoliasearch/ingestion/models/auth_o_auth.py +++ b/algoliasearch/ingestion/models/auth_o_auth.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,45 +23,40 @@ class AuthOAuth(BaseModel): Credentials for authenticating with OAuth 2.0. """ - url: StrictStr = Field(description="URL for the OAuth endpoint.") - client_id: StrictStr = Field(description="Client ID.") - client_secret: StrictStr = Field( - description="Client secret. This field is `null` in the API response." - ) - scope: Optional[StrictStr] = Field(default="", description="OAuth scope.") + url: str = Field(alias="url") + """ URL for the OAuth endpoint. """ + client_id: str = Field(alias="client_id") + """ Client ID. """ + client_secret: str = Field(alias="client_secret") + """ Client secret. This field is `null` in the API response. """ + scope: Optional[str] = Field(default=None, alias="scope") + """ OAuth scope. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthOAuth from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthOAuth from a dict""" if obj is None: return None @@ -69,12 +64,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "url": obj.get("url"), - "client_id": obj.get("client_id"), - "client_secret": obj.get("client_secret"), - "scope": obj.get("scope"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/auth_o_auth_partial.py b/algoliasearch/ingestion/models/auth_o_auth_partial.py index ad07fac0a..75b8ddaef 100644 --- a/algoliasearch/ingestion/models/auth_o_auth_partial.py +++ b/algoliasearch/ingestion/models/auth_o_auth_partial.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,48 +23,40 @@ class AuthOAuthPartial(BaseModel): Credentials for authenticating with OAuth 2.0. """ - url: Optional[StrictStr] = Field( - default=None, description="URL for the OAuth endpoint." - ) - client_id: Optional[StrictStr] = Field(default=None, description="Client ID.") - client_secret: Optional[StrictStr] = Field( - default=None, - description="Client secret. This field is `null` in the API response.", - ) - scope: Optional[StrictStr] = Field(default="", description="OAuth scope.") + url: Optional[str] = Field(default=None, alias="url") + """ URL for the OAuth endpoint. """ + client_id: Optional[str] = Field(default=None, alias="client_id") + """ Client ID. """ + client_secret: Optional[str] = Field(default=None, alias="client_secret") + """ Client secret. This field is `null` in the API response. """ + scope: Optional[str] = Field(default=None, alias="scope") + """ OAuth scope. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthOAuthPartial from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthOAuthPartial from a dict""" if obj is None: return None @@ -72,12 +64,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "url": obj.get("url"), - "client_id": obj.get("client_id"), - "client_secret": obj.get("client_secret"), - "scope": obj.get("scope"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/authentication.py b/algoliasearch/ingestion/models/authentication.py index 4085c1fba..377554d00 100644 --- a/algoliasearch/ingestion/models/authentication.py +++ b/algoliasearch/ingestion/models/authentication.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,57 +28,43 @@ class Authentication(BaseModel): Resource representing the information required to authenticate with a source or a destination. """ - authentication_id: StrictStr = Field( - description="Universally unique identifier (UUID) of an authentication resource.", - alias="authenticationID", - ) - type: AuthenticationType - name: StrictStr = Field(description="Descriptive name for the resource.") - platform: Optional[Platform] = None - input: AuthInputPartial - created_at: StrictStr = Field( - description="Date of creation in RFC 3339 format.", alias="createdAt" - ) - updated_at: Optional[StrictStr] = Field( - default=None, - description="Date of last update in RFC 3339 format.", - alias="updatedAt", - ) + authentication_id: str = Field(alias="authenticationID") + """ Universally unique identifier (UUID) of an authentication resource. """ + type: AuthenticationType = Field(alias="type") + name: str = Field(alias="name") + """ Descriptive name for the resource. """ + platform: Optional[Platform] = Field(default=None, alias="platform") + input: AuthInputPartial = Field(alias="input") + created_at: str = Field(alias="createdAt") + """ Date of creation in RFC 3339 format. """ + updated_at: Optional[str] = Field(default=None, alias="updatedAt") + """ Date of last update in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Authentication from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.input: - _dict["input"] = self.input.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Authentication from a dict""" if obj is None: return None @@ -86,19 +72,12 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "authenticationID": obj.get("authenticationID"), - "type": obj.get("type"), - "name": obj.get("name"), - "platform": obj.get("platform"), - "input": ( - AuthInputPartial.from_dict(obj.get("input")) - if obj.get("input") is not None - else None - ), - "createdAt": obj.get("createdAt"), - "updatedAt": obj.get("updatedAt"), - } + obj["type"] = obj.get("type") + obj["platform"] = obj.get("platform") + obj["input"] = ( + AuthInputPartial.from_dict(obj["input"]) + if obj.get("input") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/authentication_create.py b/algoliasearch/ingestion/models/authentication_create.py index 1b4c46ab2..9b71c6c31 100644 --- a/algoliasearch/ingestion/models/authentication_create.py +++ b/algoliasearch/ingestion/models/authentication_create.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,45 +28,37 @@ class AuthenticationCreate(BaseModel): Request body for creating a new authentication resource. """ - type: AuthenticationType - name: StrictStr = Field(description="Descriptive name for the resource.") - platform: Optional[Platform] = None - input: AuthInput + type: AuthenticationType = Field(alias="type") + name: str = Field(alias="name") + """ Descriptive name for the resource. """ + platform: Optional[Platform] = Field(default=None, alias="platform") + input: AuthInput = Field(alias="input") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthenticationCreate from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.input: - _dict["input"] = self.input.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthenticationCreate from a dict""" if obj is None: return None @@ -74,16 +66,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "type": obj.get("type"), - "name": obj.get("name"), - "platform": obj.get("platform"), - "input": ( - AuthInput.from_dict(obj.get("input")) - if obj.get("input") is not None - else None - ), - } + obj["type"] = obj.get("type") + obj["platform"] = obj.get("platform") + obj["input"] = ( + AuthInput.from_dict(obj["input"]) if obj.get("input") is not None else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/authentication_create_response.py b/algoliasearch/ingestion/models/authentication_create_response.py index e87fb30a5..2c46772a5 100644 --- a/algoliasearch/ingestion/models/authentication_create_response.py +++ b/algoliasearch/ingestion/models/authentication_create_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,47 +23,38 @@ class AuthenticationCreateResponse(BaseModel): API response for the successful creation of an authentication resource. """ - authentication_id: StrictStr = Field( - description="Universally unique identifier (UUID) of an authentication resource.", - alias="authenticationID", - ) - name: StrictStr = Field(description="Descriptive name for the resource.") - created_at: StrictStr = Field( - description="Date of creation in RFC 3339 format.", alias="createdAt" - ) + authentication_id: str = Field(alias="authenticationID") + """ Universally unique identifier (UUID) of an authentication resource. """ + name: str = Field(alias="name") + """ Descriptive name for the resource. """ + created_at: str = Field(alias="createdAt") + """ Date of creation in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthenticationCreateResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthenticationCreateResponse from a dict""" if obj is None: return None @@ -71,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "authenticationID": obj.get("authenticationID"), - "name": obj.get("name"), - "createdAt": obj.get("createdAt"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/authentication_search.py b/algoliasearch/ingestion/models/authentication_search.py index 27ee6259f..cd87f5c92 100644 --- a/algoliasearch/ingestion/models/authentication_search.py +++ b/algoliasearch/ingestion/models/authentication_search.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,40 +23,33 @@ class AuthenticationSearch(BaseModel): Request body for searching for authentication resources. """ - authentication_ids: List[StrictStr] = Field(alias="authenticationIDs") + authentication_ids: List[str] = Field(alias="authenticationIDs") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthenticationSearch from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthenticationSearch from a dict""" if obj is None: return None @@ -64,5 +57,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"authenticationIDs": obj.get("authenticationIDs")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/authentication_sort_keys.py b/algoliasearch/ingestion/models/authentication_sort_keys.py index 0429bd8e5..685c702e4 100644 --- a/algoliasearch/ingestion/models/authentication_sort_keys.py +++ b/algoliasearch/ingestion/models/authentication_sort_keys.py @@ -25,9 +25,13 @@ class AuthenticationSortKeys(str, Enum): allowed enum values """ NAME = "name" + AUTH_TYPE = "auth_type" + PLATFORM = "platform" + UPDATEDAT = "updatedAt" + CREATEDAT = "createdAt" @classmethod diff --git a/algoliasearch/ingestion/models/authentication_type.py b/algoliasearch/ingestion/models/authentication_type.py index cef87711f..cf9ee8374 100644 --- a/algoliasearch/ingestion/models/authentication_type.py +++ b/algoliasearch/ingestion/models/authentication_type.py @@ -25,10 +25,15 @@ class AuthenticationType(str, Enum): allowed enum values """ GOOGLESERVICEACCOUNT = "googleServiceAccount" + BASIC = "basic" + APIKEY = "apiKey" + OAUTH = "oauth" + ALGOLIA = "algolia" + ALGOLIAINSIGHTS = "algoliaInsights" @classmethod diff --git a/algoliasearch/ingestion/models/authentication_update.py b/algoliasearch/ingestion/models/authentication_update.py index 1ded7395b..c888e32c7 100644 --- a/algoliasearch/ingestion/models/authentication_update.py +++ b/algoliasearch/ingestion/models/authentication_update.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,47 +28,37 @@ class AuthenticationUpdate(BaseModel): Request body for updating an authentication resource. """ - type: Optional[AuthenticationType] = None - name: Optional[StrictStr] = Field( - default=None, description="Descriptive name for the resource." - ) - platform: Optional[Platform] = None - input: Optional[AuthInputPartial] = None + type: Optional[AuthenticationType] = Field(default=None, alias="type") + name: Optional[str] = Field(default=None, alias="name") + """ Descriptive name for the resource. """ + platform: Optional[Platform] = Field(default=None, alias="platform") + input: Optional[AuthInputPartial] = Field(default=None, alias="input") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthenticationUpdate from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.input: - _dict["input"] = self.input.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthenticationUpdate from a dict""" if obj is None: return None @@ -76,16 +66,12 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "type": obj.get("type"), - "name": obj.get("name"), - "platform": obj.get("platform"), - "input": ( - AuthInputPartial.from_dict(obj.get("input")) - if obj.get("input") is not None - else None - ), - } + obj["type"] = obj.get("type") + obj["platform"] = obj.get("platform") + obj["input"] = ( + AuthInputPartial.from_dict(obj["input"]) + if obj.get("input") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/authentication_update_response.py b/algoliasearch/ingestion/models/authentication_update_response.py index 9ac21f63e..055d1e6e2 100644 --- a/algoliasearch/ingestion/models/authentication_update_response.py +++ b/algoliasearch/ingestion/models/authentication_update_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,47 +23,38 @@ class AuthenticationUpdateResponse(BaseModel): API response for a successful update of an authentication resource. """ - authentication_id: StrictStr = Field( - description="Universally unique identifier (UUID) of an authentication resource.", - alias="authenticationID", - ) - name: StrictStr = Field(description="Descriptive name for the resource.") - updated_at: StrictStr = Field( - description="Date of last update in RFC 3339 format.", alias="updatedAt" - ) + authentication_id: str = Field(alias="authenticationID") + """ Universally unique identifier (UUID) of an authentication resource. """ + name: str = Field(alias="name") + """ Descriptive name for the resource. """ + updated_at: str = Field(alias="updatedAt") + """ Date of last update in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AuthenticationUpdateResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AuthenticationUpdateResponse from a dict""" if obj is None: return None @@ -71,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "authenticationID": obj.get("authenticationID"), - "name": obj.get("name"), - "updatedAt": obj.get("updatedAt"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/big_commerce_channel.py b/algoliasearch/ingestion/models/big_commerce_channel.py index 64854e201..788306b4d 100644 --- a/algoliasearch/ingestion/models/big_commerce_channel.py +++ b/algoliasearch/ingestion/models/big_commerce_channel.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,36 @@ class BigCommerceChannel(BaseModel): BigCommerceChannel """ - id: StrictInt = Field(description="ID of the BigCommerce channel.") - currencies: Optional[List[StrictStr]] = Field( - default=None, description="Currencies for the given channel." - ) + id: int = Field(alias="id") + """ ID of the BigCommerce channel. """ + currencies: Optional[List[str]] = Field(default=None, alias="currencies") + """ Currencies for the given channel. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of BigCommerceChannel from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of BigCommerceChannel from a dict""" if obj is None: return None @@ -67,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"id": obj.get("id"), "currencies": obj.get("currencies")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/big_commerce_metafield.py b/algoliasearch/ingestion/models/big_commerce_metafield.py index 014fb9895..7adb8f177 100644 --- a/algoliasearch/ingestion/models/big_commerce_metafield.py +++ b/algoliasearch/ingestion/models/big_commerce_metafield.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,41 +23,36 @@ class BigCommerceMetafield(BaseModel): BigCommerceMetafield """ - namespace: StrictStr = Field(description="Namespace of the metafield.") - key: StrictStr = Field(description="Key identifier of the metafield.") + namespace: str = Field(alias="namespace") + """ Namespace of the metafield. """ + key: str = Field(alias="key") + """ Key identifier of the metafield. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of BigCommerceMetafield from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of BigCommerceMetafield from a dict""" if obj is None: return None @@ -65,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"namespace": obj.get("namespace"), "key": obj.get("key")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/big_query_data_type.py b/algoliasearch/ingestion/models/big_query_data_type.py index 20dfffe1f..d13143960 100644 --- a/algoliasearch/ingestion/models/big_query_data_type.py +++ b/algoliasearch/ingestion/models/big_query_data_type.py @@ -25,6 +25,7 @@ class BigQueryDataType(str, Enum): allowed enum values """ GA4 = "ga4" + GA360 = "ga360" @classmethod diff --git a/algoliasearch/ingestion/models/commercetools_custom_fields.py b/algoliasearch/ingestion/models/commercetools_custom_fields.py index f875a8682..5d5c1e4f1 100644 --- a/algoliasearch/ingestion/models/commercetools_custom_fields.py +++ b/algoliasearch/ingestion/models/commercetools_custom_fields.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,48 +23,38 @@ class CommercetoolsCustomFields(BaseModel): Custom fields from commercetools to add to the records. For more information, see [Using Custom Types and Custom Fields](https://docs.commercetools.com/tutorials/custom-types). """ - inventory: Optional[List[StrictStr]] = Field( - default=None, description="Inventory custom fields." - ) - price: Optional[List[StrictStr]] = Field( - default=None, description="Price custom fields." - ) - category: Optional[List[StrictStr]] = Field( - default=None, description="Category custom fields." - ) + inventory: Optional[List[str]] = Field(default=None, alias="inventory") + """ Inventory custom fields. """ + price: Optional[List[str]] = Field(default=None, alias="price") + """ Price custom fields. """ + category: Optional[List[str]] = Field(default=None, alias="category") + """ Category custom fields. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of CommercetoolsCustomFields from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of CommercetoolsCustomFields from a dict""" if obj is None: return None @@ -72,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "inventory": obj.get("inventory"), - "price": obj.get("price"), - "category": obj.get("category"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/delete_response.py b/algoliasearch/ingestion/models/delete_response.py index ff9fb366a..006891723 100644 --- a/algoliasearch/ingestion/models/delete_response.py +++ b/algoliasearch/ingestion/models/delete_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,42 +23,34 @@ class DeleteResponse(BaseModel): DeleteResponse """ - deleted_at: StrictStr = Field( - description="Date of deletion in RFC 3339 format.", alias="deletedAt" - ) + deleted_at: str = Field(alias="deletedAt") + """ Date of deletion in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DeleteResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DeleteResponse from a dict""" if obj is None: return None @@ -66,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"deletedAt": obj.get("deletedAt")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/destination.py b/algoliasearch/ingestion/models/destination.py index 7ffaf0c1e..f67a75491 100644 --- a/algoliasearch/ingestion/models/destination.py +++ b/algoliasearch/ingestion/models/destination.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,64 +27,47 @@ class Destination(BaseModel): Destinations are Algolia resources like indices or event streams. """ - destination_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a destination resource.", - alias="destinationID", - ) - type: DestinationType - name: StrictStr = Field(description="Descriptive name for the resource.") - input: DestinationInput - created_at: StrictStr = Field( - description="Date of creation in RFC 3339 format.", alias="createdAt" - ) - updated_at: Optional[StrictStr] = Field( - default=None, - description="Date of last update in RFC 3339 format.", - alias="updatedAt", - ) - authentication_id: Optional[StrictStr] = Field( - default=None, - description="Universally unique identifier (UUID) of an authentication resource.", - alias="authenticationID", - ) - transformation_ids: Optional[List[StrictStr]] = Field( + destination_id: str = Field(alias="destinationID") + """ Universally unique identifier (UUID) of a destination resource. """ + type: DestinationType = Field(alias="type") + name: str = Field(alias="name") + """ Descriptive name for the resource. """ + input: DestinationInput = Field(alias="input") + created_at: str = Field(alias="createdAt") + """ Date of creation in RFC 3339 format. """ + updated_at: Optional[str] = Field(default=None, alias="updatedAt") + """ Date of last update in RFC 3339 format. """ + authentication_id: Optional[str] = Field(default=None, alias="authenticationID") + """ Universally unique identifier (UUID) of an authentication resource. """ + transformation_ids: Optional[List[str]] = Field( default=None, alias="transformationIDs" ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Destination from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.input: - _dict["input"] = self.input.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Destination from a dict""" if obj is None: return None @@ -92,20 +75,11 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "destinationID": obj.get("destinationID"), - "type": obj.get("type"), - "name": obj.get("name"), - "input": ( - DestinationInput.from_dict(obj.get("input")) - if obj.get("input") is not None - else None - ), - "createdAt": obj.get("createdAt"), - "updatedAt": obj.get("updatedAt"), - "authenticationID": obj.get("authenticationID"), - "transformationIDs": obj.get("transformationIDs"), - } + obj["type"] = obj.get("type") + obj["input"] = ( + DestinationInput.from_dict(obj["input"]) + if obj.get("input") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/destination_create.py b/algoliasearch/ingestion/models/destination_create.py index b8516743f..a8ebc29f2 100644 --- a/algoliasearch/ingestion/models/destination_create.py +++ b/algoliasearch/ingestion/models/destination_create.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,52 +27,41 @@ class DestinationCreate(BaseModel): API request body for creating a new destination. """ - type: DestinationType - name: StrictStr = Field(description="Descriptive name for the resource.") - input: DestinationInput - authentication_id: Optional[StrictStr] = Field( - default=None, - description="Universally unique identifier (UUID) of an authentication resource.", - alias="authenticationID", - ) - transformation_ids: Optional[List[StrictStr]] = Field( + type: DestinationType = Field(alias="type") + name: str = Field(alias="name") + """ Descriptive name for the resource. """ + input: DestinationInput = Field(alias="input") + authentication_id: Optional[str] = Field(default=None, alias="authenticationID") + """ Universally unique identifier (UUID) of an authentication resource. """ + transformation_ids: Optional[List[str]] = Field( default=None, alias="transformationIDs" ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DestinationCreate from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.input: - _dict["input"] = self.input.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DestinationCreate from a dict""" if obj is None: return None @@ -80,17 +69,11 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "type": obj.get("type"), - "name": obj.get("name"), - "input": ( - DestinationInput.from_dict(obj.get("input")) - if obj.get("input") is not None - else None - ), - "authenticationID": obj.get("authenticationID"), - "transformationIDs": obj.get("transformationIDs"), - } + obj["type"] = obj.get("type") + obj["input"] = ( + DestinationInput.from_dict(obj["input"]) + if obj.get("input") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/destination_create_response.py b/algoliasearch/ingestion/models/destination_create_response.py index fe4fb8cb6..3672a4a99 100644 --- a/algoliasearch/ingestion/models/destination_create_response.py +++ b/algoliasearch/ingestion/models/destination_create_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,47 +23,38 @@ class DestinationCreateResponse(BaseModel): API response for creating a new destination. """ - destination_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a destination resource.", - alias="destinationID", - ) - name: StrictStr = Field(description="Descriptive name for the resource.") - created_at: StrictStr = Field( - description="Date of creation in RFC 3339 format.", alias="createdAt" - ) + destination_id: str = Field(alias="destinationID") + """ Universally unique identifier (UUID) of a destination resource. """ + name: str = Field(alias="name") + """ Descriptive name for the resource. """ + created_at: str = Field(alias="createdAt") + """ Date of creation in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DestinationCreateResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DestinationCreateResponse from a dict""" if obj is None: return None @@ -71,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "destinationID": obj.get("destinationID"), - "name": obj.get("name"), - "createdAt": obj.get("createdAt"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/destination_index_name.py b/algoliasearch/ingestion/models/destination_index_name.py index 333d611bd..b4cdd6bb8 100644 --- a/algoliasearch/ingestion/models/destination_index_name.py +++ b/algoliasearch/ingestion/models/destination_index_name.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,48 +26,39 @@ class DestinationIndexName(BaseModel): DestinationIndexName """ - index_name: StrictStr = Field( - description="Algolia index name (case-sensitive).", alias="indexName" - ) + index_name: str = Field(alias="indexName") + """ Algolia index name (case-sensitive). """ record_type: Optional[RecordType] = Field(default=None, alias="recordType") - attributes_to_exclude: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes from your source to exclude from Algolia records. Not all your data attributes will be useful for searching. Keeping your Algolia records small increases indexing and search performance. - Exclude nested attributes with `.` notation. For example, `foo.bar` indexes the `foo` attribute and all its children **except** the `bar` attribute. - Exclude attributes from arrays with `[i]`, where `i` is the index of the array element. For example, `foo.[0].bar` only excludes the `bar` attribute from the first element of the `foo` array, but indexes the complete `foo` attribute for all other elements. Use `*` as wildcard: `foo.[*].bar` excludes `bar` from all elements of the `foo` array. ", - alias="attributesToExclude", + attributes_to_exclude: Optional[List[str]] = Field( + default=None, alias="attributesToExclude" ) + """ Attributes from your source to exclude from Algolia records. Not all your data attributes will be useful for searching. Keeping your Algolia records small increases indexing and search performance. - Exclude nested attributes with `.` notation. For example, `foo.bar` indexes the `foo` attribute and all its children **except** the `bar` attribute. - Exclude attributes from arrays with `[i]`, where `i` is the index of the array element. For example, `foo.[0].bar` only excludes the `bar` attribute from the first element of the `foo` array, but indexes the complete `foo` attribute for all other elements. Use `*` as wildcard: `foo.[*].bar` excludes `bar` from all elements of the `foo` array. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DestinationIndexName from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DestinationIndexName from a dict""" if obj is None: return None @@ -75,11 +66,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "indexName": obj.get("indexName"), - "recordType": obj.get("recordType"), - "attributesToExclude": obj.get("attributesToExclude"), - } - ) - return _obj + obj["recordType"] = obj.get("recordType") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/destination_input.py b/algoliasearch/ingestion/models/destination_input.py index 831c80abc..8bed22f89 100644 --- a/algoliasearch/ingestion/models/destination_input.py +++ b/algoliasearch/ingestion/models/destination_input.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -26,8 +26,10 @@ class DestinationInput(BaseModel): DestinationInput """ - oneof_schema_1_validator: Optional[DestinationIndexName] = None + oneof_schema_1_validator: Optional[DestinationIndexName] = Field(default=None) + actual_instance: Optional[Union[DestinationIndexName]] = None + one_of_schemas: Set[str] = {"DestinationIndexName"} def __init__(self, *args, **kwargs) -> None: if args: @@ -51,7 +53,8 @@ def unwrap_actual_instance(self) -> Optional[Union[DestinationIndexName]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of DestinationInput from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -77,17 +80,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], DestinationIndexName]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/ingestion/models/destination_search.py b/algoliasearch/ingestion/models/destination_search.py index ae4cf425b..de77cbdce 100644 --- a/algoliasearch/ingestion/models/destination_search.py +++ b/algoliasearch/ingestion/models/destination_search.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,40 +23,33 @@ class DestinationSearch(BaseModel): API request body for searching destinations. """ - destination_ids: List[StrictStr] = Field(alias="destinationIDs") + destination_ids: List[str] = Field(alias="destinationIDs") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DestinationSearch from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DestinationSearch from a dict""" if obj is None: return None @@ -64,5 +57,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"destinationIDs": obj.get("destinationIDs")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/destination_sort_keys.py b/algoliasearch/ingestion/models/destination_sort_keys.py index 9a8c64c74..cba5b373d 100644 --- a/algoliasearch/ingestion/models/destination_sort_keys.py +++ b/algoliasearch/ingestion/models/destination_sort_keys.py @@ -25,8 +25,11 @@ class DestinationSortKeys(str, Enum): allowed enum values """ NAME = "name" + TYPE = "type" + UPDATEDAT = "updatedAt" + CREATEDAT = "createdAt" @classmethod diff --git a/algoliasearch/ingestion/models/destination_type.py b/algoliasearch/ingestion/models/destination_type.py index ce0eb4088..58195bd4d 100644 --- a/algoliasearch/ingestion/models/destination_type.py +++ b/algoliasearch/ingestion/models/destination_type.py @@ -25,6 +25,7 @@ class DestinationType(str, Enum): allowed enum values """ SEARCH = "search" + INSIGHTS = "insights" @classmethod diff --git a/algoliasearch/ingestion/models/destination_update.py b/algoliasearch/ingestion/models/destination_update.py index 32366569d..bfdb77327 100644 --- a/algoliasearch/ingestion/models/destination_update.py +++ b/algoliasearch/ingestion/models/destination_update.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,54 +27,41 @@ class DestinationUpdate(BaseModel): API request body for updating a destination. """ - type: Optional[DestinationType] = None - name: Optional[StrictStr] = Field( - default=None, description="Descriptive name for the resource." - ) - input: Optional[DestinationInput] = None - authentication_id: Optional[StrictStr] = Field( - default=None, - description="Universally unique identifier (UUID) of an authentication resource.", - alias="authenticationID", - ) - transformation_ids: Optional[List[StrictStr]] = Field( + type: Optional[DestinationType] = Field(default=None, alias="type") + name: Optional[str] = Field(default=None, alias="name") + """ Descriptive name for the resource. """ + input: Optional[DestinationInput] = Field(default=None, alias="input") + authentication_id: Optional[str] = Field(default=None, alias="authenticationID") + """ Universally unique identifier (UUID) of an authentication resource. """ + transformation_ids: Optional[List[str]] = Field( default=None, alias="transformationIDs" ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DestinationUpdate from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.input: - _dict["input"] = self.input.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DestinationUpdate from a dict""" if obj is None: return None @@ -82,17 +69,11 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "type": obj.get("type"), - "name": obj.get("name"), - "input": ( - DestinationInput.from_dict(obj.get("input")) - if obj.get("input") is not None - else None - ), - "authenticationID": obj.get("authenticationID"), - "transformationIDs": obj.get("transformationIDs"), - } + obj["type"] = obj.get("type") + obj["input"] = ( + DestinationInput.from_dict(obj["input"]) + if obj.get("input") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/destination_update_response.py b/algoliasearch/ingestion/models/destination_update_response.py index aa0d77f5a..4f9ad8fd5 100644 --- a/algoliasearch/ingestion/models/destination_update_response.py +++ b/algoliasearch/ingestion/models/destination_update_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,47 +23,38 @@ class DestinationUpdateResponse(BaseModel): API response for updating a destination. """ - destination_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a destination resource.", - alias="destinationID", - ) - name: StrictStr = Field(description="Descriptive name for the resource.") - updated_at: StrictStr = Field( - description="Date of last update in RFC 3339 format.", alias="updatedAt" - ) + destination_id: str = Field(alias="destinationID") + """ Universally unique identifier (UUID) of a destination resource. """ + name: str = Field(alias="name") + """ Descriptive name for the resource. """ + updated_at: str = Field(alias="updatedAt") + """ Date of last update in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DestinationUpdateResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DestinationUpdateResponse from a dict""" if obj is None: return None @@ -71,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "destinationID": obj.get("destinationID"), - "name": obj.get("name"), - "updatedAt": obj.get("updatedAt"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/docker_image_type.py b/algoliasearch/ingestion/models/docker_image_type.py index 56be6ff0c..100d6a4e4 100644 --- a/algoliasearch/ingestion/models/docker_image_type.py +++ b/algoliasearch/ingestion/models/docker_image_type.py @@ -25,7 +25,9 @@ class DockerImageType(str, Enum): allowed enum values """ SINGER = "singer" + CUSTOM = "custom" + AIRBYTE = "airbyte" @classmethod diff --git a/algoliasearch/ingestion/models/docker_registry.py b/algoliasearch/ingestion/models/docker_registry.py index 54176ddce..591fadff5 100644 --- a/algoliasearch/ingestion/models/docker_registry.py +++ b/algoliasearch/ingestion/models/docker_registry.py @@ -25,6 +25,7 @@ class DockerRegistry(str, Enum): allowed enum values """ DOCKERHUB = "dockerhub" + GHCR = "ghcr" @classmethod diff --git a/algoliasearch/ingestion/models/docker_streams.py b/algoliasearch/ingestion/models/docker_streams.py index e9794e6bd..7bf6aecd9 100644 --- a/algoliasearch/ingestion/models/docker_streams.py +++ b/algoliasearch/ingestion/models/docker_streams.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,47 +28,37 @@ class DockerStreams(BaseModel): DockerStreams """ - name: StrictStr = Field( - description="The name of the stream to fetch the data from (e.g. table name)." - ) - properties: Optional[List[StrictStr]] = Field( - default=None, - description="The properties of the stream to select (e.g. column).", - ) + name: str = Field(alias="name") + """ The name of the stream to fetch the data from (e.g. table name). """ + properties: Optional[List[str]] = Field(default=None, alias="properties") + """ The properties of the stream to select (e.g. column). """ sync_mode: DockerStreamsSyncMode = Field(alias="syncMode") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DockerStreams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DockerStreams from a dict""" if obj is None: return None @@ -76,11 +66,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "name": obj.get("name"), - "properties": obj.get("properties"), - "syncMode": obj.get("syncMode"), - } - ) - return _obj + obj["syncMode"] = obj.get("syncMode") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/docker_streams_input.py b/algoliasearch/ingestion/models/docker_streams_input.py index 02903d875..5e2feb5c4 100644 --- a/algoliasearch/ingestion/models/docker_streams_input.py +++ b/algoliasearch/ingestion/models/docker_streams_input.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,46 +26,33 @@ class DockerStreamsInput(BaseModel): The selected streams of a singer or airbyte connector. """ - streams: List[DockerStreams] + streams: List[DockerStreams] = Field(alias="streams") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DockerStreamsInput from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.streams: - for _item in self.streams: - if _item: - _items.append(_item.to_dict()) - _dict["streams"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DockerStreamsInput from a dict""" if obj is None: return None @@ -73,13 +60,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "streams": ( - [DockerStreams.from_dict(_item) for _item in obj.get("streams")] - if obj.get("streams") is not None - else None - ) - } + obj["streams"] = ( + [DockerStreams.from_dict(_item) for _item in obj["streams"]] + if obj.get("streams") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/docker_streams_sync_mode.py b/algoliasearch/ingestion/models/docker_streams_sync_mode.py index 9763d0a34..9999d2126 100644 --- a/algoliasearch/ingestion/models/docker_streams_sync_mode.py +++ b/algoliasearch/ingestion/models/docker_streams_sync_mode.py @@ -25,6 +25,7 @@ class DockerStreamsSyncMode(str, Enum): allowed enum values """ INCREMENTAL = "incremental" + FULLTABLE = "fullTable" @classmethod diff --git a/algoliasearch/ingestion/models/entity_type.py b/algoliasearch/ingestion/models/entity_type.py index a303414d9..71bedf09c 100644 --- a/algoliasearch/ingestion/models/entity_type.py +++ b/algoliasearch/ingestion/models/entity_type.py @@ -25,6 +25,7 @@ class EntityType(str, Enum): allowed enum values """ PRODUCT = "product" + COLLECTION = "collection" @classmethod diff --git a/algoliasearch/ingestion/models/error_base.py b/algoliasearch/ingestion/models/error_base.py index 4317b330d..075d8a3ac 100644 --- a/algoliasearch/ingestion/models/error_base.py +++ b/algoliasearch/ingestion/models/error_base.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, ClassVar, Dict, List, Optional +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,50 +23,34 @@ class ErrorBase(BaseModel): Error. """ - message: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["message"] + message: Optional[str] = Field(default=None, alias="message") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + extra="allow", ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ErrorBase from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={ - "additional_properties", - }, exclude_none=True, exclude_unset=True, ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ErrorBase from a dict""" if obj is None: return None @@ -74,10 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"message": obj.get("message")}) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/event.py b/algoliasearch/ingestion/models/event.py index 3268e5ca4..278dfa3bd 100644 --- a/algoliasearch/ingestion/models/event.py +++ b/algoliasearch/ingestion/models/event.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.ingestion.models.event_status import EventStatus @@ -27,59 +27,45 @@ class Event(BaseModel): An event describe a step of the task execution flow.. """ - event_id: StrictStr = Field( - description="Universally unique identifier (UUID) of an event.", alias="eventID" - ) - run_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a task run.", alias="runID" - ) - parent_id: Optional[StrictStr] = Field( - default=None, - description="The parent event, the cause of this event.", - alias="parentID", - ) - status: EventStatus - type: EventType - batch_size: Annotated[int, Field(multiple_of=1, strict=True, ge=0)] = Field( - description="The extracted record batch size.", alias="batchSize" - ) - data: Optional[Dict[str, Any]] = None - published_at: StrictStr = Field( - description="Date of publish RFC 3339 format.", alias="publishedAt" - ) + event_id: str = Field(alias="eventID") + """ Universally unique identifier (UUID) of an event. """ + run_id: str = Field(alias="runID") + """ Universally unique identifier (UUID) of a task run. """ + parent_id: Optional[str] = Field(default=None, alias="parentID") + """ The parent event, the cause of this event. """ + status: EventStatus = Field(alias="status") + type: EventType = Field(alias="type") + batch_size: int = Field(alias="batchSize") + """ The extracted record batch size. """ + data: Optional[Dict[str, object]] = Field(default=None, alias="data") + published_at: str = Field(alias="publishedAt") + """ Date of publish RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Event from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Event from a dict""" if obj is None: return None @@ -87,16 +73,7 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "eventID": obj.get("eventID"), - "runID": obj.get("runID"), - "parentID": obj.get("parentID"), - "status": obj.get("status"), - "type": obj.get("type"), - "batchSize": obj.get("batchSize"), - "data": obj.get("data"), - "publishedAt": obj.get("publishedAt"), - } - ) - return _obj + obj["status"] = obj.get("status") + obj["type"] = obj.get("type") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/event_sort_keys.py b/algoliasearch/ingestion/models/event_sort_keys.py index 4c89569fb..d273116da 100644 --- a/algoliasearch/ingestion/models/event_sort_keys.py +++ b/algoliasearch/ingestion/models/event_sort_keys.py @@ -25,7 +25,9 @@ class EventSortKeys(str, Enum): allowed enum values """ STATUS = "status" + TYPE = "type" + PUBLISHEDAT = "publishedAt" @classmethod diff --git a/algoliasearch/ingestion/models/event_status.py b/algoliasearch/ingestion/models/event_status.py index fd1df1ae9..a225d50b1 100644 --- a/algoliasearch/ingestion/models/event_status.py +++ b/algoliasearch/ingestion/models/event_status.py @@ -25,10 +25,15 @@ class EventStatus(str, Enum): allowed enum values """ CREATED = "created" + STARTED = "started" + RETRIED = "retried" + FAILED = "failed" + SUCCEEDED = "succeeded" + CRITICAL = "critical" @classmethod diff --git a/algoliasearch/ingestion/models/event_type.py b/algoliasearch/ingestion/models/event_type.py index 63962de8d..a8e022bb1 100644 --- a/algoliasearch/ingestion/models/event_type.py +++ b/algoliasearch/ingestion/models/event_type.py @@ -25,8 +25,11 @@ class EventType(str, Enum): allowed enum values """ FETCH = "fetch" + RECORD = "record" + LOG = "log" + TRANSFORM = "transform" @classmethod diff --git a/algoliasearch/ingestion/models/list_authentications_response.py b/algoliasearch/ingestion/models/list_authentications_response.py index b726e1527..2f121b094 100644 --- a/algoliasearch/ingestion/models/list_authentications_response.py +++ b/algoliasearch/ingestion/models/list_authentications_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,49 +27,34 @@ class ListAuthenticationsResponse(BaseModel): ListAuthenticationsResponse """ - authentications: List[Authentication] - pagination: Pagination + authentications: List[Authentication] = Field(alias="authentications") + pagination: Pagination = Field(alias="pagination") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ListAuthenticationsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.authentications: - for _item in self.authentications: - if _item: - _items.append(_item.to_dict()) - _dict["authentications"] = _items - if self.pagination: - _dict["pagination"] = self.pagination.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ListAuthenticationsResponse from a dict""" if obj is None: return None @@ -77,21 +62,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "authentications": ( - [ - Authentication.from_dict(_item) - for _item in obj.get("authentications") - ] - if obj.get("authentications") is not None - else None - ), - "pagination": ( - Pagination.from_dict(obj.get("pagination")) - if obj.get("pagination") is not None - else None - ), - } + obj["authentications"] = ( + [Authentication.from_dict(_item) for _item in obj["authentications"]] + if obj.get("authentications") is not None + else None ) - return _obj + obj["pagination"] = ( + Pagination.from_dict(obj["pagination"]) + if obj.get("pagination") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/list_destinations_response.py b/algoliasearch/ingestion/models/list_destinations_response.py index 81c011660..28b9ced85 100644 --- a/algoliasearch/ingestion/models/list_destinations_response.py +++ b/algoliasearch/ingestion/models/list_destinations_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,49 +27,34 @@ class ListDestinationsResponse(BaseModel): ListDestinationsResponse """ - destinations: List[Destination] - pagination: Pagination + destinations: List[Destination] = Field(alias="destinations") + pagination: Pagination = Field(alias="pagination") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ListDestinationsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.destinations: - for _item in self.destinations: - if _item: - _items.append(_item.to_dict()) - _dict["destinations"] = _items - if self.pagination: - _dict["pagination"] = self.pagination.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ListDestinationsResponse from a dict""" if obj is None: return None @@ -77,18 +62,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "destinations": ( - [Destination.from_dict(_item) for _item in obj.get("destinations")] - if obj.get("destinations") is not None - else None - ), - "pagination": ( - Pagination.from_dict(obj.get("pagination")) - if obj.get("pagination") is not None - else None - ), - } + obj["destinations"] = ( + [Destination.from_dict(_item) for _item in obj["destinations"]] + if obj.get("destinations") is not None + else None ) - return _obj + obj["pagination"] = ( + Pagination.from_dict(obj["pagination"]) + if obj.get("pagination") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/list_events_response.py b/algoliasearch/ingestion/models/list_events_response.py index 3cddb8c4b..40866f464 100644 --- a/algoliasearch/ingestion/models/list_events_response.py +++ b/algoliasearch/ingestion/models/list_events_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,52 +28,35 @@ class ListEventsResponse(BaseModel): ListEventsResponse """ - events: List[Event] - pagination: Pagination - window: Window + events: List[Event] = Field(alias="events") + pagination: Pagination = Field(alias="pagination") + window: Window = Field(alias="window") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ListEventsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.events: - for _item in self.events: - if _item: - _items.append(_item.to_dict()) - _dict["events"] = _items - if self.pagination: - _dict["pagination"] = self.pagination.to_dict() - if self.window: - _dict["window"] = self.window.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ListEventsResponse from a dict""" if obj is None: return None @@ -81,23 +64,18 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "events": ( - [Event.from_dict(_item) for _item in obj.get("events")] - if obj.get("events") is not None - else None - ), - "pagination": ( - Pagination.from_dict(obj.get("pagination")) - if obj.get("pagination") is not None - else None - ), - "window": ( - Window.from_dict(obj.get("window")) - if obj.get("window") is not None - else None - ), - } + obj["events"] = ( + [Event.from_dict(_item) for _item in obj["events"]] + if obj.get("events") is not None + else None + ) + obj["pagination"] = ( + Pagination.from_dict(obj["pagination"]) + if obj.get("pagination") is not None + else None ) - return _obj + obj["window"] = ( + Window.from_dict(obj["window"]) if obj.get("window") is not None else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/list_sources_response.py b/algoliasearch/ingestion/models/list_sources_response.py index 9b6edaf3b..683c9aed0 100644 --- a/algoliasearch/ingestion/models/list_sources_response.py +++ b/algoliasearch/ingestion/models/list_sources_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,49 +27,34 @@ class ListSourcesResponse(BaseModel): ListSourcesResponse """ - sources: List[Source] - pagination: Pagination + sources: List[Source] = Field(alias="sources") + pagination: Pagination = Field(alias="pagination") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ListSourcesResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.sources: - for _item in self.sources: - if _item: - _items.append(_item.to_dict()) - _dict["sources"] = _items - if self.pagination: - _dict["pagination"] = self.pagination.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ListSourcesResponse from a dict""" if obj is None: return None @@ -77,18 +62,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "sources": ( - [Source.from_dict(_item) for _item in obj.get("sources")] - if obj.get("sources") is not None - else None - ), - "pagination": ( - Pagination.from_dict(obj.get("pagination")) - if obj.get("pagination") is not None - else None - ), - } + obj["sources"] = ( + [Source.from_dict(_item) for _item in obj["sources"]] + if obj.get("sources") is not None + else None ) - return _obj + obj["pagination"] = ( + Pagination.from_dict(obj["pagination"]) + if obj.get("pagination") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/list_tasks_response.py b/algoliasearch/ingestion/models/list_tasks_response.py index 922461a25..775fb351d 100644 --- a/algoliasearch/ingestion/models/list_tasks_response.py +++ b/algoliasearch/ingestion/models/list_tasks_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,49 +27,34 @@ class ListTasksResponse(BaseModel): Configured tasks and pagination information. """ - tasks: List[Task] - pagination: Pagination + tasks: List[Task] = Field(alias="tasks") + pagination: Pagination = Field(alias="pagination") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ListTasksResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.tasks: - for _item in self.tasks: - if _item: - _items.append(_item.to_dict()) - _dict["tasks"] = _items - if self.pagination: - _dict["pagination"] = self.pagination.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ListTasksResponse from a dict""" if obj is None: return None @@ -77,18 +62,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "tasks": ( - [Task.from_dict(_item) for _item in obj.get("tasks")] - if obj.get("tasks") is not None - else None - ), - "pagination": ( - Pagination.from_dict(obj.get("pagination")) - if obj.get("pagination") is not None - else None - ), - } + obj["tasks"] = ( + [Task.from_dict(_item) for _item in obj["tasks"]] + if obj.get("tasks") is not None + else None ) - return _obj + obj["pagination"] = ( + Pagination.from_dict(obj["pagination"]) + if obj.get("pagination") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/list_tasks_response_v1.py b/algoliasearch/ingestion/models/list_tasks_response_v1.py index 995780241..02f66ee59 100644 --- a/algoliasearch/ingestion/models/list_tasks_response_v1.py +++ b/algoliasearch/ingestion/models/list_tasks_response_v1.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,49 +27,34 @@ class ListTasksResponseV1(BaseModel): Configured tasks and pagination information. """ - tasks: List[TaskV1] - pagination: Pagination + tasks: List[TaskV1] = Field(alias="tasks") + pagination: Pagination = Field(alias="pagination") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ListTasksResponseV1 from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.tasks: - for _item in self.tasks: - if _item: - _items.append(_item.to_dict()) - _dict["tasks"] = _items - if self.pagination: - _dict["pagination"] = self.pagination.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ListTasksResponseV1 from a dict""" if obj is None: return None @@ -77,18 +62,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "tasks": ( - [TaskV1.from_dict(_item) for _item in obj.get("tasks")] - if obj.get("tasks") is not None - else None - ), - "pagination": ( - Pagination.from_dict(obj.get("pagination")) - if obj.get("pagination") is not None - else None - ), - } + obj["tasks"] = ( + [TaskV1.from_dict(_item) for _item in obj["tasks"]] + if obj.get("tasks") is not None + else None ) - return _obj + obj["pagination"] = ( + Pagination.from_dict(obj["pagination"]) + if obj.get("pagination") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/list_transformations_response.py b/algoliasearch/ingestion/models/list_transformations_response.py index 28fb12713..2262b6b03 100644 --- a/algoliasearch/ingestion/models/list_transformations_response.py +++ b/algoliasearch/ingestion/models/list_transformations_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,49 +27,34 @@ class ListTransformationsResponse(BaseModel): Configured transformations and pagination information. """ - transformations: List[Transformation] - pagination: Pagination + transformations: List[Transformation] = Field(alias="transformations") + pagination: Pagination = Field(alias="pagination") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ListTransformationsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.transformations: - for _item in self.transformations: - if _item: - _items.append(_item.to_dict()) - _dict["transformations"] = _items - if self.pagination: - _dict["pagination"] = self.pagination.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ListTransformationsResponse from a dict""" if obj is None: return None @@ -77,21 +62,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "transformations": ( - [ - Transformation.from_dict(_item) - for _item in obj.get("transformations") - ] - if obj.get("transformations") is not None - else None - ), - "pagination": ( - Pagination.from_dict(obj.get("pagination")) - if obj.get("pagination") is not None - else None - ), - } + obj["transformations"] = ( + [Transformation.from_dict(_item) for _item in obj["transformations"]] + if obj.get("transformations") is not None + else None ) - return _obj + obj["pagination"] = ( + Pagination.from_dict(obj["pagination"]) + if obj.get("pagination") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/mapping_field_directive.py b/algoliasearch/ingestion/models/mapping_field_directive.py index f8f7ee87e..ee75acbce 100644 --- a/algoliasearch/ingestion/models/mapping_field_directive.py +++ b/algoliasearch/ingestion/models/mapping_field_directive.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,36 @@ class MappingFieldDirective(BaseModel): Describes how a field should be resolved by applying a set of directives. """ - field_key: StrictStr = Field(description="Destination field key.", alias="fieldKey") - value: Dict[str, Any] = Field( - description="How the destination field should be resolved from the source." - ) + field_key: str = Field(alias="fieldKey") + """ Destination field key. """ + value: Dict[str, object] = Field(alias="value") + """ How the destination field should be resolved from the source. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of MappingFieldDirective from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of MappingFieldDirective from a dict""" if obj is None: return None @@ -67,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"fieldKey": obj.get("fieldKey"), "value": obj.get("value")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/mapping_input.py b/algoliasearch/ingestion/models/mapping_input.py index 8648453d8..fe8159c2a 100644 --- a/algoliasearch/ingestion/models/mapping_input.py +++ b/algoliasearch/ingestion/models/mapping_input.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,47 +27,34 @@ class MappingInput(BaseModel): Transformations to apply to the source, serialized as a JSON string. """ - format: MappingFormatSchema - actions: List[MappingKitAction] + format: MappingFormatSchema = Field(alias="format") + actions: List[MappingKitAction] = Field(alias="actions") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of MappingInput from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.actions: - for _item in self.actions: - if _item: - _items.append(_item.to_dict()) - _dict["actions"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of MappingInput from a dict""" if obj is None: return None @@ -75,14 +62,11 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "format": obj.get("format"), - "actions": ( - [MappingKitAction.from_dict(_item) for _item in obj.get("actions")] - if obj.get("actions") is not None - else None - ), - } + obj["format"] = obj.get("format") + obj["actions"] = ( + [MappingKitAction.from_dict(_item) for _item in obj["actions"]] + if obj.get("actions") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/mapping_kit_action.py b/algoliasearch/ingestion/models/mapping_kit_action.py index b66ef8a90..1cf3285be 100644 --- a/algoliasearch/ingestion/models/mapping_kit_action.py +++ b/algoliasearch/ingestion/models/mapping_kit_action.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,53 +26,39 @@ class MappingKitAction(BaseModel): Describes how a destination object should be resolved by means of applying a set of directives. """ - id: Optional[StrictStr] = Field( - default=None, description="ID to uniquely identify this action." - ) - enabled: StrictBool = Field(description="Whether this action has any effect.") - trigger: StrictStr = Field( - description="Condition which must be satisfied to apply the action. If this evaluates to false, the action is not applied, and the process attempts to apply the next action, if any." - ) + id: Optional[str] = Field(default=None, alias="id") + """ ID to uniquely identify this action. """ + enabled: bool = Field(alias="enabled") + """ Whether this action has any effect. """ + trigger: str = Field(alias="trigger") + """ Condition which must be satisfied to apply the action. If this evaluates to false, the action is not applied, and the process attempts to apply the next action, if any. """ field_directives: List[MappingFieldDirective] = Field(alias="fieldDirectives") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of MappingKitAction from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.field_directives: - for _item in self.field_directives: - if _item: - _items.append(_item.to_dict()) - _dict["fieldDirectives"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of MappingKitAction from a dict""" if obj is None: return None @@ -80,19 +66,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "id": obj.get("id"), - "enabled": obj.get("enabled"), - "trigger": obj.get("trigger"), - "fieldDirectives": ( - [ - MappingFieldDirective.from_dict(_item) - for _item in obj.get("fieldDirectives") - ] - if obj.get("fieldDirectives") is not None - else None - ), - } + obj["fieldDirectives"] = ( + [MappingFieldDirective.from_dict(_item) for _item in obj["fieldDirectives"]] + if obj.get("fieldDirectives") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/mapping_type_csv.py b/algoliasearch/ingestion/models/mapping_type_csv.py index 69e6a42d7..25f07fe3a 100644 --- a/algoliasearch/ingestion/models/mapping_type_csv.py +++ b/algoliasearch/ingestion/models/mapping_type_csv.py @@ -25,9 +25,13 @@ class MappingTypeCSV(str, Enum): allowed enum values """ STRING = "string" + INTEGER = "integer" + FLOAT = "float" + BOOLEAN = "boolean" + JSON = "json" @classmethod diff --git a/algoliasearch/ingestion/models/method_type.py b/algoliasearch/ingestion/models/method_type.py index d25e4a05c..63d177e79 100644 --- a/algoliasearch/ingestion/models/method_type.py +++ b/algoliasearch/ingestion/models/method_type.py @@ -25,6 +25,7 @@ class MethodType(str, Enum): allowed enum values """ GET = "GET" + POST = "POST" @classmethod diff --git a/algoliasearch/ingestion/models/on_demand_trigger.py b/algoliasearch/ingestion/models/on_demand_trigger.py index c724431d9..0afe069a4 100644 --- a/algoliasearch/ingestion/models/on_demand_trigger.py +++ b/algoliasearch/ingestion/models/on_demand_trigger.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,45 +26,35 @@ class OnDemandTrigger(BaseModel): Trigger information for manually-triggered tasks. """ - type: OnDemandTriggerType - last_run: Optional[StrictStr] = Field( - default=None, - description="The last time the scheduled task ran in RFC 3339 format.", - alias="lastRun", - ) + type: OnDemandTriggerType = Field(alias="type") + last_run: Optional[str] = Field(default=None, alias="lastRun") + """ The last time the scheduled task ran in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of OnDemandTrigger from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of OnDemandTrigger from a dict""" if obj is None: return None @@ -72,7 +62,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"type": obj.get("type"), "lastRun": obj.get("lastRun")} - ) - return _obj + obj["type"] = obj.get("type") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/on_demand_trigger_input.py b/algoliasearch/ingestion/models/on_demand_trigger_input.py index e1ce90b13..743ceaca1 100644 --- a/algoliasearch/ingestion/models/on_demand_trigger_input.py +++ b/algoliasearch/ingestion/models/on_demand_trigger_input.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,40 +26,33 @@ class OnDemandTriggerInput(BaseModel): Trigger information for manually-triggered tasks. """ - type: OnDemandTriggerType + type: OnDemandTriggerType = Field(alias="type") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of OnDemandTriggerInput from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of OnDemandTriggerInput from a dict""" if obj is None: return None @@ -67,5 +60,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"type": obj.get("type")}) - return _obj + obj["type"] = obj.get("type") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/order_keys.py b/algoliasearch/ingestion/models/order_keys.py index a0385c45c..237439c51 100644 --- a/algoliasearch/ingestion/models/order_keys.py +++ b/algoliasearch/ingestion/models/order_keys.py @@ -25,6 +25,7 @@ class OrderKeys(str, Enum): allowed enum values """ ASC = "asc" + DESC = "desc" @classmethod diff --git a/algoliasearch/ingestion/models/pagination.py b/algoliasearch/ingestion/models/pagination.py index 83d82eb20..1ca0f6236 100644 --- a/algoliasearch/ingestion/models/pagination.py +++ b/algoliasearch/ingestion/models/pagination.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class Pagination(BaseModel): @@ -23,51 +23,40 @@ class Pagination(BaseModel): Paginated API response. """ - nb_pages: Annotated[int, Field(strict=True, ge=1)] = Field( - description="Number of pages in the API response.", alias="nbPages" - ) - page: Annotated[int, Field(strict=True, ge=1)] = Field( - description="Page of the API response to retrieve." - ) - nb_items: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of items in the API response.", alias="nbItems" - ) - items_per_page: Annotated[int, Field(le=100, strict=True, ge=1)] = Field( - description="Number of items per page.", alias="itemsPerPage" - ) + nb_pages: int = Field(alias="nbPages") + """ Number of pages in the API response. """ + page: int = Field(alias="page") + """ Page of the API response to retrieve. """ + nb_items: int = Field(alias="nbItems") + """ Number of items in the API response. """ + items_per_page: int = Field(alias="itemsPerPage") + """ Number of items per page. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Pagination from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Pagination from a dict""" if obj is None: return None @@ -75,12 +64,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "nbPages": obj.get("nbPages"), - "page": obj.get("page"), - "nbItems": obj.get("nbItems"), - "itemsPerPage": obj.get("itemsPerPage"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/platform.py b/algoliasearch/ingestion/models/platform.py index 50bab5c22..9d728fd60 100644 --- a/algoliasearch/ingestion/models/platform.py +++ b/algoliasearch/ingestion/models/platform.py @@ -25,7 +25,9 @@ class Platform(str, Enum): allowed enum values """ BIGCOMMERCE = "bigcommerce" + COMMERCETOOLS = "commercetools" + SHOPIFY = "shopify" @classmethod diff --git a/algoliasearch/ingestion/models/platform_with_none.py b/algoliasearch/ingestion/models/platform_with_none.py index 2b6d2c099..4d368b32e 100644 --- a/algoliasearch/ingestion/models/platform_with_none.py +++ b/algoliasearch/ingestion/models/platform_with_none.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -27,9 +27,12 @@ class PlatformWithNone(BaseModel): PlatformWithNone """ - oneof_schema_1_validator: Optional[Platform] = None - oneof_schema_2_validator: Optional[PlatformNone] = None + oneof_schema_1_validator: Optional[Platform] = Field(default=None) + + oneof_schema_2_validator: Optional[PlatformNone] = Field(default=None) + actual_instance: Optional[Union[Platform, PlatformNone]] = None + one_of_schemas: Set[str] = {"Platform", "PlatformNone"} def __init__(self, *args, **kwargs) -> None: if args: @@ -53,7 +56,8 @@ def unwrap_actual_instance(self) -> Optional[Union[Platform, PlatformNone]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of PlatformWithNone from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -85,17 +89,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], Platform, PlatformNone]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/ingestion/models/push_task_payload.py b/algoliasearch/ingestion/models/push_task_payload.py index e28ed097c..b0dd7f274 100644 --- a/algoliasearch/ingestion/models/push_task_payload.py +++ b/algoliasearch/ingestion/models/push_task_payload.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,47 +27,34 @@ class PushTaskPayload(BaseModel): PushTaskPayload """ - action: Action - records: List[PushTaskRecords] + action: Action = Field(alias="action") + records: List[PushTaskRecords] = Field(alias="records") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of PushTaskPayload from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.records: - for _item in self.records: - if _item: - _items.append(_item.to_dict()) - _dict["records"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of PushTaskPayload from a dict""" if obj is None: return None @@ -75,14 +62,11 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "action": obj.get("action"), - "records": ( - [PushTaskRecords.from_dict(_item) for _item in obj.get("records")] - if obj.get("records") is not None - else None - ), - } + obj["action"] = obj.get("action") + obj["records"] = ( + [PushTaskRecords.from_dict(_item) for _item in obj["records"]] + if obj.get("records") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/push_task_records.py b/algoliasearch/ingestion/models/push_task_records.py index 8c772c6d9..04af5790f 100644 --- a/algoliasearch/ingestion/models/push_task_records.py +++ b/algoliasearch/ingestion/models/push_task_records.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, ClassVar, Dict, List +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,52 +23,35 @@ class PushTaskRecords(BaseModel): PushTaskRecords """ - object_id: StrictStr = Field( - description="Unique record identifier.", alias="objectID" - ) - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["objectID"] + object_id: str = Field(alias="objectID") + """ Unique record identifier. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + extra="allow", ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of PushTaskRecords from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={ - "additional_properties", - }, exclude_none=True, exclude_unset=True, ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of PushTaskRecords from a dict""" if obj is None: return None @@ -76,10 +59,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"objectID": obj.get("objectID")}) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/record_type.py b/algoliasearch/ingestion/models/record_type.py index aae30858a..8432b6629 100644 --- a/algoliasearch/ingestion/models/record_type.py +++ b/algoliasearch/ingestion/models/record_type.py @@ -25,6 +25,7 @@ class RecordType(str, Enum): allowed enum values """ PRODUCT = "product" + VARIANT = "variant" @classmethod diff --git a/algoliasearch/ingestion/models/run.py b/algoliasearch/ingestion/models/run.py index b5244a4c0..9bd50327a 100644 --- a/algoliasearch/ingestion/models/run.py +++ b/algoliasearch/ingestion/models/run.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.ingestion.models.run_outcome import RunOutcome @@ -30,74 +30,52 @@ class Run(BaseModel): Run """ - run_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a task run.", alias="runID" - ) - app_id: StrictStr = Field(alias="appID") - task_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a task.", alias="taskID" - ) - status: RunStatus - progress: Optional[RunProgress] = None - outcome: Optional[RunOutcome] = None - failure_threshold: Optional[Annotated[int, Field(le=100, strict=True, ge=0)]] = ( - Field( - default=None, - description="Maximum accepted percentage of failures for a task run to finish successfully.", - alias="failureThreshold", - ) - ) - reason: Optional[StrictStr] = Field( - default=None, description="More information about the task run's outcome." - ) + run_id: str = Field(alias="runID") + """ Universally unique identifier (UUID) of a task run. """ + app_id: str = Field(alias="appID") + task_id: str = Field(alias="taskID") + """ Universally unique identifier (UUID) of a task. """ + status: RunStatus = Field(alias="status") + progress: Optional[RunProgress] = Field(default=None, alias="progress") + outcome: Optional[RunOutcome] = Field(default=None, alias="outcome") + failure_threshold: Optional[int] = Field(default=None, alias="failureThreshold") + """ Maximum accepted percentage of failures for a task run to finish successfully. """ + reason: Optional[str] = Field(default=None, alias="reason") + """ More information about the task run's outcome. """ reason_code: Optional[RunReasonCode] = Field(default=None, alias="reasonCode") - type: RunType - created_at: StrictStr = Field( - description="Date of creation in RFC 3339 format.", alias="createdAt" - ) - started_at: Optional[StrictStr] = Field( - default=None, description="Date of start in RFC 3339 format.", alias="startedAt" - ) - finished_at: Optional[StrictStr] = Field( - default=None, - description="Date of finish in RFC 3339 format.", - alias="finishedAt", - ) + type: RunType = Field(alias="type") + created_at: str = Field(alias="createdAt") + """ Date of creation in RFC 3339 format. """ + started_at: Optional[str] = Field(default=None, alias="startedAt") + """ Date of start in RFC 3339 format. """ + finished_at: Optional[str] = Field(default=None, alias="finishedAt") + """ Date of finish in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Run from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.progress: - _dict["progress"] = self.progress.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Run from a dict""" if obj is None: return None @@ -105,25 +83,14 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "runID": obj.get("runID"), - "appID": obj.get("appID"), - "taskID": obj.get("taskID"), - "status": obj.get("status"), - "progress": ( - RunProgress.from_dict(obj.get("progress")) - if obj.get("progress") is not None - else None - ), - "outcome": obj.get("outcome"), - "failureThreshold": obj.get("failureThreshold"), - "reason": obj.get("reason"), - "reasonCode": obj.get("reasonCode"), - "type": obj.get("type"), - "createdAt": obj.get("createdAt"), - "startedAt": obj.get("startedAt"), - "finishedAt": obj.get("finishedAt"), - } + obj["status"] = obj.get("status") + obj["progress"] = ( + RunProgress.from_dict(obj["progress"]) + if obj.get("progress") is not None + else None ) - return _obj + obj["outcome"] = obj.get("outcome") + obj["reasonCode"] = obj.get("reasonCode") + obj["type"] = obj.get("type") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/run_list_response.py b/algoliasearch/ingestion/models/run_list_response.py index 8a6e04b91..382550a0c 100644 --- a/algoliasearch/ingestion/models/run_list_response.py +++ b/algoliasearch/ingestion/models/run_list_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,52 +28,35 @@ class RunListResponse(BaseModel): RunListResponse """ - runs: List[Run] - pagination: Pagination - window: Window + runs: List[Run] = Field(alias="runs") + pagination: Pagination = Field(alias="pagination") + window: Window = Field(alias="window") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RunListResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.runs: - for _item in self.runs: - if _item: - _items.append(_item.to_dict()) - _dict["runs"] = _items - if self.pagination: - _dict["pagination"] = self.pagination.to_dict() - if self.window: - _dict["window"] = self.window.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RunListResponse from a dict""" if obj is None: return None @@ -81,23 +64,18 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "runs": ( - [Run.from_dict(_item) for _item in obj.get("runs")] - if obj.get("runs") is not None - else None - ), - "pagination": ( - Pagination.from_dict(obj.get("pagination")) - if obj.get("pagination") is not None - else None - ), - "window": ( - Window.from_dict(obj.get("window")) - if obj.get("window") is not None - else None - ), - } + obj["runs"] = ( + [Run.from_dict(_item) for _item in obj["runs"]] + if obj.get("runs") is not None + else None + ) + obj["pagination"] = ( + Pagination.from_dict(obj["pagination"]) + if obj.get("pagination") is not None + else None ) - return _obj + obj["window"] = ( + Window.from_dict(obj["window"]) if obj.get("window") is not None else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/run_outcome.py b/algoliasearch/ingestion/models/run_outcome.py index ac7d18ce0..6a4d83be1 100644 --- a/algoliasearch/ingestion/models/run_outcome.py +++ b/algoliasearch/ingestion/models/run_outcome.py @@ -25,7 +25,9 @@ class RunOutcome(str, Enum): allowed enum values """ SUCCESS = "success" + FAILURE = "failure" + PROCESSING = "processing" @classmethod diff --git a/algoliasearch/ingestion/models/run_progress.py b/algoliasearch/ingestion/models/run_progress.py index 8074c4b54..335c7df2a 100644 --- a/algoliasearch/ingestion/models/run_progress.py +++ b/algoliasearch/ingestion/models/run_progress.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,45 +23,38 @@ class RunProgress(BaseModel): RunProgress """ - expected_nb_of_events: Optional[StrictInt] = Field( + expected_nb_of_events: Optional[int] = Field( default=None, alias="expectedNbOfEvents" ) - received_nb_of_events: Optional[StrictInt] = Field( + received_nb_of_events: Optional[int] = Field( default=None, alias="receivedNbOfEvents" ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RunProgress from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RunProgress from a dict""" if obj is None: return None @@ -69,10 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "expectedNbOfEvents": obj.get("expectedNbOfEvents"), - "receivedNbOfEvents": obj.get("receivedNbOfEvents"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/run_reason_code.py b/algoliasearch/ingestion/models/run_reason_code.py index 838469065..882145f13 100644 --- a/algoliasearch/ingestion/models/run_reason_code.py +++ b/algoliasearch/ingestion/models/run_reason_code.py @@ -25,11 +25,17 @@ class RunReasonCode(str, Enum): allowed enum values """ INTERNAL = "internal" + CRITICAL = "critical" + NO_EVENTS = "no_events" + TOO_MANY_ERRORS = "too_many_errors" + OK = "ok" + DISCARDED = "discarded" + BLOCKING = "blocking" @classmethod diff --git a/algoliasearch/ingestion/models/run_response.py b/algoliasearch/ingestion/models/run_response.py index 95718e94e..94c5492c6 100644 --- a/algoliasearch/ingestion/models/run_response.py +++ b/algoliasearch/ingestion/models/run_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,45 +23,36 @@ class RunResponse(BaseModel): API response for running a task. """ - run_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a task run.", alias="runID" - ) - created_at: StrictStr = Field( - description="Date of creation in RFC 3339 format.", alias="createdAt" - ) + run_id: str = Field(alias="runID") + """ Universally unique identifier (UUID) of a task run. """ + created_at: str = Field(alias="createdAt") + """ Date of creation in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RunResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RunResponse from a dict""" if obj is None: return None @@ -69,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"runID": obj.get("runID"), "createdAt": obj.get("createdAt")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/run_sort_keys.py b/algoliasearch/ingestion/models/run_sort_keys.py index ff1ae1fea..5b6fc024e 100644 --- a/algoliasearch/ingestion/models/run_sort_keys.py +++ b/algoliasearch/ingestion/models/run_sort_keys.py @@ -25,7 +25,9 @@ class RunSortKeys(str, Enum): allowed enum values """ STATUS = "status" + UPDATEDAT = "updatedAt" + CREATEDAT = "createdAt" @classmethod diff --git a/algoliasearch/ingestion/models/run_source_payload.py b/algoliasearch/ingestion/models/run_source_payload.py index 768a051f3..8eeefdb28 100644 --- a/algoliasearch/ingestion/models/run_source_payload.py +++ b/algoliasearch/ingestion/models/run_source_payload.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,53 +26,39 @@ class RunSourcePayload(BaseModel): RunSourcePayload """ - index_to_include: Optional[List[StrictStr]] = Field( - default=None, - description="List of index names to include in reidexing/update.", - alias="indexToInclude", - ) - index_to_exclude: Optional[List[StrictStr]] = Field( - default=None, - description="List of index names to exclude in reidexing/update.", - alias="indexToExclude", - ) - entity_ids: Optional[List[StrictStr]] = Field( - default=None, description="List of entityID to update.", alias="entityIDs" - ) + index_to_include: Optional[List[str]] = Field(default=None, alias="indexToInclude") + """ List of index names to include in reidexing/update. """ + index_to_exclude: Optional[List[str]] = Field(default=None, alias="indexToExclude") + """ List of index names to exclude in reidexing/update. """ + entity_ids: Optional[List[str]] = Field(default=None, alias="entityIDs") + """ List of entityID to update. """ entity_type: Optional[EntityType] = Field(default=None, alias="entityType") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RunSourcePayload from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RunSourcePayload from a dict""" if obj is None: return None @@ -80,12 +66,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "indexToInclude": obj.get("indexToInclude"), - "indexToExclude": obj.get("indexToExclude"), - "entityIDs": obj.get("entityIDs"), - "entityType": obj.get("entityType"), - } - ) - return _obj + obj["entityType"] = obj.get("entityType") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/run_source_response.py b/algoliasearch/ingestion/models/run_source_response.py index c65026044..5ee76ca3c 100644 --- a/algoliasearch/ingestion/models/run_source_response.py +++ b/algoliasearch/ingestion/models/run_source_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,46 +23,36 @@ class RunSourceResponse(BaseModel): RunSourceResponse """ - task_with_run_id: Dict[str, StrictStr] = Field( - description="Map of taskID sent for reindex with the corresponding runID.", - alias="taskWithRunID", - ) - created_at: StrictStr = Field( - description="Date of creation in RFC 3339 format.", alias="createdAt" - ) + task_with_run_id: Dict[str, str] = Field(alias="taskWithRunID") + """ Map of taskID sent for reindex with the corresponding runID. """ + created_at: str = Field(alias="createdAt") + """ Date of creation in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RunSourceResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RunSourceResponse from a dict""" if obj is None: return None @@ -70,10 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "taskWithRunID": obj.get("taskWithRunID"), - "createdAt": obj.get("createdAt"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/run_status.py b/algoliasearch/ingestion/models/run_status.py index cd346582c..a2cda3b07 100644 --- a/algoliasearch/ingestion/models/run_status.py +++ b/algoliasearch/ingestion/models/run_status.py @@ -25,9 +25,13 @@ class RunStatus(str, Enum): allowed enum values """ CREATED = "created" + STARTED = "started" + IDLED = "idled" + FINISHED = "finished" + SKIPPED = "skipped" @classmethod diff --git a/algoliasearch/ingestion/models/run_type.py b/algoliasearch/ingestion/models/run_type.py index 393a87323..697348091 100644 --- a/algoliasearch/ingestion/models/run_type.py +++ b/algoliasearch/ingestion/models/run_type.py @@ -25,9 +25,13 @@ class RunType(str, Enum): allowed enum values """ REINDEX = "reindex" + UPDATE = "update" + DISCOVER = "discover" + VALIDATE = "validate" + PUSH = "push" @classmethod diff --git a/algoliasearch/ingestion/models/schedule_trigger.py b/algoliasearch/ingestion/models/schedule_trigger.py index 3a4134f5e..00be9f92d 100644 --- a/algoliasearch/ingestion/models/schedule_trigger.py +++ b/algoliasearch/ingestion/models/schedule_trigger.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,50 +26,39 @@ class ScheduleTrigger(BaseModel): Trigger information for scheduled tasks. """ - type: ScheduleTriggerType - cron: StrictStr = Field(description="Cron expression for the task's schedule.") - last_run: Optional[StrictStr] = Field( - default=None, - description="The last time the scheduled task ran in RFC 3339 format.", - alias="lastRun", - ) - next_run: StrictStr = Field( - description="The next scheduled run of the task in RFC 3339 format.", - alias="nextRun", - ) + type: ScheduleTriggerType = Field(alias="type") + cron: str = Field(alias="cron") + """ Cron expression for the task's schedule. """ + last_run: Optional[str] = Field(default=None, alias="lastRun") + """ The last time the scheduled task ran in RFC 3339 format. """ + next_run: str = Field(alias="nextRun") + """ The next scheduled run of the task in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ScheduleTrigger from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ScheduleTrigger from a dict""" if obj is None: return None @@ -77,12 +66,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "type": obj.get("type"), - "cron": obj.get("cron"), - "lastRun": obj.get("lastRun"), - "nextRun": obj.get("nextRun"), - } - ) - return _obj + obj["type"] = obj.get("type") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/schedule_trigger_input.py b/algoliasearch/ingestion/models/schedule_trigger_input.py index d8a6c7d80..99d8174c4 100644 --- a/algoliasearch/ingestion/models/schedule_trigger_input.py +++ b/algoliasearch/ingestion/models/schedule_trigger_input.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,41 +26,35 @@ class ScheduleTriggerInput(BaseModel): Trigger input for scheduled tasks. """ - type: ScheduleTriggerType - cron: StrictStr = Field(description="Cron expression for the task's schedule.") + type: ScheduleTriggerType = Field(alias="type") + cron: str = Field(alias="cron") + """ Cron expression for the task's schedule. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ScheduleTriggerInput from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ScheduleTriggerInput from a dict""" if obj is None: return None @@ -68,5 +62,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"type": obj.get("type"), "cron": obj.get("cron")}) - return _obj + obj["type"] = obj.get("type") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/shopify_input.py b/algoliasearch/ingestion/models/shopify_input.py index c40d8fe1c..ffd294381 100644 --- a/algoliasearch/ingestion/models/shopify_input.py +++ b/algoliasearch/ingestion/models/shopify_input.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,49 +27,34 @@ class ShopifyInput(BaseModel): Represents the required elements of the task input when using a `shopify` source. """ - metafields: List[ShopifyMetafield] - market: ShopifyMarket + metafields: List[ShopifyMetafield] = Field(alias="metafields") + market: ShopifyMarket = Field(alias="market") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ShopifyInput from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.metafields: - for _item in self.metafields: - if _item: - _items.append(_item.to_dict()) - _dict["metafields"] = _items - if self.market: - _dict["market"] = self.market.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ShopifyInput from a dict""" if obj is None: return None @@ -77,21 +62,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "metafields": ( - [ - ShopifyMetafield.from_dict(_item) - for _item in obj.get("metafields") - ] - if obj.get("metafields") is not None - else None - ), - "market": ( - ShopifyMarket.from_dict(obj.get("market")) - if obj.get("market") is not None - else None - ), - } + obj["metafields"] = ( + [ShopifyMetafield.from_dict(_item) for _item in obj["metafields"]] + if obj.get("metafields") is not None + else None ) - return _obj + obj["market"] = ( + ShopifyMarket.from_dict(obj["market"]) + if obj.get("market") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/shopify_market.py b/algoliasearch/ingestion/models/shopify_market.py index 8d6c70be3..8f4950bba 100644 --- a/algoliasearch/ingestion/models/shopify_market.py +++ b/algoliasearch/ingestion/models/shopify_market.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,42 +23,35 @@ class ShopifyMarket(BaseModel): Represents a market in Shopify. """ - countries: List[StrictStr] - currencies: List[StrictStr] - locales: List[StrictStr] + countries: List[str] = Field(alias="countries") + currencies: List[str] = Field(alias="currencies") + locales: List[str] = Field(alias="locales") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ShopifyMarket from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ShopifyMarket from a dict""" if obj is None: return None @@ -66,11 +59,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "countries": obj.get("countries"), - "currencies": obj.get("currencies"), - "locales": obj.get("locales"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/shopify_metafield.py b/algoliasearch/ingestion/models/shopify_metafield.py index 0426a2fea..2f3f5ab27 100644 --- a/algoliasearch/ingestion/models/shopify_metafield.py +++ b/algoliasearch/ingestion/models/shopify_metafield.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,42 +23,35 @@ class ShopifyMetafield(BaseModel): Represents a metafield in Shopify. """ - namespace: StrictStr - key: StrictStr - value: StrictStr + namespace: str = Field(alias="namespace") + key: str = Field(alias="key") + value: str = Field(alias="value") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ShopifyMetafield from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ShopifyMetafield from a dict""" if obj is None: return None @@ -66,11 +59,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "namespace": obj.get("namespace"), - "key": obj.get("key"), - "value": obj.get("value"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/sort_keys.py b/algoliasearch/ingestion/models/sort_keys.py index f33728244..1deddccfe 100644 --- a/algoliasearch/ingestion/models/sort_keys.py +++ b/algoliasearch/ingestion/models/sort_keys.py @@ -25,8 +25,11 @@ class SortKeys(str, Enum): allowed enum values """ NAME = "name" + TYPE = "type" + UPDATEDAT = "updatedAt" + CREATEDAT = "createdAt" @classmethod diff --git a/algoliasearch/ingestion/models/source.py b/algoliasearch/ingestion/models/source.py index ef8bf8012..4b1898990 100644 --- a/algoliasearch/ingestion/models/source.py +++ b/algoliasearch/ingestion/models/source.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,61 +27,43 @@ class Source(BaseModel): Source """ - source_id: StrictStr = Field( - description="Universally uniqud identifier (UUID) of a source.", - alias="sourceID", - ) - type: SourceType - name: StrictStr - input: Optional[SourceInput] = None - authentication_id: Optional[StrictStr] = Field( - default=None, - description="Universally unique identifier (UUID) of an authentication resource.", - alias="authenticationID", - ) - created_at: StrictStr = Field( - description="Date of creation in RFC 3339 format.", alias="createdAt" - ) - updated_at: Optional[StrictStr] = Field( - default=None, - description="Date of last update in RFC 3339 format.", - alias="updatedAt", - ) + source_id: str = Field(alias="sourceID") + """ Universally uniqud identifier (UUID) of a source. """ + type: SourceType = Field(alias="type") + name: str = Field(alias="name") + input: Optional[SourceInput] = Field(default=None, alias="input") + authentication_id: Optional[str] = Field(default=None, alias="authenticationID") + """ Universally unique identifier (UUID) of an authentication resource. """ + created_at: str = Field(alias="createdAt") + """ Date of creation in RFC 3339 format. """ + updated_at: Optional[str] = Field(default=None, alias="updatedAt") + """ Date of last update in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Source from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.input: - _dict["input"] = self.input.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Source from a dict""" if obj is None: return None @@ -89,19 +71,11 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "sourceID": obj.get("sourceID"), - "type": obj.get("type"), - "name": obj.get("name"), - "input": ( - SourceInput.from_dict(obj.get("input")) - if obj.get("input") is not None - else None - ), - "authenticationID": obj.get("authenticationID"), - "createdAt": obj.get("createdAt"), - "updatedAt": obj.get("updatedAt"), - } + obj["type"] = obj.get("type") + obj["input"] = ( + SourceInput.from_dict(obj["input"]) + if obj.get("input") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_big_commerce.py b/algoliasearch/ingestion/models/source_big_commerce.py index 23ae6651d..360a4010c 100644 --- a/algoliasearch/ingestion/models/source_big_commerce.py +++ b/algoliasearch/ingestion/models/source_big_commerce.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,11 +27,10 @@ class SourceBigCommerce(BaseModel): SourceBigCommerce """ - store_hash: StrictStr = Field( - description="Store hash identifying your BigCommerce store.", alias="storeHash" - ) - channel: Optional[BigCommerceChannel] = None - custom_fields: Optional[List[StrictStr]] = Field(default=None, alias="customFields") + store_hash: str = Field(alias="storeHash") + """ Store hash identifying your BigCommerce store. """ + channel: Optional[BigCommerceChannel] = Field(default=None, alias="channel") + custom_fields: Optional[List[str]] = Field(default=None, alias="customFields") product_metafields: Optional[List[BigCommerceMetafield]] = Field( default=None, alias="productMetafields" ) @@ -40,51 +39,30 @@ class SourceBigCommerce(BaseModel): ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceBigCommerce from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.channel: - _dict["channel"] = self.channel.to_dict() - _items = [] - if self.product_metafields: - for _item in self.product_metafields: - if _item: - _items.append(_item.to_dict()) - _dict["productMetafields"] = _items - _items = [] - if self.variant_metafields: - for _item in self.variant_metafields: - if _item: - _items.append(_item.to_dict()) - _dict["variantMetafields"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceBigCommerce from a dict""" if obj is None: return None @@ -92,31 +70,26 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "storeHash": obj.get("storeHash"), - "channel": ( - BigCommerceChannel.from_dict(obj.get("channel")) - if obj.get("channel") is not None - else None - ), - "customFields": obj.get("customFields"), - "productMetafields": ( - [ - BigCommerceMetafield.from_dict(_item) - for _item in obj.get("productMetafields") - ] - if obj.get("productMetafields") is not None - else None - ), - "variantMetafields": ( - [ - BigCommerceMetafield.from_dict(_item) - for _item in obj.get("variantMetafields") - ] - if obj.get("variantMetafields") is not None - else None - ), - } + obj["channel"] = ( + BigCommerceChannel.from_dict(obj["channel"]) + if obj.get("channel") is not None + else None ) - return _obj + obj["productMetafields"] = ( + [ + BigCommerceMetafield.from_dict(_item) + for _item in obj["productMetafields"] + ] + if obj.get("productMetafields") is not None + else None + ) + obj["variantMetafields"] = ( + [ + BigCommerceMetafield.from_dict(_item) + for _item in obj["variantMetafields"] + ] + if obj.get("variantMetafields") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_big_query.py b/algoliasearch/ingestion/models/source_big_query.py index 1c9e6f067..3ae98d6ea 100644 --- a/algoliasearch/ingestion/models/source_big_query.py +++ b/algoliasearch/ingestion/models/source_big_query.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,64 +26,45 @@ class SourceBigQuery(BaseModel): SourceBigQuery """ - project_id: StrictStr = Field( - description="Project ID of the BigQuery source.", alias="projectID" - ) - dataset_id: StrictStr = Field( - description="Dataset ID of the BigQuery source.", alias="datasetID" - ) + project_id: str = Field(alias="projectID") + """ Project ID of the BigQuery source. """ + dataset_id: str = Field(alias="datasetID") + """ Dataset ID of the BigQuery source. """ data_type: Optional[BigQueryDataType] = Field(default=None, alias="dataType") - table: Optional[StrictStr] = Field( - default=None, description="Table name for the BigQuery export." - ) - table_prefix: Optional[StrictStr] = Field( - default=None, - description="Table prefix for a Google Analytics 4 data export to BigQuery.", - alias="tablePrefix", - ) - custom_sql_request: Optional[StrictStr] = Field( - default=None, - description="Custom SQL request to extract data from the BigQuery table.", - alias="customSQLRequest", - ) - unique_id_column: Optional[StrictStr] = Field( - default=None, - description="Name of a column that contains a unique ID which will be used as `objectID` in Algolia.", - alias="uniqueIDColumn", - ) + table: Optional[str] = Field(default=None, alias="table") + """ Table name for the BigQuery export. """ + table_prefix: Optional[str] = Field(default=None, alias="tablePrefix") + """ Table prefix for a Google Analytics 4 data export to BigQuery. """ + custom_sql_request: Optional[str] = Field(default=None, alias="customSQLRequest") + """ Custom SQL request to extract data from the BigQuery table. """ + unique_id_column: Optional[str] = Field(default=None, alias="uniqueIDColumn") + """ Name of a column that contains a unique ID which will be used as `objectID` in Algolia. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceBigQuery from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceBigQuery from a dict""" if obj is None: return None @@ -91,15 +72,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "projectID": obj.get("projectID"), - "datasetID": obj.get("datasetID"), - "dataType": obj.get("dataType"), - "table": obj.get("table"), - "tablePrefix": obj.get("tablePrefix"), - "customSQLRequest": obj.get("customSQLRequest"), - "uniqueIDColumn": obj.get("uniqueIDColumn"), - } - ) - return _obj + obj["dataType"] = obj.get("dataType") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_commercetools.py b/algoliasearch/ingestion/models/source_commercetools.py index e13b55b5b..8f2923cbb 100644 --- a/algoliasearch/ingestion/models/source_commercetools.py +++ b/algoliasearch/ingestion/models/source_commercetools.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.ingestion.models.commercetools_custom_fields import ( @@ -28,55 +28,44 @@ class SourceCommercetools(BaseModel): SourceCommercetools """ - store_keys: Optional[List[StrictStr]] = Field(default=None, alias="storeKeys") - locales: Optional[List[Annotated[str, Field(strict=True)]]] = Field( - default=None, description="Locales for your commercetools stores." - ) - url: StrictStr - project_key: StrictStr = Field(alias="projectKey") - fallback_is_in_stock_value: Optional[StrictBool] = Field( - default=True, - description="Whether a fallback value is stored in the Algolia record if there's no inventory information about the product. ", - alias="fallbackIsInStockValue", + store_keys: Optional[List[str]] = Field(default=None, alias="storeKeys") + locales: Optional[List[str]] = Field(default=None, alias="locales") + """ Locales for your commercetools stores. """ + url: str = Field(alias="url") + project_key: str = Field(alias="projectKey") + fallback_is_in_stock_value: Optional[bool] = Field( + default=None, alias="fallbackIsInStockValue" ) + """ Whether a fallback value is stored in the Algolia record if there's no inventory information about the product. """ custom_fields: Optional[CommercetoolsCustomFields] = Field( default=None, alias="customFields" ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceCommercetools from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.custom_fields: - _dict["customFields"] = self.custom_fields.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceCommercetools from a dict""" if obj is None: return None @@ -84,18 +73,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "storeKeys": obj.get("storeKeys"), - "locales": obj.get("locales"), - "url": obj.get("url"), - "projectKey": obj.get("projectKey"), - "fallbackIsInStockValue": obj.get("fallbackIsInStockValue"), - "customFields": ( - CommercetoolsCustomFields.from_dict(obj.get("customFields")) - if obj.get("customFields") is not None - else None - ), - } + obj["customFields"] = ( + CommercetoolsCustomFields.from_dict(obj["customFields"]) + if obj.get("customFields") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_create.py b/algoliasearch/ingestion/models/source_create.py index cf363fe41..06cb27313 100644 --- a/algoliasearch/ingestion/models/source_create.py +++ b/algoliasearch/ingestion/models/source_create.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,49 +27,38 @@ class SourceCreate(BaseModel): SourceCreate """ - type: SourceType - name: StrictStr = Field(description="Descriptive name of the source.") - input: Optional[SourceInput] = None - authentication_id: Optional[StrictStr] = Field( - default=None, - description="Universally unique identifier (UUID) of an authentication resource.", - alias="authenticationID", - ) + type: SourceType = Field(alias="type") + name: str = Field(alias="name") + """ Descriptive name of the source. """ + input: Optional[SourceInput] = Field(default=None, alias="input") + authentication_id: Optional[str] = Field(default=None, alias="authenticationID") + """ Universally unique identifier (UUID) of an authentication resource. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceCreate from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.input: - _dict["input"] = self.input.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceCreate from a dict""" if obj is None: return None @@ -77,16 +66,11 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "type": obj.get("type"), - "name": obj.get("name"), - "input": ( - SourceInput.from_dict(obj.get("input")) - if obj.get("input") is not None - else None - ), - "authenticationID": obj.get("authenticationID"), - } + obj["type"] = obj.get("type") + obj["input"] = ( + SourceInput.from_dict(obj["input"]) + if obj.get("input") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_create_response.py b/algoliasearch/ingestion/models/source_create_response.py index 93be5a0c4..ef30e472a 100644 --- a/algoliasearch/ingestion/models/source_create_response.py +++ b/algoliasearch/ingestion/models/source_create_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,47 +23,38 @@ class SourceCreateResponse(BaseModel): SourceCreateResponse """ - source_id: StrictStr = Field( - description="Universally uniqud identifier (UUID) of a source.", - alias="sourceID", - ) - name: StrictStr = Field(description="Descriptive name of the source.") - created_at: StrictStr = Field( - description="Date of creation in RFC 3339 format.", alias="createdAt" - ) + source_id: str = Field(alias="sourceID") + """ Universally uniqud identifier (UUID) of a source. """ + name: str = Field(alias="name") + """ Descriptive name of the source. """ + created_at: str = Field(alias="createdAt") + """ Date of creation in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceCreateResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceCreateResponse from a dict""" if obj is None: return None @@ -71,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "sourceID": obj.get("sourceID"), - "name": obj.get("name"), - "createdAt": obj.get("createdAt"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_csv.py b/algoliasearch/ingestion/models/source_csv.py index 11fc6131e..993489a01 100644 --- a/algoliasearch/ingestion/models/source_csv.py +++ b/algoliasearch/ingestion/models/source_csv.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.ingestion.models.mapping_type_csv import MappingTypeCSV @@ -27,56 +27,41 @@ class SourceCSV(BaseModel): SourceCSV """ - url: StrictStr = Field(description="URL of the file.") - unique_id_column: Optional[StrictStr] = Field( - default=None, - description="Name of a column that contains a unique ID which will be used as `objectID` in Algolia.", - alias="uniqueIDColumn", - ) - mapping: Optional[Dict[str, MappingTypeCSV]] = Field( - default=None, - description="Key-value pairs of column names and their expected types. ", - ) - method: Optional[MethodType] = None - delimiter: Optional[ - Annotated[str, Field(min_length=1, strict=True, max_length=1)] - ] = Field( - default=",", - description="The character used to split the value on each line, default to a comma (\\r, \\n, 0xFFFD, and space are forbidden).", - ) + url: str = Field(alias="url") + """ URL of the file. """ + unique_id_column: Optional[str] = Field(default=None, alias="uniqueIDColumn") + """ Name of a column that contains a unique ID which will be used as `objectID` in Algolia. """ + mapping: Optional[Dict[str, MappingTypeCSV]] = Field(default=None, alias="mapping") + """ Key-value pairs of column names and their expected types. """ + method: Optional[MethodType] = Field(default=None, alias="method") + delimiter: Optional[str] = Field(default=None, alias="delimiter") + """ The character used to split the value on each line, default to a comma (\\r, \\n, 0xFFFD, and space are forbidden). """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceCSV from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceCSV from a dict""" if obj is None: return None @@ -84,13 +69,7 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "url": obj.get("url"), - "uniqueIDColumn": obj.get("uniqueIDColumn"), - "mapping": dict((_k, _v) for _k, _v in obj.get("mapping").items()), - "method": obj.get("method"), - "delimiter": obj.get("delimiter"), - } - ) - return _obj + obj["mapping"] = dict((_k, _v) for _k, _v in obj.get("mapping").items()) + obj["method"] = obj.get("method") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_docker.py b/algoliasearch/ingestion/models/source_docker.py index b0875484b..4087e553c 100644 --- a/algoliasearch/ingestion/models/source_docker.py +++ b/algoliasearch/ingestion/models/source_docker.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,45 +28,39 @@ class SourceDocker(BaseModel): """ image_type: DockerImageType = Field(alias="imageType") - registry: DockerRegistry - image: StrictStr = Field(description="Docker image name.") - version: Optional[StrictStr] = Field( - default="latest", description="Docker image version." - ) - configuration: Dict[str, Any] = Field(description="Configuration of the spec.") + registry: DockerRegistry = Field(alias="registry") + image: str = Field(alias="image") + """ Docker image name. """ + version: Optional[str] = Field(default=None, alias="version") + """ Docker image version. """ + configuration: object = Field(alias="configuration") + """ Configuration of the spec. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceDocker from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceDocker from a dict""" if obj is None: return None @@ -74,13 +68,7 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "imageType": obj.get("imageType"), - "registry": obj.get("registry"), - "image": obj.get("image"), - "version": obj.get("version"), - "configuration": obj.get("configuration"), - } - ) - return _obj + obj["imageType"] = obj.get("imageType") + obj["registry"] = obj.get("registry") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_ga4_big_query_export.py b/algoliasearch/ingestion/models/source_ga4_big_query_export.py index 33350db36..98dad13d0 100644 --- a/algoliasearch/ingestion/models/source_ga4_big_query_export.py +++ b/algoliasearch/ingestion/models/source_ga4_big_query_export.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,51 +23,38 @@ class SourceGA4BigQueryExport(BaseModel): SourceGA4BigQueryExport """ - project_id: StrictStr = Field( - description="GCP project ID that the BigQuery export writes to.", - alias="projectID", - ) - dataset_id: StrictStr = Field( - description="BigQuery dataset ID that the BigQuery export writes to.", - alias="datasetID", - ) - table_prefix: StrictStr = Field( - description="Prefix of the tables that the BigQuery Export writes to.", - alias="tablePrefix", - ) + project_id: str = Field(alias="projectID") + """ GCP project ID that the BigQuery export writes to. """ + dataset_id: str = Field(alias="datasetID") + """ BigQuery dataset ID that the BigQuery export writes to. """ + table_prefix: str = Field(alias="tablePrefix") + """ Prefix of the tables that the BigQuery Export writes to. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceGA4BigQueryExport from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceGA4BigQueryExport from a dict""" if obj is None: return None @@ -75,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "projectID": obj.get("projectID"), - "datasetID": obj.get("datasetID"), - "tablePrefix": obj.get("tablePrefix"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_input.py b/algoliasearch/ingestion/models/source_input.py index 05f207cce..68c6cec34 100644 --- a/algoliasearch/ingestion/models/source_input.py +++ b/algoliasearch/ingestion/models/source_input.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -35,14 +35,22 @@ class SourceInput(BaseModel): SourceInput """ - oneof_schema_1_validator: Optional[SourceCommercetools] = None - oneof_schema_2_validator: Optional[SourceBigCommerce] = None - oneof_schema_3_validator: Optional[SourceJSON] = None - oneof_schema_4_validator: Optional[SourceCSV] = None - oneof_schema_5_validator: Optional[SourceBigQuery] = None - oneof_schema_6_validator: Optional[SourceGA4BigQueryExport] = None - oneof_schema_7_validator: Optional[SourceDocker] = None - oneof_schema_8_validator: Optional[SourceShopify] = None + oneof_schema_1_validator: Optional[SourceCommercetools] = Field(default=None) + + oneof_schema_2_validator: Optional[SourceBigCommerce] = Field(default=None) + + oneof_schema_3_validator: Optional[SourceJSON] = Field(default=None) + + oneof_schema_4_validator: Optional[SourceCSV] = Field(default=None) + + oneof_schema_5_validator: Optional[SourceBigQuery] = Field(default=None) + + oneof_schema_6_validator: Optional[SourceGA4BigQueryExport] = Field(default=None) + + oneof_schema_7_validator: Optional[SourceDocker] = Field(default=None) + + oneof_schema_8_validator: Optional[SourceShopify] = Field(default=None) + actual_instance: Optional[ Union[ SourceBigCommerce, @@ -55,6 +63,16 @@ class SourceInput(BaseModel): SourceShopify, ] ] = None + one_of_schemas: Set[str] = { + "SourceBigCommerce", + "SourceBigQuery", + "SourceCSV", + "SourceCommercetools", + "SourceDocker", + "SourceGA4BigQueryExport", + "SourceJSON", + "SourceShopify", + } def __init__(self, *args, **kwargs) -> None: if args: @@ -91,7 +109,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of SourceInput from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -159,17 +178,35 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[ + Union[ + Dict[str, Any], + SourceBigCommerce, + SourceBigQuery, + SourceCSV, + SourceCommercetools, + SourceDocker, + SourceGA4BigQueryExport, + SourceJSON, + SourceShopify, + ] + ]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/ingestion/models/source_json.py b/algoliasearch/ingestion/models/source_json.py index c77c9ec52..cec4f9dc5 100644 --- a/algoliasearch/ingestion/models/source_json.py +++ b/algoliasearch/ingestion/models/source_json.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,46 +26,37 @@ class SourceJSON(BaseModel): SourceJSON """ - url: StrictStr = Field(description="URL of the file.") - unique_id_column: Optional[StrictStr] = Field( - default=None, - description="Name of a column that contains a unique ID which will be used as `objectID` in Algolia.", - alias="uniqueIDColumn", - ) - method: Optional[MethodType] = None + url: str = Field(alias="url") + """ URL of the file. """ + unique_id_column: Optional[str] = Field(default=None, alias="uniqueIDColumn") + """ Name of a column that contains a unique ID which will be used as `objectID` in Algolia. """ + method: Optional[MethodType] = Field(default=None, alias="method") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceJSON from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceJSON from a dict""" if obj is None: return None @@ -73,11 +64,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "url": obj.get("url"), - "uniqueIDColumn": obj.get("uniqueIDColumn"), - "method": obj.get("method"), - } - ) - return _obj + obj["method"] = obj.get("method") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_search.py b/algoliasearch/ingestion/models/source_search.py index 3c7f9b041..d2213d60c 100644 --- a/algoliasearch/ingestion/models/source_search.py +++ b/algoliasearch/ingestion/models/source_search.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,40 +23,33 @@ class SourceSearch(BaseModel): SourceSearch """ - source_ids: List[StrictStr] = Field(alias="sourceIDs") + source_ids: List[str] = Field(alias="sourceIDs") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceSearch from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceSearch from a dict""" if obj is None: return None @@ -64,5 +57,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"sourceIDs": obj.get("sourceIDs")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_shopify.py b/algoliasearch/ingestion/models/source_shopify.py index 12b102c4a..040c7ed02 100644 --- a/algoliasearch/ingestion/models/source_shopify.py +++ b/algoliasearch/ingestion/models/source_shopify.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,47 +23,38 @@ class SourceShopify(BaseModel): SourceShopify """ - feature_flags: Optional[Dict[str, Any]] = Field( - default=None, - description="Feature flags for the Shopify source.", - alias="featureFlags", - ) - shop_url: StrictStr = Field( - description="URL of the Shopify store.", alias="shopURL" + feature_flags: Optional[Dict[str, object]] = Field( + default=None, alias="featureFlags" ) + """ Feature flags for the Shopify source. """ + shop_url: str = Field(alias="shopURL") + """ URL of the Shopify store. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceShopify from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceShopify from a dict""" if obj is None: return None @@ -71,7 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"featureFlags": obj.get("featureFlags"), "shopURL": obj.get("shopURL")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_sort_keys.py b/algoliasearch/ingestion/models/source_sort_keys.py index 1414c8e93..41a6c56ef 100644 --- a/algoliasearch/ingestion/models/source_sort_keys.py +++ b/algoliasearch/ingestion/models/source_sort_keys.py @@ -25,8 +25,11 @@ class SourceSortKeys(str, Enum): allowed enum values """ NAME = "name" + TYPE = "type" + UPDATEDAT = "updatedAt" + CREATEDAT = "createdAt" @classmethod diff --git a/algoliasearch/ingestion/models/source_type.py b/algoliasearch/ingestion/models/source_type.py index cc5f0e71f..cef44935f 100644 --- a/algoliasearch/ingestion/models/source_type.py +++ b/algoliasearch/ingestion/models/source_type.py @@ -25,14 +25,23 @@ class SourceType(str, Enum): allowed enum values """ BIGCOMMERCE = "bigcommerce" + BIGQUERY = "bigquery" + COMMERCETOOLS = "commercetools" + CSV = "csv" + DOCKER = "docker" + GA4BIGQUERYEXPORT = "ga4BigqueryExport" + JSON = "json" + SHOPIFY = "shopify" + SFCC = "sfcc" + PUSH = "push" @classmethod diff --git a/algoliasearch/ingestion/models/source_update.py b/algoliasearch/ingestion/models/source_update.py index ccf97855b..2fe91c077 100644 --- a/algoliasearch/ingestion/models/source_update.py +++ b/algoliasearch/ingestion/models/source_update.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,50 +26,37 @@ class SourceUpdate(BaseModel): SourceUpdate """ - name: Optional[StrictStr] = Field( - default=None, description="Descriptive name of the source." - ) - input: Optional[SourceUpdateInput] = None - authentication_id: Optional[StrictStr] = Field( - default=None, - description="Universally unique identifier (UUID) of an authentication resource.", - alias="authenticationID", - ) + name: Optional[str] = Field(default=None, alias="name") + """ Descriptive name of the source. """ + input: Optional[SourceUpdateInput] = Field(default=None, alias="input") + authentication_id: Optional[str] = Field(default=None, alias="authenticationID") + """ Universally unique identifier (UUID) of an authentication resource. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceUpdate from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.input: - _dict["input"] = self.input.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceUpdate from a dict""" if obj is None: return None @@ -77,15 +64,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "name": obj.get("name"), - "input": ( - SourceUpdateInput.from_dict(obj.get("input")) - if obj.get("input") is not None - else None - ), - "authenticationID": obj.get("authenticationID"), - } + obj["input"] = ( + SourceUpdateInput.from_dict(obj["input"]) + if obj.get("input") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_update_commercetools.py b/algoliasearch/ingestion/models/source_update_commercetools.py index 9261a76da..03a8c1cac 100644 --- a/algoliasearch/ingestion/models/source_update_commercetools.py +++ b/algoliasearch/ingestion/models/source_update_commercetools.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.ingestion.models.commercetools_custom_fields import ( @@ -28,54 +28,43 @@ class SourceUpdateCommercetools(BaseModel): SourceUpdateCommercetools """ - store_keys: Optional[List[StrictStr]] = Field(default=None, alias="storeKeys") - locales: Optional[List[Annotated[str, Field(strict=True)]]] = Field( - default=None, description="Locales for your commercetools stores." - ) - url: Optional[StrictStr] = None - fallback_is_in_stock_value: Optional[StrictBool] = Field( - default=None, - description="Whether a fallback value is stored in the Algolia record if there's no inventory information about the product. ", - alias="fallbackIsInStockValue", + store_keys: Optional[List[str]] = Field(default=None, alias="storeKeys") + locales: Optional[List[str]] = Field(default=None, alias="locales") + """ Locales for your commercetools stores. """ + url: Optional[str] = Field(default=None, alias="url") + fallback_is_in_stock_value: Optional[bool] = Field( + default=None, alias="fallbackIsInStockValue" ) + """ Whether a fallback value is stored in the Algolia record if there's no inventory information about the product. """ custom_fields: Optional[CommercetoolsCustomFields] = Field( default=None, alias="customFields" ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceUpdateCommercetools from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.custom_fields: - _dict["customFields"] = self.custom_fields.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceUpdateCommercetools from a dict""" if obj is None: return None @@ -83,17 +72,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "storeKeys": obj.get("storeKeys"), - "locales": obj.get("locales"), - "url": obj.get("url"), - "fallbackIsInStockValue": obj.get("fallbackIsInStockValue"), - "customFields": ( - CommercetoolsCustomFields.from_dict(obj.get("customFields")) - if obj.get("customFields") is not None - else None - ), - } + obj["customFields"] = ( + CommercetoolsCustomFields.from_dict(obj["customFields"]) + if obj.get("customFields") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_update_docker.py b/algoliasearch/ingestion/models/source_update_docker.py index a194992fe..d2aa19af1 100644 --- a/algoliasearch/ingestion/models/source_update_docker.py +++ b/algoliasearch/ingestion/models/source_update_docker.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,45 +26,39 @@ class SourceUpdateDocker(BaseModel): SourceUpdateDocker """ - registry: Optional[DockerRegistry] = None - image: Optional[StrictStr] = Field(default=None, description="Docker image name.") - version: Optional[StrictStr] = Field( - default="latest", description="Docker image version." - ) - configuration: Dict[str, Any] = Field(description="Configuration of the spec.") + registry: Optional[DockerRegistry] = Field(default=None, alias="registry") + image: Optional[str] = Field(default=None, alias="image") + """ Docker image name. """ + version: Optional[str] = Field(default=None, alias="version") + """ Docker image version. """ + configuration: object = Field(alias="configuration") + """ Configuration of the spec. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceUpdateDocker from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceUpdateDocker from a dict""" if obj is None: return None @@ -72,12 +66,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "registry": obj.get("registry"), - "image": obj.get("image"), - "version": obj.get("version"), - "configuration": obj.get("configuration"), - } - ) - return _obj + obj["registry"] = obj.get("registry") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_update_input.py b/algoliasearch/ingestion/models/source_update_input.py index 3268b3713..879f6c6d4 100644 --- a/algoliasearch/ingestion/models/source_update_input.py +++ b/algoliasearch/ingestion/models/source_update_input.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -36,13 +36,20 @@ class SourceUpdateInput(BaseModel): SourceUpdateInput """ - oneof_schema_1_validator: Optional[SourceUpdateCommercetools] = None - oneof_schema_2_validator: Optional[SourceJSON] = None - oneof_schema_3_validator: Optional[SourceCSV] = None - oneof_schema_4_validator: Optional[SourceBigQuery] = None - oneof_schema_5_validator: Optional[SourceGA4BigQueryExport] = None - oneof_schema_6_validator: Optional[SourceUpdateDocker] = None - oneof_schema_7_validator: Optional[SourceUpdateShopify] = None + oneof_schema_1_validator: Optional[SourceUpdateCommercetools] = Field(default=None) + + oneof_schema_2_validator: Optional[SourceJSON] = Field(default=None) + + oneof_schema_3_validator: Optional[SourceCSV] = Field(default=None) + + oneof_schema_4_validator: Optional[SourceBigQuery] = Field(default=None) + + oneof_schema_5_validator: Optional[SourceGA4BigQueryExport] = Field(default=None) + + oneof_schema_6_validator: Optional[SourceUpdateDocker] = Field(default=None) + + oneof_schema_7_validator: Optional[SourceUpdateShopify] = Field(default=None) + actual_instance: Optional[ Union[ SourceBigQuery, @@ -54,6 +61,15 @@ class SourceUpdateInput(BaseModel): SourceUpdateShopify, ] ] = None + one_of_schemas: Set[str] = { + "SourceBigQuery", + "SourceCSV", + "SourceGA4BigQueryExport", + "SourceJSON", + "SourceUpdateCommercetools", + "SourceUpdateDocker", + "SourceUpdateShopify", + } def __init__(self, *args, **kwargs) -> None: if args: @@ -89,7 +105,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of SourceUpdateInput from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -151,17 +168,34 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[ + Union[ + Dict[str, Any], + SourceBigQuery, + SourceCSV, + SourceGA4BigQueryExport, + SourceJSON, + SourceUpdateCommercetools, + SourceUpdateDocker, + SourceUpdateShopify, + ] + ]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/ingestion/models/source_update_response.py b/algoliasearch/ingestion/models/source_update_response.py index 3766a29a3..ddc8434a3 100644 --- a/algoliasearch/ingestion/models/source_update_response.py +++ b/algoliasearch/ingestion/models/source_update_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,47 +23,38 @@ class SourceUpdateResponse(BaseModel): SourceUpdateResponse """ - source_id: StrictStr = Field( - description="Universally uniqud identifier (UUID) of a source.", - alias="sourceID", - ) - name: StrictStr = Field(description="Descriptive name of the source.") - updated_at: StrictStr = Field( - description="Date of last update in RFC 3339 format.", alias="updatedAt" - ) + source_id: str = Field(alias="sourceID") + """ Universally uniqud identifier (UUID) of a source. """ + name: str = Field(alias="name") + """ Descriptive name of the source. """ + updated_at: str = Field(alias="updatedAt") + """ Date of last update in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceUpdateResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceUpdateResponse from a dict""" if obj is None: return None @@ -71,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "sourceID": obj.get("sourceID"), - "name": obj.get("name"), - "updatedAt": obj.get("updatedAt"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_update_shopify.py b/algoliasearch/ingestion/models/source_update_shopify.py index 52b0377c8..e23bd89ef 100644 --- a/algoliasearch/ingestion/models/source_update_shopify.py +++ b/algoliasearch/ingestion/models/source_update_shopify.py @@ -23,44 +23,36 @@ class SourceUpdateShopify(BaseModel): SourceUpdateShopify """ - feature_flags: Optional[Dict[str, Any]] = Field( - default=None, - description="Feature flags for the Shopify source.", - alias="featureFlags", + feature_flags: Optional[Dict[str, object]] = Field( + default=None, alias="featureFlags" ) + """ Feature flags for the Shopify source. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceUpdateShopify from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceUpdateShopify from a dict""" if obj is None: return None @@ -68,5 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"featureFlags": obj.get("featureFlags")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/source_watch_response.py b/algoliasearch/ingestion/models/source_watch_response.py index 5c8342bc6..4bcfbec07 100644 --- a/algoliasearch/ingestion/models/source_watch_response.py +++ b/algoliasearch/ingestion/models/source_watch_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,61 +26,40 @@ class SourceWatchResponse(BaseModel): SourceWatchResponse """ - run_id: Optional[StrictStr] = Field( - default=None, - description="Universally unique identifier (UUID) of a task run.", - alias="runID", - ) - data: Optional[List[Dict[str, Any]]] = Field( - default=None, - description="depending on the source type, the validation returns sampling data of your source (JSON, CSV, BigQuery).", - ) - events: Optional[List[Event]] = Field( - default=None, - description="in case of error, observability events will be added to the response, if any.", - ) - message: StrictStr = Field( - description="a message describing the outcome of a validate run." - ) + run_id: Optional[str] = Field(default=None, alias="runID") + """ Universally unique identifier (UUID) of a task run. """ + data: Optional[List[object]] = Field(default=None, alias="data") + """ depending on the source type, the validation returns sampling data of your source (JSON, CSV, BigQuery). """ + events: Optional[List[Event]] = Field(default=None, alias="events") + """ in case of error, observability events will be added to the response, if any. """ + message: str = Field(alias="message") + """ a message describing the outcome of a validate run. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceWatchResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.events: - for _item in self.events: - if _item: - _items.append(_item.to_dict()) - _dict["events"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceWatchResponse from a dict""" if obj is None: return None @@ -88,16 +67,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "runID": obj.get("runID"), - "data": obj.get("data"), - "events": ( - [Event.from_dict(_item) for _item in obj.get("events")] - if obj.get("events") is not None - else None - ), - "message": obj.get("message"), - } + obj["events"] = ( + [Event.from_dict(_item) for _item in obj["events"]] + if obj.get("events") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/streaming_input.py b/algoliasearch/ingestion/models/streaming_input.py index f8a10c11f..c2cf9a682 100644 --- a/algoliasearch/ingestion/models/streaming_input.py +++ b/algoliasearch/ingestion/models/streaming_input.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,42 +26,33 @@ class StreamingInput(BaseModel): Input for a `streaming` task whose source is of type `ga4BigqueryExport` and for which extracted data is continuously streamed. """ - mapping: MappingInput + mapping: MappingInput = Field(alias="mapping") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of StreamingInput from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.mapping: - _dict["mapping"] = self.mapping.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of StreamingInput from a dict""" if obj is None: return None @@ -69,13 +60,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "mapping": ( - MappingInput.from_dict(obj.get("mapping")) - if obj.get("mapping") is not None - else None - ) - } + obj["mapping"] = ( + MappingInput.from_dict(obj["mapping"]) + if obj.get("mapping") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/streaming_trigger.py b/algoliasearch/ingestion/models/streaming_trigger.py index a71e8a8b2..8e133d83e 100644 --- a/algoliasearch/ingestion/models/streaming_trigger.py +++ b/algoliasearch/ingestion/models/streaming_trigger.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,40 +26,33 @@ class StreamingTrigger(BaseModel): Trigger input for continuously running tasks. """ - type: StreamingTriggerType + type: StreamingTriggerType = Field(alias="type") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of StreamingTrigger from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of StreamingTrigger from a dict""" if obj is None: return None @@ -67,5 +60,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"type": obj.get("type")}) - return _obj + obj["type"] = obj.get("type") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/subscription_trigger.py b/algoliasearch/ingestion/models/subscription_trigger.py index 9f4ddeb03..210a743d9 100644 --- a/algoliasearch/ingestion/models/subscription_trigger.py +++ b/algoliasearch/ingestion/models/subscription_trigger.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,40 +28,33 @@ class SubscriptionTrigger(BaseModel): Trigger input for subscription tasks. """ - type: SubscriptionTriggerType + type: SubscriptionTriggerType = Field(alias="type") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SubscriptionTrigger from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SubscriptionTrigger from a dict""" if obj is None: return None @@ -69,5 +62,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"type": obj.get("type")}) - return _obj + obj["type"] = obj.get("type") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/task.py b/algoliasearch/ingestion/models/task.py index 1e15734d2..c0efdfcd3 100644 --- a/algoliasearch/ingestion/models/task.py +++ b/algoliasearch/ingestion/models/task.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.ingestion.models.action_type import ActionType @@ -27,86 +27,56 @@ class Task(BaseModel): Task """ - task_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a task.", alias="taskID" - ) - source_id: StrictStr = Field( - description="Universally uniqud identifier (UUID) of a source.", - alias="sourceID", - ) - destination_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a destination resource.", - alias="destinationID", - ) - cron: Optional[StrictStr] = Field( - default=None, description="Cron expression for the task's schedule." - ) - last_run: Optional[StrictStr] = Field( - default=None, - description="The last time the scheduled task ran in RFC 3339 format.", - alias="lastRun", - ) - next_run: Optional[StrictStr] = Field( - default=None, - description="The next scheduled run of the task in RFC 3339 format.", - alias="nextRun", - ) - input: Optional[TaskInput] = None - enabled: StrictBool = Field(description="Whether the task is enabled.") - failure_threshold: Optional[Annotated[int, Field(le=100, strict=True, ge=0)]] = ( - Field( - default=None, - description="Maximum accepted percentage of failures for a task run to finish successfully.", - alias="failureThreshold", - ) - ) - action: ActionType - cursor: Optional[StrictStr] = Field( - default=None, description="Date of the last cursor in RFC 3339 format." - ) - created_at: StrictStr = Field( - description="Date of creation in RFC 3339 format.", alias="createdAt" - ) - updated_at: Optional[StrictStr] = Field( - default=None, - description="Date of last update in RFC 3339 format.", - alias="updatedAt", - ) + task_id: str = Field(alias="taskID") + """ Universally unique identifier (UUID) of a task. """ + source_id: str = Field(alias="sourceID") + """ Universally uniqud identifier (UUID) of a source. """ + destination_id: str = Field(alias="destinationID") + """ Universally unique identifier (UUID) of a destination resource. """ + cron: Optional[str] = Field(default=None, alias="cron") + """ Cron expression for the task's schedule. """ + last_run: Optional[str] = Field(default=None, alias="lastRun") + """ The last time the scheduled task ran in RFC 3339 format. """ + next_run: Optional[str] = Field(default=None, alias="nextRun") + """ The next scheduled run of the task in RFC 3339 format. """ + input: Optional[TaskInput] = Field(default=None, alias="input") + enabled: bool = Field(alias="enabled") + """ Whether the task is enabled. """ + failure_threshold: Optional[int] = Field(default=None, alias="failureThreshold") + """ Maximum accepted percentage of failures for a task run to finish successfully. """ + action: ActionType = Field(alias="action") + cursor: Optional[str] = Field(default=None, alias="cursor") + """ Date of the last cursor in RFC 3339 format. """ + created_at: str = Field(alias="createdAt") + """ Date of creation in RFC 3339 format. """ + updated_at: Optional[str] = Field(default=None, alias="updatedAt") + """ Date of last update in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Task from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.input: - _dict["input"] = self.input.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Task from a dict""" if obj is None: return None @@ -114,25 +84,9 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "taskID": obj.get("taskID"), - "sourceID": obj.get("sourceID"), - "destinationID": obj.get("destinationID"), - "cron": obj.get("cron"), - "lastRun": obj.get("lastRun"), - "nextRun": obj.get("nextRun"), - "input": ( - TaskInput.from_dict(obj.get("input")) - if obj.get("input") is not None - else None - ), - "enabled": obj.get("enabled"), - "failureThreshold": obj.get("failureThreshold"), - "action": obj.get("action"), - "cursor": obj.get("cursor"), - "createdAt": obj.get("createdAt"), - "updatedAt": obj.get("updatedAt"), - } + obj["input"] = ( + TaskInput.from_dict(obj["input"]) if obj.get("input") is not None else None ) - return _obj + obj["action"] = obj.get("action") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/task_create.py b/algoliasearch/ingestion/models/task_create.py index 83b4aa0af..3784cd903 100644 --- a/algoliasearch/ingestion/models/task_create.py +++ b/algoliasearch/ingestion/models/task_create.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.ingestion.models.action_type import ActionType @@ -27,67 +27,46 @@ class TaskCreate(BaseModel): API request body for creating a task. """ - source_id: StrictStr = Field( - description="Universally uniqud identifier (UUID) of a source.", - alias="sourceID", - ) - destination_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a destination resource.", - alias="destinationID", - ) - action: ActionType - cron: Optional[StrictStr] = Field( - default=None, description="Cron expression for the task's schedule." - ) - enabled: Optional[StrictBool] = Field( - default=None, description="Whether the task is enabled." - ) - failure_threshold: Optional[Annotated[int, Field(le=100, strict=True, ge=0)]] = ( - Field( - default=None, - description="Maximum accepted percentage of failures for a task run to finish successfully.", - alias="failureThreshold", - ) - ) - input: Optional[TaskInput] = None - cursor: Optional[StrictStr] = Field( - default=None, description="Date of the last cursor in RFC 3339 format." - ) + source_id: str = Field(alias="sourceID") + """ Universally uniqud identifier (UUID) of a source. """ + destination_id: str = Field(alias="destinationID") + """ Universally unique identifier (UUID) of a destination resource. """ + action: ActionType = Field(alias="action") + cron: Optional[str] = Field(default=None, alias="cron") + """ Cron expression for the task's schedule. """ + enabled: Optional[bool] = Field(default=None, alias="enabled") + """ Whether the task is enabled. """ + failure_threshold: Optional[int] = Field(default=None, alias="failureThreshold") + """ Maximum accepted percentage of failures for a task run to finish successfully. """ + input: Optional[TaskInput] = Field(default=None, alias="input") + cursor: Optional[str] = Field(default=None, alias="cursor") + """ Date of the last cursor in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TaskCreate from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.input: - _dict["input"] = self.input.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TaskCreate from a dict""" if obj is None: return None @@ -95,20 +74,9 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "sourceID": obj.get("sourceID"), - "destinationID": obj.get("destinationID"), - "action": obj.get("action"), - "cron": obj.get("cron"), - "enabled": obj.get("enabled"), - "failureThreshold": obj.get("failureThreshold"), - "input": ( - TaskInput.from_dict(obj.get("input")) - if obj.get("input") is not None - else None - ), - "cursor": obj.get("cursor"), - } + obj["action"] = obj.get("action") + obj["input"] = ( + TaskInput.from_dict(obj["input"]) if obj.get("input") is not None else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/task_create_response.py b/algoliasearch/ingestion/models/task_create_response.py index ed64967dc..01752beca 100644 --- a/algoliasearch/ingestion/models/task_create_response.py +++ b/algoliasearch/ingestion/models/task_create_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,45 +23,36 @@ class TaskCreateResponse(BaseModel): API response for creating a task. """ - task_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a task.", alias="taskID" - ) - created_at: StrictStr = Field( - description="Date of creation in RFC 3339 format.", alias="createdAt" - ) + task_id: str = Field(alias="taskID") + """ Universally unique identifier (UUID) of a task. """ + created_at: str = Field(alias="createdAt") + """ Date of creation in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TaskCreateResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TaskCreateResponse from a dict""" if obj is None: return None @@ -69,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"taskID": obj.get("taskID"), "createdAt": obj.get("createdAt")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/task_create_trigger.py b/algoliasearch/ingestion/models/task_create_trigger.py index 36a5f15f4..2104cd227 100644 --- a/algoliasearch/ingestion/models/task_create_trigger.py +++ b/algoliasearch/ingestion/models/task_create_trigger.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -29,10 +29,14 @@ class TaskCreateTrigger(BaseModel): TaskCreateTrigger """ - oneof_schema_1_validator: Optional[OnDemandTriggerInput] = None - oneof_schema_2_validator: Optional[ScheduleTriggerInput] = None - oneof_schema_3_validator: Optional[SubscriptionTrigger] = None - oneof_schema_4_validator: Optional[StreamingTrigger] = None + oneof_schema_1_validator: Optional[OnDemandTriggerInput] = Field(default=None) + + oneof_schema_2_validator: Optional[ScheduleTriggerInput] = Field(default=None) + + oneof_schema_3_validator: Optional[SubscriptionTrigger] = Field(default=None) + + oneof_schema_4_validator: Optional[StreamingTrigger] = Field(default=None) + actual_instance: Optional[ Union[ OnDemandTriggerInput, @@ -41,6 +45,12 @@ class TaskCreateTrigger(BaseModel): SubscriptionTrigger, ] ] = None + one_of_schemas: Set[str] = { + "OnDemandTriggerInput", + "ScheduleTriggerInput", + "StreamingTrigger", + "SubscriptionTrigger", + } def __init__(self, *args, **kwargs) -> None: if args: @@ -73,7 +83,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of TaskCreateTrigger from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -117,17 +128,31 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[ + Union[ + Dict[str, Any], + OnDemandTriggerInput, + ScheduleTriggerInput, + StreamingTrigger, + SubscriptionTrigger, + ] + ]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/ingestion/models/task_create_v1.py b/algoliasearch/ingestion/models/task_create_v1.py index 94a4c394d..d6dfed268 100644 --- a/algoliasearch/ingestion/models/task_create_v1.py +++ b/algoliasearch/ingestion/models/task_create_v1.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.ingestion.models.action_type import ActionType @@ -28,67 +28,45 @@ class TaskCreateV1(BaseModel): API request body for creating a task using the V1 shape, please use methods and types that don't contain the V1 suffix. """ - source_id: StrictStr = Field( - description="Universally uniqud identifier (UUID) of a source.", - alias="sourceID", - ) - destination_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a destination resource.", - alias="destinationID", - ) - trigger: TaskCreateTrigger - action: ActionType - enabled: Optional[StrictBool] = Field( - default=None, description="Whether the task is enabled." - ) - failure_threshold: Optional[Annotated[int, Field(le=100, strict=True, ge=0)]] = ( - Field( - default=None, - description="Maximum accepted percentage of failures for a task run to finish successfully.", - alias="failureThreshold", - ) - ) - input: Optional[TaskInput] = None - cursor: Optional[StrictStr] = Field( - default=None, description="Date of the last cursor in RFC 3339 format." - ) + source_id: str = Field(alias="sourceID") + """ Universally uniqud identifier (UUID) of a source. """ + destination_id: str = Field(alias="destinationID") + """ Universally unique identifier (UUID) of a destination resource. """ + trigger: TaskCreateTrigger = Field(alias="trigger") + action: ActionType = Field(alias="action") + enabled: Optional[bool] = Field(default=None, alias="enabled") + """ Whether the task is enabled. """ + failure_threshold: Optional[int] = Field(default=None, alias="failureThreshold") + """ Maximum accepted percentage of failures for a task run to finish successfully. """ + input: Optional[TaskInput] = Field(default=None, alias="input") + cursor: Optional[str] = Field(default=None, alias="cursor") + """ Date of the last cursor in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TaskCreateV1 from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.trigger: - _dict["trigger"] = self.trigger.to_dict() - if self.input: - _dict["input"] = self.input.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TaskCreateV1 from a dict""" if obj is None: return None @@ -96,24 +74,14 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "sourceID": obj.get("sourceID"), - "destinationID": obj.get("destinationID"), - "trigger": ( - TaskCreateTrigger.from_dict(obj.get("trigger")) - if obj.get("trigger") is not None - else None - ), - "action": obj.get("action"), - "enabled": obj.get("enabled"), - "failureThreshold": obj.get("failureThreshold"), - "input": ( - TaskInput.from_dict(obj.get("input")) - if obj.get("input") is not None - else None - ), - "cursor": obj.get("cursor"), - } + obj["trigger"] = ( + TaskCreateTrigger.from_dict(obj["trigger"]) + if obj.get("trigger") is not None + else None ) - return _obj + obj["action"] = obj.get("action") + obj["input"] = ( + TaskInput.from_dict(obj["input"]) if obj.get("input") is not None else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/task_input.py b/algoliasearch/ingestion/models/task_input.py index b27d57f4d..3f0b39aff 100644 --- a/algoliasearch/ingestion/models/task_input.py +++ b/algoliasearch/ingestion/models/task_input.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -28,12 +28,16 @@ class TaskInput(BaseModel): Configuration of the task, depending on its type. """ - oneof_schema_1_validator: Optional[StreamingInput] = None - oneof_schema_2_validator: Optional[DockerStreamsInput] = None - oneof_schema_3_validator: Optional[ShopifyInput] = None + oneof_schema_1_validator: Optional[StreamingInput] = Field(default=None) + + oneof_schema_2_validator: Optional[DockerStreamsInput] = Field(default=None) + + oneof_schema_3_validator: Optional[ShopifyInput] = Field(default=None) + actual_instance: Optional[ Union[DockerStreamsInput, ShopifyInput, StreamingInput] ] = None + one_of_schemas: Set[str] = {"DockerStreamsInput", "ShopifyInput", "StreamingInput"} def __init__(self, *args, **kwargs) -> None: if args: @@ -59,7 +63,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of TaskInput from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -97,17 +102,25 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[ + Union[Dict[str, Any], DockerStreamsInput, ShopifyInput, StreamingInput] + ]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/ingestion/models/task_search.py b/algoliasearch/ingestion/models/task_search.py index c0ee53d46..9eca11dc6 100644 --- a/algoliasearch/ingestion/models/task_search.py +++ b/algoliasearch/ingestion/models/task_search.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,40 +23,33 @@ class TaskSearch(BaseModel): TaskSearch """ - task_ids: List[StrictStr] = Field(alias="taskIDs") + task_ids: List[str] = Field(alias="taskIDs") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TaskSearch from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TaskSearch from a dict""" if obj is None: return None @@ -64,5 +57,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"taskIDs": obj.get("taskIDs")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/task_sort_keys.py b/algoliasearch/ingestion/models/task_sort_keys.py index 8b04c0934..f40eef566 100644 --- a/algoliasearch/ingestion/models/task_sort_keys.py +++ b/algoliasearch/ingestion/models/task_sort_keys.py @@ -25,9 +25,13 @@ class TaskSortKeys(str, Enum): allowed enum values """ ENABLED = "enabled" + TRIGGERTYPE = "triggerType" + ACTION = "action" + UPDATEDAT = "updatedAt" + CREATEDAT = "createdAt" @classmethod diff --git a/algoliasearch/ingestion/models/task_update.py b/algoliasearch/ingestion/models/task_update.py index 744ee2a6d..91f219ce2 100644 --- a/algoliasearch/ingestion/models/task_update.py +++ b/algoliasearch/ingestion/models/task_update.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.ingestion.models.task_input import TaskInput @@ -26,60 +26,41 @@ class TaskUpdate(BaseModel): API request body for updating a task. """ - destination_id: Optional[StrictStr] = Field( - default=None, - description="Universally unique identifier (UUID) of a destination resource.", - alias="destinationID", - ) - cron: Optional[StrictStr] = Field( - default=None, description="Cron expression for the task's schedule." - ) - input: Optional[TaskInput] = None - enabled: Optional[StrictBool] = Field( - default=None, description="Whether the task is enabled." - ) - failure_threshold: Optional[Annotated[int, Field(le=100, strict=True, ge=0)]] = ( - Field( - default=None, - description="Maximum accepted percentage of failures for a task run to finish successfully.", - alias="failureThreshold", - ) - ) + destination_id: Optional[str] = Field(default=None, alias="destinationID") + """ Universally unique identifier (UUID) of a destination resource. """ + cron: Optional[str] = Field(default=None, alias="cron") + """ Cron expression for the task's schedule. """ + input: Optional[TaskInput] = Field(default=None, alias="input") + enabled: Optional[bool] = Field(default=None, alias="enabled") + """ Whether the task is enabled. """ + failure_threshold: Optional[int] = Field(default=None, alias="failureThreshold") + """ Maximum accepted percentage of failures for a task run to finish successfully. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TaskUpdate from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.input: - _dict["input"] = self.input.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TaskUpdate from a dict""" if obj is None: return None @@ -87,17 +68,8 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "destinationID": obj.get("destinationID"), - "cron": obj.get("cron"), - "input": ( - TaskInput.from_dict(obj.get("input")) - if obj.get("input") is not None - else None - ), - "enabled": obj.get("enabled"), - "failureThreshold": obj.get("failureThreshold"), - } + obj["input"] = ( + TaskInput.from_dict(obj["input"]) if obj.get("input") is not None else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/task_update_response.py b/algoliasearch/ingestion/models/task_update_response.py index 0b351918b..c3f32e70f 100644 --- a/algoliasearch/ingestion/models/task_update_response.py +++ b/algoliasearch/ingestion/models/task_update_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,45 +23,36 @@ class TaskUpdateResponse(BaseModel): API response for updating a task. """ - task_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a task.", alias="taskID" - ) - updated_at: StrictStr = Field( - description="Date of last update in RFC 3339 format.", alias="updatedAt" - ) + task_id: str = Field(alias="taskID") + """ Universally unique identifier (UUID) of a task. """ + updated_at: str = Field(alias="updatedAt") + """ Date of last update in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TaskUpdateResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TaskUpdateResponse from a dict""" if obj is None: return None @@ -69,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"taskID": obj.get("taskID"), "updatedAt": obj.get("updatedAt")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/task_update_v1.py b/algoliasearch/ingestion/models/task_update_v1.py index c7bd3b1ef..791d0788f 100644 --- a/algoliasearch/ingestion/models/task_update_v1.py +++ b/algoliasearch/ingestion/models/task_update_v1.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.ingestion.models.task_input import TaskInput @@ -27,60 +27,40 @@ class TaskUpdateV1(BaseModel): API request body for updating a task using the V1 shape, please use methods and types that don't contain the V1 suffix. """ - destination_id: Optional[StrictStr] = Field( - default=None, - description="Universally unique identifier (UUID) of a destination resource.", - alias="destinationID", - ) - trigger: Optional[TriggerUpdateInput] = None - input: Optional[TaskInput] = None - enabled: Optional[StrictBool] = Field( - default=None, description="Whether the task is enabled." - ) - failure_threshold: Optional[Annotated[int, Field(le=100, strict=True, ge=0)]] = ( - Field( - default=None, - description="Maximum accepted percentage of failures for a task run to finish successfully.", - alias="failureThreshold", - ) - ) + destination_id: Optional[str] = Field(default=None, alias="destinationID") + """ Universally unique identifier (UUID) of a destination resource. """ + trigger: Optional[TriggerUpdateInput] = Field(default=None, alias="trigger") + input: Optional[TaskInput] = Field(default=None, alias="input") + enabled: Optional[bool] = Field(default=None, alias="enabled") + """ Whether the task is enabled. """ + failure_threshold: Optional[int] = Field(default=None, alias="failureThreshold") + """ Maximum accepted percentage of failures for a task run to finish successfully. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TaskUpdateV1 from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.trigger: - _dict["trigger"] = self.trigger.to_dict() - if self.input: - _dict["input"] = self.input.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TaskUpdateV1 from a dict""" if obj is None: return None @@ -88,21 +68,13 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "destinationID": obj.get("destinationID"), - "trigger": ( - TriggerUpdateInput.from_dict(obj.get("trigger")) - if obj.get("trigger") is not None - else None - ), - "input": ( - TaskInput.from_dict(obj.get("input")) - if obj.get("input") is not None - else None - ), - "enabled": obj.get("enabled"), - "failureThreshold": obj.get("failureThreshold"), - } + obj["trigger"] = ( + TriggerUpdateInput.from_dict(obj["trigger"]) + if obj.get("trigger") is not None + else None ) - return _obj + obj["input"] = ( + TaskInput.from_dict(obj["input"]) if obj.get("input") is not None else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/task_v1.py b/algoliasearch/ingestion/models/task_v1.py index 3ec6c5ea2..a0fa899a4 100644 --- a/algoliasearch/ingestion/models/task_v1.py +++ b/algoliasearch/ingestion/models/task_v1.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.ingestion.models.action_type import ActionType @@ -28,76 +28,51 @@ class TaskV1(BaseModel): The V1 task object, please use methods and types that don't contain the V1 suffix. """ - task_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a task.", alias="taskID" - ) - source_id: StrictStr = Field( - description="Universally uniqud identifier (UUID) of a source.", - alias="sourceID", - ) - destination_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a destination resource.", - alias="destinationID", - ) - trigger: Trigger - input: Optional[TaskInput] = None - enabled: StrictBool = Field(description="Whether the task is enabled.") - failure_threshold: Optional[Annotated[int, Field(le=100, strict=True, ge=0)]] = ( - Field( - default=None, - description="Maximum accepted percentage of failures for a task run to finish successfully.", - alias="failureThreshold", - ) - ) - action: ActionType - cursor: Optional[StrictStr] = Field( - default=None, description="Date of the last cursor in RFC 3339 format." - ) - created_at: StrictStr = Field( - description="Date of creation in RFC 3339 format.", alias="createdAt" - ) - updated_at: Optional[StrictStr] = Field( - default=None, - description="Date of last update in RFC 3339 format.", - alias="updatedAt", - ) + task_id: str = Field(alias="taskID") + """ Universally unique identifier (UUID) of a task. """ + source_id: str = Field(alias="sourceID") + """ Universally uniqud identifier (UUID) of a source. """ + destination_id: str = Field(alias="destinationID") + """ Universally unique identifier (UUID) of a destination resource. """ + trigger: Trigger = Field(alias="trigger") + input: Optional[TaskInput] = Field(default=None, alias="input") + enabled: bool = Field(alias="enabled") + """ Whether the task is enabled. """ + failure_threshold: Optional[int] = Field(default=None, alias="failureThreshold") + """ Maximum accepted percentage of failures for a task run to finish successfully. """ + action: ActionType = Field(alias="action") + cursor: Optional[str] = Field(default=None, alias="cursor") + """ Date of the last cursor in RFC 3339 format. """ + created_at: str = Field(alias="createdAt") + """ Date of creation in RFC 3339 format. """ + updated_at: Optional[str] = Field(default=None, alias="updatedAt") + """ Date of last update in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TaskV1 from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.trigger: - _dict["trigger"] = self.trigger.to_dict() - if self.input: - _dict["input"] = self.input.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TaskV1 from a dict""" if obj is None: return None @@ -105,27 +80,14 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "taskID": obj.get("taskID"), - "sourceID": obj.get("sourceID"), - "destinationID": obj.get("destinationID"), - "trigger": ( - Trigger.from_dict(obj.get("trigger")) - if obj.get("trigger") is not None - else None - ), - "input": ( - TaskInput.from_dict(obj.get("input")) - if obj.get("input") is not None - else None - ), - "enabled": obj.get("enabled"), - "failureThreshold": obj.get("failureThreshold"), - "action": obj.get("action"), - "cursor": obj.get("cursor"), - "createdAt": obj.get("createdAt"), - "updatedAt": obj.get("updatedAt"), - } + obj["trigger"] = ( + Trigger.from_dict(obj["trigger"]) + if obj.get("trigger") is not None + else None + ) + obj["input"] = ( + TaskInput.from_dict(obj["input"]) if obj.get("input") is not None else None ) - return _obj + obj["action"] = obj.get("action") + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/transformation.py b/algoliasearch/ingestion/models/transformation.py index d48cf8a40..27ad236ec 100644 --- a/algoliasearch/ingestion/models/transformation.py +++ b/algoliasearch/ingestion/models/transformation.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,64 +23,48 @@ class Transformation(BaseModel): Transformation """ - transformation_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a transformation.", - alias="transformationID", - ) - authentication_ids: Optional[List[StrictStr]] = Field( - default=None, - description="The authentications associated for the current transformation.", - alias="authenticationIDs", - ) - code: StrictStr = Field(description="The source code of the transformation.") - name: StrictStr = Field( - description="The uniquely identified name of your transformation." - ) - description: Optional[StrictStr] = Field( - default=None, - description="A descriptive name for your transformation of what it does.", - ) - created_at: StrictStr = Field( - description="Date of creation in RFC 3339 format.", alias="createdAt" - ) - updated_at: Optional[StrictStr] = Field( - default=None, - description="Date of last update in RFC 3339 format.", - alias="updatedAt", + transformation_id: str = Field(alias="transformationID") + """ Universally unique identifier (UUID) of a transformation. """ + authentication_ids: Optional[List[str]] = Field( + default=None, alias="authenticationIDs" ) + """ The authentications associated for the current transformation. """ + code: str = Field(alias="code") + """ The source code of the transformation. """ + name: str = Field(alias="name") + """ The uniquely identified name of your transformation. """ + description: Optional[str] = Field(default=None, alias="description") + """ A descriptive name for your transformation of what it does. """ + created_at: str = Field(alias="createdAt") + """ Date of creation in RFC 3339 format. """ + updated_at: Optional[str] = Field(default=None, alias="updatedAt") + """ Date of last update in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Transformation from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Transformation from a dict""" if obj is None: return None @@ -88,15 +72,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "transformationID": obj.get("transformationID"), - "authenticationIDs": obj.get("authenticationIDs"), - "code": obj.get("code"), - "name": obj.get("name"), - "description": obj.get("description"), - "createdAt": obj.get("createdAt"), - "updatedAt": obj.get("updatedAt"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/transformation_create.py b/algoliasearch/ingestion/models/transformation_create.py index 42c1be353..0fe05e679 100644 --- a/algoliasearch/ingestion/models/transformation_create.py +++ b/algoliasearch/ingestion/models/transformation_create.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,52 +23,42 @@ class TransformationCreate(BaseModel): API request body for creating a transformation. """ - code: StrictStr = Field(description="The source code of the transformation.") - name: StrictStr = Field( - description="The uniquely identified name of your transformation." - ) - description: Optional[StrictStr] = Field( - default=None, - description="A descriptive name for your transformation of what it does.", - ) - authentication_ids: Optional[List[StrictStr]] = Field( - default=None, - description="The authentications associated for the current transformation.", - alias="authenticationIDs", + code: str = Field(alias="code") + """ The source code of the transformation. """ + name: str = Field(alias="name") + """ The uniquely identified name of your transformation. """ + description: Optional[str] = Field(default=None, alias="description") + """ A descriptive name for your transformation of what it does. """ + authentication_ids: Optional[List[str]] = Field( + default=None, alias="authenticationIDs" ) + """ The authentications associated for the current transformation. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TransformationCreate from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TransformationCreate from a dict""" if obj is None: return None @@ -76,12 +66,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "code": obj.get("code"), - "name": obj.get("name"), - "description": obj.get("description"), - "authenticationIDs": obj.get("authenticationIDs"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/transformation_create_response.py b/algoliasearch/ingestion/models/transformation_create_response.py index 973d14228..8fa2fc633 100644 --- a/algoliasearch/ingestion/models/transformation_create_response.py +++ b/algoliasearch/ingestion/models/transformation_create_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,46 +23,36 @@ class TransformationCreateResponse(BaseModel): API response for creating a transformation. """ - transformation_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a transformation.", - alias="transformationID", - ) - created_at: StrictStr = Field( - description="Date of creation in RFC 3339 format.", alias="createdAt" - ) + transformation_id: str = Field(alias="transformationID") + """ Universally unique identifier (UUID) of a transformation. """ + created_at: str = Field(alias="createdAt") + """ Date of creation in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TransformationCreateResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TransformationCreateResponse from a dict""" if obj is None: return None @@ -70,10 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "transformationID": obj.get("transformationID"), - "createdAt": obj.get("createdAt"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/transformation_error.py b/algoliasearch/ingestion/models/transformation_error.py index 9f51acc65..bf54942a0 100644 --- a/algoliasearch/ingestion/models/transformation_error.py +++ b/algoliasearch/ingestion/models/transformation_error.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,45 +23,36 @@ class TransformationError(BaseModel): The error if the transformation failed. """ - code: Optional[StrictInt] = Field( - default=None, description="The error status code." - ) - message: Optional[StrictStr] = Field( - default=None, description="A descriptive message explaining the failure." - ) + code: Optional[int] = Field(default=None, alias="code") + """ The error status code. """ + message: Optional[str] = Field(default=None, alias="message") + """ A descriptive message explaining the failure. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TransformationError from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TransformationError from a dict""" if obj is None: return None @@ -69,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"code": obj.get("code"), "message": obj.get("message")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/transformation_search.py b/algoliasearch/ingestion/models/transformation_search.py index 59289ac5f..d9b98c921 100644 --- a/algoliasearch/ingestion/models/transformation_search.py +++ b/algoliasearch/ingestion/models/transformation_search.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,40 +23,33 @@ class TransformationSearch(BaseModel): TransformationSearch """ - transformation_ids: List[StrictStr] = Field(alias="transformationIDs") + transformation_ids: List[str] = Field(alias="transformationIDs") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TransformationSearch from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TransformationSearch from a dict""" if obj is None: return None @@ -64,5 +57,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"transformationIDs": obj.get("transformationIDs")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/transformation_try.py b/algoliasearch/ingestion/models/transformation_try.py index 031ed4e08..b616077d3 100644 --- a/algoliasearch/ingestion/models/transformation_try.py +++ b/algoliasearch/ingestion/models/transformation_try.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,50 +26,39 @@ class TransformationTry(BaseModel): TransformationTry """ - code: StrictStr = Field(description="The source code of the transformation.") - sample_record: Dict[str, Any] = Field( - description="The record to apply the given code to.", alias="sampleRecord" + code: str = Field(alias="code") + """ The source code of the transformation. """ + sample_record: object = Field(alias="sampleRecord") + """ The record to apply the given code to. """ + authentications: Optional[List[AuthenticationCreate]] = Field( + default=None, alias="authentications" ) - authentications: Optional[List[AuthenticationCreate]] = None model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TransformationTry from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.authentications: - for _item in self.authentications: - if _item: - _items.append(_item.to_dict()) - _dict["authentications"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TransformationTry from a dict""" if obj is None: return None @@ -77,18 +66,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "code": obj.get("code"), - "sampleRecord": obj.get("sampleRecord"), - "authentications": ( - [ - AuthenticationCreate.from_dict(_item) - for _item in obj.get("authentications") - ] - if obj.get("authentications") is not None - else None - ), - } + obj["authentications"] = ( + [AuthenticationCreate.from_dict(_item) for _item in obj["authentications"]] + if obj.get("authentications") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/transformation_try_response.py b/algoliasearch/ingestion/models/transformation_try_response.py index 7b83571e7..8c32bfaea 100644 --- a/algoliasearch/ingestion/models/transformation_try_response.py +++ b/algoliasearch/ingestion/models/transformation_try_response.py @@ -26,45 +26,35 @@ class TransformationTryResponse(BaseModel): TransformationTryResponse """ - payloads: List[Dict[str, Any]] = Field( - description="The array of records returned by the transformation service." - ) - error: Optional[TransformationError] = None + payloads: List[object] = Field(alias="payloads") + """ The array of records returned by the transformation service. """ + error: Optional[TransformationError] = Field(default=None, alias="error") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TransformationTryResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.error: - _dict["error"] = self.error.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TransformationTryResponse from a dict""" if obj is None: return None @@ -72,14 +62,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "payloads": obj.get("payloads"), - "error": ( - TransformationError.from_dict(obj.get("error")) - if obj.get("error") is not None - else None - ), - } + obj["error"] = ( + TransformationError.from_dict(obj["error"]) + if obj.get("error") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/transformation_update_response.py b/algoliasearch/ingestion/models/transformation_update_response.py index b78eec565..7820ef432 100644 --- a/algoliasearch/ingestion/models/transformation_update_response.py +++ b/algoliasearch/ingestion/models/transformation_update_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,46 +23,36 @@ class TransformationUpdateResponse(BaseModel): API response for updating a transformation. """ - transformation_id: StrictStr = Field( - description="Universally unique identifier (UUID) of a transformation.", - alias="transformationID", - ) - updated_at: StrictStr = Field( - description="Date of last update in RFC 3339 format.", alias="updatedAt" - ) + transformation_id: str = Field(alias="transformationID") + """ Universally unique identifier (UUID) of a transformation. """ + updated_at: str = Field(alias="updatedAt") + """ Date of last update in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TransformationUpdateResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TransformationUpdateResponse from a dict""" if obj is None: return None @@ -70,10 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "transformationID": obj.get("transformationID"), - "updatedAt": obj.get("updatedAt"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/trigger.py b/algoliasearch/ingestion/models/trigger.py index ed35becfb..1875833eb 100644 --- a/algoliasearch/ingestion/models/trigger.py +++ b/algoliasearch/ingestion/models/trigger.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -29,13 +29,23 @@ class Trigger(BaseModel): Trigger that runs the task. """ - oneof_schema_1_validator: Optional[OnDemandTrigger] = None - oneof_schema_2_validator: Optional[ScheduleTrigger] = None - oneof_schema_3_validator: Optional[SubscriptionTrigger] = None - oneof_schema_4_validator: Optional[StreamingTrigger] = None + oneof_schema_1_validator: Optional[OnDemandTrigger] = Field(default=None) + + oneof_schema_2_validator: Optional[ScheduleTrigger] = Field(default=None) + + oneof_schema_3_validator: Optional[SubscriptionTrigger] = Field(default=None) + + oneof_schema_4_validator: Optional[StreamingTrigger] = Field(default=None) + actual_instance: Optional[ Union[OnDemandTrigger, ScheduleTrigger, StreamingTrigger, SubscriptionTrigger] ] = None + one_of_schemas: Set[str] = { + "OnDemandTrigger", + "ScheduleTrigger", + "StreamingTrigger", + "SubscriptionTrigger", + } def __init__(self, *args, **kwargs) -> None: if args: @@ -63,7 +73,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of Trigger from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -107,17 +118,31 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[ + Union[ + Dict[str, Any], + OnDemandTrigger, + ScheduleTrigger, + StreamingTrigger, + SubscriptionTrigger, + ] + ]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/ingestion/models/trigger_type.py b/algoliasearch/ingestion/models/trigger_type.py index 7d25a4d0e..6de9cc9dd 100644 --- a/algoliasearch/ingestion/models/trigger_type.py +++ b/algoliasearch/ingestion/models/trigger_type.py @@ -25,8 +25,11 @@ class TriggerType(str, Enum): allowed enum values """ ONDEMAND = "onDemand" + SCHEDULE = "schedule" + SUBSCRIPTION = "subscription" + STREAMING = "streaming" @classmethod diff --git a/algoliasearch/ingestion/models/trigger_update_input.py b/algoliasearch/ingestion/models/trigger_update_input.py index 4cdf52c17..198284555 100644 --- a/algoliasearch/ingestion/models/trigger_update_input.py +++ b/algoliasearch/ingestion/models/trigger_update_input.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,40 +23,34 @@ class TriggerUpdateInput(BaseModel): Trigger for a task update. """ - cron: StrictStr = Field(description="Cron expression for the task's schedule.") + cron: str = Field(alias="cron") + """ Cron expression for the task's schedule. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TriggerUpdateInput from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TriggerUpdateInput from a dict""" if obj is None: return None @@ -64,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"cron": obj.get("cron")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/ingestion/models/window.py b/algoliasearch/ingestion/models/window.py index cf6b131b9..619adf2e5 100644 --- a/algoliasearch/ingestion/models/window.py +++ b/algoliasearch/ingestion/models/window.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,47 +23,36 @@ class Window(BaseModel): Time window by which to filter the observability data. """ - start_date: StrictStr = Field( - description="Date in RFC 3339 format representing the oldest data in the time window.", - alias="startDate", - ) - end_date: StrictStr = Field( - description="Date in RFC 3339 format representing the newest data in the time window.", - alias="endDate", - ) + start_date: str = Field(alias="startDate") + """ Date in RFC 3339 format representing the oldest data in the time window. """ + end_date: str = Field(alias="endDate") + """ Date in RFC 3339 format representing the newest data in the time window. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Window from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Window from a dict""" if obj is None: return None @@ -71,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"startDate": obj.get("startDate"), "endDate": obj.get("endDate")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/insights/client.py b/algoliasearch/insights/client.py index 8aeb9e9a7..e8490d49f 100644 --- a/algoliasearch/insights/client.py +++ b/algoliasearch/insights/client.py @@ -12,11 +12,12 @@ from urllib.parse import quote from pydantic import Field, StrictStr +from typing_extensions import Annotated if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.http.api_response import ApiResponse from algoliasearch.http.request_options import RequestOptions diff --git a/algoliasearch/insights/models/added_to_cart_object_ids.py b/algoliasearch/insights/models/added_to_cart_object_ids.py index aa2e2d018..e71064f8a 100644 --- a/algoliasearch/insights/models/added_to_cart_object_ids.py +++ b/algoliasearch/insights/models/added_to_cart_object_ids.py @@ -11,12 +11,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.insights.models.add_to_cart_event import AddToCartEvent @@ -30,48 +30,27 @@ class AddedToCartObjectIDs(BaseModel): Use this event to track when users add items to their shopping cart unrelated to a previous Algolia request. For example, if you don't use Algolia to build your category pages, use this event. To track add-to-cart events related to Algolia requests, use the \"Added to cart object IDs after search\" event. """ - event_name: Annotated[str, Field(min_length=1, strict=True, max_length=64)] = Field( - description="Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. ", - alias="eventName", - ) + event_name: str = Field(alias="eventName") + """ Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. """ event_type: ConversionEvent = Field(alias="eventType") event_subtype: AddToCartEvent = Field(alias="eventSubtype") - index: StrictStr = Field( - description="Index name (case-sensitive) to which the event's items belong." - ) - object_ids: Annotated[List[StrictStr], Field(min_length=1, max_length=20)] = Field( - description="Object IDs of the records that are part of the event.", - alias="objectIDs", - ) - user_token: Annotated[str, Field(min_length=1, strict=True, max_length=129)] = ( - Field( - description="Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - ) - authenticated_user_token: Optional[ - Annotated[str, Field(min_length=1, strict=True, max_length=129)] - ] = Field( - default=None, - description="Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="authenticatedUserToken", - ) - currency: Optional[StrictStr] = Field( - default=None, - description="Three-letter [currency code](https://www.iso.org/iso-4217-currency-codes.html).", + index: str = Field(alias="index") + """ Index name (case-sensitive) to which the event's items belong. """ + object_ids: List[str] = Field(alias="objectIDs") + """ Object IDs of the records that are part of the event. """ + user_token: str = Field(alias="userToken") + """ Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + authenticated_user_token: Optional[str] = Field( + default=None, alias="authenticatedUserToken" ) - object_data: Optional[ - Annotated[List[ObjectData], Field(min_length=1, max_length=20)] - ] = Field( - default=None, - description="Extra information about the records involved in a purchase or add-to-cart event. If specified, it must have the same length as `objectIDs`. ", - alias="objectData", - ) - timestamp: Optional[StrictInt] = Field( - default=None, - description="Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. ", - ) - value: Optional[Value] = None + """ Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + currency: Optional[str] = Field(default=None, alias="currency") + """ Three-letter [currency code](https://www.iso.org/iso-4217-currency-codes.html). """ + object_data: Optional[List[ObjectData]] = Field(default=None, alias="objectData") + """ Extra information about the records involved in a purchase or add-to-cart event. If specified, it must have the same length as `objectIDs`. """ + timestamp: Optional[int] = Field(default=None, alias="timestamp") + """ Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. """ + value: Optional[Value] = Field(default=None, alias="value") @field_validator("event_name") def event_name_validate_regular_expression(cls, value): @@ -104,45 +83,30 @@ def authenticated_user_token_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AddedToCartObjectIDs from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.object_data: - for _item in self.object_data: - if _item: - _items.append(_item.to_dict()) - _dict["objectData"] = _items - if self.value: - _dict["value"] = self.value.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AddedToCartObjectIDs from a dict""" if obj is None: return None @@ -150,27 +114,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "eventName": obj.get("eventName"), - "eventType": obj.get("eventType"), - "eventSubtype": obj.get("eventSubtype"), - "index": obj.get("index"), - "objectIDs": obj.get("objectIDs"), - "userToken": obj.get("userToken"), - "authenticatedUserToken": obj.get("authenticatedUserToken"), - "currency": obj.get("currency"), - "objectData": ( - [ObjectData.from_dict(_item) for _item in obj.get("objectData")] - if obj.get("objectData") is not None - else None - ), - "timestamp": obj.get("timestamp"), - "value": ( - Value.from_dict(obj.get("value")) - if obj.get("value") is not None - else None - ), - } + obj["eventType"] = obj.get("eventType") + obj["eventSubtype"] = obj.get("eventSubtype") + obj["objectData"] = ( + [ObjectData.from_dict(_item) for _item in obj["objectData"]] + if obj.get("objectData") is not None + else None + ) + obj["value"] = ( + Value.from_dict(obj["value"]) if obj.get("value") is not None else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/insights/models/added_to_cart_object_ids_after_search.py b/algoliasearch/insights/models/added_to_cart_object_ids_after_search.py index 0b3a990ad..6cd5d64dd 100644 --- a/algoliasearch/insights/models/added_to_cart_object_ids_after_search.py +++ b/algoliasearch/insights/models/added_to_cart_object_ids_after_search.py @@ -11,12 +11,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.insights.models.add_to_cart_event import AddToCartEvent @@ -30,52 +30,31 @@ class AddedToCartObjectIDsAfterSearch(BaseModel): Use this event to track when users add items to their shopping cart after a previous Algolia request. If you're building your category pages with Algolia, you'll also use this event. """ - event_name: Annotated[str, Field(min_length=1, strict=True, max_length=64)] = Field( - description="Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. ", - alias="eventName", - ) + event_name: str = Field(alias="eventName") + """ Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. """ event_type: ConversionEvent = Field(alias="eventType") event_subtype: AddToCartEvent = Field(alias="eventSubtype") - index: StrictStr = Field( - description="Index name (case-sensitive) to which the event's items belong." - ) - query_id: Annotated[str, Field(min_length=32, strict=True, max_length=32)] = Field( - description="Unique identifier for a search query. The query ID is required for events related to search or browse requests. If you add `clickAnalytics: true` as a search request parameter, the query ID is included in the API response. ", - alias="queryID", - ) - object_ids: Annotated[List[StrictStr], Field(min_length=1, max_length=20)] = Field( - description="Object IDs of the records that are part of the event.", - alias="objectIDs", - ) - user_token: Annotated[str, Field(min_length=1, strict=True, max_length=129)] = ( - Field( - description="Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - ) - authenticated_user_token: Optional[ - Annotated[str, Field(min_length=1, strict=True, max_length=129)] - ] = Field( - default=None, - description="Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="authenticatedUserToken", + index: str = Field(alias="index") + """ Index name (case-sensitive) to which the event's items belong. """ + query_id: str = Field(alias="queryID") + """ Unique identifier for a search query. The query ID is required for events related to search or browse requests. If you add `clickAnalytics: true` as a search request parameter, the query ID is included in the API response. """ + object_ids: List[str] = Field(alias="objectIDs") + """ Object IDs of the records that are part of the event. """ + user_token: str = Field(alias="userToken") + """ Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + authenticated_user_token: Optional[str] = Field( + default=None, alias="authenticatedUserToken" ) - currency: Optional[StrictStr] = Field( - default=None, - description="Three-letter [currency code](https://www.iso.org/iso-4217-currency-codes.html).", + """ Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + currency: Optional[str] = Field(default=None, alias="currency") + """ Three-letter [currency code](https://www.iso.org/iso-4217-currency-codes.html). """ + object_data: Optional[List[ObjectDataAfterSearch]] = Field( + default=None, alias="objectData" ) - object_data: Optional[ - Annotated[List[ObjectDataAfterSearch], Field(min_length=1, max_length=20)] - ] = Field( - default=None, - description="Extra information about the records involved in a purchase or add-to-cart events. If provided, it must be the same length as `objectIDs`. ", - alias="objectData", - ) - timestamp: Optional[StrictInt] = Field( - default=None, - description="Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. ", - ) - value: Optional[Value] = None + """ Extra information about the records involved in a purchase or add-to-cart events. If provided, it must be the same length as `objectIDs`. """ + timestamp: Optional[int] = Field(default=None, alias="timestamp") + """ Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. """ + value: Optional[Value] = Field(default=None, alias="value") @field_validator("event_name") def event_name_validate_regular_expression(cls, value): @@ -115,45 +94,30 @@ def authenticated_user_token_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AddedToCartObjectIDsAfterSearch from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.object_data: - for _item in self.object_data: - if _item: - _items.append(_item.to_dict()) - _dict["objectData"] = _items - if self.value: - _dict["value"] = self.value.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AddedToCartObjectIDsAfterSearch from a dict""" if obj is None: return None @@ -161,31 +125,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "eventName": obj.get("eventName"), - "eventType": obj.get("eventType"), - "eventSubtype": obj.get("eventSubtype"), - "index": obj.get("index"), - "queryID": obj.get("queryID"), - "objectIDs": obj.get("objectIDs"), - "userToken": obj.get("userToken"), - "authenticatedUserToken": obj.get("authenticatedUserToken"), - "currency": obj.get("currency"), - "objectData": ( - [ - ObjectDataAfterSearch.from_dict(_item) - for _item in obj.get("objectData") - ] - if obj.get("objectData") is not None - else None - ), - "timestamp": obj.get("timestamp"), - "value": ( - Value.from_dict(obj.get("value")) - if obj.get("value") is not None - else None - ), - } + obj["eventType"] = obj.get("eventType") + obj["eventSubtype"] = obj.get("eventSubtype") + obj["objectData"] = ( + [ObjectDataAfterSearch.from_dict(_item) for _item in obj["objectData"]] + if obj.get("objectData") is not None + else None + ) + obj["value"] = ( + Value.from_dict(obj["value"]) if obj.get("value") is not None else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/insights/models/clicked_filters.py b/algoliasearch/insights/models/clicked_filters.py index 8d591ad19..b248cba93 100644 --- a/algoliasearch/insights/models/clicked_filters.py +++ b/algoliasearch/insights/models/clicked_filters.py @@ -11,12 +11,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.insights.models.click_event import ClickEvent @@ -27,34 +27,21 @@ class ClickedFilters(BaseModel): Use this event to track when users click facet filters in your user interface. """ - event_name: Annotated[str, Field(min_length=1, strict=True, max_length=64)] = Field( - description="Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. ", - alias="eventName", - ) + event_name: str = Field(alias="eventName") + """ Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. """ event_type: ClickEvent = Field(alias="eventType") - index: StrictStr = Field( - description="Index name (case-sensitive) to which the event's items belong." - ) - filters: Annotated[List[StrictStr], Field(min_length=1, max_length=20)] = Field( - description="Applied facet filters. Facet filters are `facet:value` pairs. Facet values must be URL-encoded, such as, `discount:10%25`. " - ) - user_token: Annotated[str, Field(min_length=1, strict=True, max_length=129)] = ( - Field( - description="Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - ) - authenticated_user_token: Optional[ - Annotated[str, Field(min_length=1, strict=True, max_length=129)] - ] = Field( - default=None, - description="Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="authenticatedUserToken", - ) - timestamp: Optional[StrictInt] = Field( - default=None, - description="Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. ", + index: str = Field(alias="index") + """ Index name (case-sensitive) to which the event's items belong. """ + filters: List[str] = Field(alias="filters") + """ Applied facet filters. Facet filters are `facet:value` pairs. Facet values must be URL-encoded, such as, `discount:10%25`. """ + user_token: str = Field(alias="userToken") + """ Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + authenticated_user_token: Optional[str] = Field( + default=None, alias="authenticatedUserToken" ) + """ Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + timestamp: Optional[int] = Field(default=None, alias="timestamp") + """ Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. """ @field_validator("event_name") def event_name_validate_regular_expression(cls, value): @@ -87,37 +74,30 @@ def authenticated_user_token_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ClickedFilters from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ClickedFilters from a dict""" if obj is None: return None @@ -125,15 +105,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "eventName": obj.get("eventName"), - "eventType": obj.get("eventType"), - "index": obj.get("index"), - "filters": obj.get("filters"), - "userToken": obj.get("userToken"), - "authenticatedUserToken": obj.get("authenticatedUserToken"), - "timestamp": obj.get("timestamp"), - } - ) - return _obj + obj["eventType"] = obj.get("eventType") + + return cls.model_validate(obj) diff --git a/algoliasearch/insights/models/clicked_object_ids.py b/algoliasearch/insights/models/clicked_object_ids.py index fc10fc4ee..de1e332e2 100644 --- a/algoliasearch/insights/models/clicked_object_ids.py +++ b/algoliasearch/insights/models/clicked_object_ids.py @@ -11,12 +11,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.insights.models.click_event import ClickEvent @@ -27,35 +27,21 @@ class ClickedObjectIDs(BaseModel): Use this event to track when users click items unrelated to a previous Algolia request. For example, if you don't use Algolia to build your category pages, use this event. To track click events related to Algolia requests, use the \"Clicked object IDs after search\" event. """ - event_name: Annotated[str, Field(min_length=1, strict=True, max_length=64)] = Field( - description="Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. ", - alias="eventName", - ) + event_name: str = Field(alias="eventName") + """ Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. """ event_type: ClickEvent = Field(alias="eventType") - index: StrictStr = Field( - description="Index name (case-sensitive) to which the event's items belong." - ) - object_ids: Annotated[List[StrictStr], Field(min_length=1, max_length=20)] = Field( - description="Object IDs of the records that are part of the event.", - alias="objectIDs", - ) - user_token: Annotated[str, Field(min_length=1, strict=True, max_length=129)] = ( - Field( - description="Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - ) - authenticated_user_token: Optional[ - Annotated[str, Field(min_length=1, strict=True, max_length=129)] - ] = Field( - default=None, - description="Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="authenticatedUserToken", - ) - timestamp: Optional[StrictInt] = Field( - default=None, - description="Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. ", + index: str = Field(alias="index") + """ Index name (case-sensitive) to which the event's items belong. """ + object_ids: List[str] = Field(alias="objectIDs") + """ Object IDs of the records that are part of the event. """ + user_token: str = Field(alias="userToken") + """ Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + authenticated_user_token: Optional[str] = Field( + default=None, alias="authenticatedUserToken" ) + """ Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + timestamp: Optional[int] = Field(default=None, alias="timestamp") + """ Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. """ @field_validator("event_name") def event_name_validate_regular_expression(cls, value): @@ -88,37 +74,30 @@ def authenticated_user_token_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ClickedObjectIDs from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ClickedObjectIDs from a dict""" if obj is None: return None @@ -126,15 +105,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "eventName": obj.get("eventName"), - "eventType": obj.get("eventType"), - "index": obj.get("index"), - "objectIDs": obj.get("objectIDs"), - "userToken": obj.get("userToken"), - "authenticatedUserToken": obj.get("authenticatedUserToken"), - "timestamp": obj.get("timestamp"), - } - ) - return _obj + obj["eventType"] = obj.get("eventType") + + return cls.model_validate(obj) diff --git a/algoliasearch/insights/models/clicked_object_ids_after_search.py b/algoliasearch/insights/models/clicked_object_ids_after_search.py index a2fa0782c..6b6b0c6ed 100644 --- a/algoliasearch/insights/models/clicked_object_ids_after_search.py +++ b/algoliasearch/insights/models/clicked_object_ids_after_search.py @@ -11,12 +11,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.insights.models.click_event import ClickEvent @@ -27,42 +27,25 @@ class ClickedObjectIDsAfterSearch(BaseModel): Click event after an Algolia request. Use this event to track when users click items in the search results. If you're building your category pages with Algolia, you'll also use this event. """ - event_name: Annotated[str, Field(min_length=1, strict=True, max_length=64)] = Field( - description="Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. ", - alias="eventName", - ) + event_name: str = Field(alias="eventName") + """ Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. """ event_type: ClickEvent = Field(alias="eventType") - index: StrictStr = Field( - description="Index name (case-sensitive) to which the event's items belong." - ) - object_ids: Annotated[List[StrictStr], Field(min_length=1, max_length=20)] = Field( - description="Object IDs of the records that are part of the event.", - alias="objectIDs", - ) - positions: Annotated[List[StrictInt], Field(min_length=1, max_length=20)] = Field( - description="Position of the clicked item the search results. You must provide 1 `position` for each `objectID`. " - ) - query_id: Annotated[str, Field(min_length=32, strict=True, max_length=32)] = Field( - description="Unique identifier for a search query. The query ID is required for events related to search or browse requests. If you add `clickAnalytics: true` as a search request parameter, the query ID is included in the API response. ", - alias="queryID", - ) - user_token: Annotated[str, Field(min_length=1, strict=True, max_length=129)] = ( - Field( - description="Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - ) - authenticated_user_token: Optional[ - Annotated[str, Field(min_length=1, strict=True, max_length=129)] - ] = Field( - default=None, - description="Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="authenticatedUserToken", - ) - timestamp: Optional[StrictInt] = Field( - default=None, - description="Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. ", + index: str = Field(alias="index") + """ Index name (case-sensitive) to which the event's items belong. """ + object_ids: List[str] = Field(alias="objectIDs") + """ Object IDs of the records that are part of the event. """ + positions: List[int] = Field(alias="positions") + """ Position of the clicked item the search results. You must provide 1 `position` for each `objectID`. """ + query_id: str = Field(alias="queryID") + """ Unique identifier for a search query. The query ID is required for events related to search or browse requests. If you add `clickAnalytics: true` as a search request parameter, the query ID is included in the API response. """ + user_token: str = Field(alias="userToken") + """ Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + authenticated_user_token: Optional[str] = Field( + default=None, alias="authenticatedUserToken" ) + """ Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + timestamp: Optional[int] = Field(default=None, alias="timestamp") + """ Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. """ @field_validator("event_name") def event_name_validate_regular_expression(cls, value): @@ -102,37 +85,30 @@ def authenticated_user_token_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ClickedObjectIDsAfterSearch from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ClickedObjectIDsAfterSearch from a dict""" if obj is None: return None @@ -140,17 +116,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "eventName": obj.get("eventName"), - "eventType": obj.get("eventType"), - "index": obj.get("index"), - "objectIDs": obj.get("objectIDs"), - "positions": obj.get("positions"), - "queryID": obj.get("queryID"), - "userToken": obj.get("userToken"), - "authenticatedUserToken": obj.get("authenticatedUserToken"), - "timestamp": obj.get("timestamp"), - } - ) - return _obj + obj["eventType"] = obj.get("eventType") + + return cls.model_validate(obj) diff --git a/algoliasearch/insights/models/converted_filters.py b/algoliasearch/insights/models/converted_filters.py index d915126d8..c90f13687 100644 --- a/algoliasearch/insights/models/converted_filters.py +++ b/algoliasearch/insights/models/converted_filters.py @@ -11,12 +11,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.insights.models.conversion_event import ConversionEvent @@ -27,34 +27,21 @@ class ConvertedFilters(BaseModel): ConvertedFilters """ - event_name: Annotated[str, Field(min_length=1, strict=True, max_length=64)] = Field( - description="Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. ", - alias="eventName", - ) + event_name: str = Field(alias="eventName") + """ Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. """ event_type: ConversionEvent = Field(alias="eventType") - index: StrictStr = Field( - description="Index name (case-sensitive) to which the event's items belong." - ) - filters: Annotated[List[StrictStr], Field(min_length=1, max_length=20)] = Field( - description="Applied facet filters. Facet filters are `facet:value` pairs. Facet values must be URL-encoded, such as, `discount:10%25`. " - ) - user_token: Annotated[str, Field(min_length=1, strict=True, max_length=129)] = ( - Field( - description="Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - ) - authenticated_user_token: Optional[ - Annotated[str, Field(min_length=1, strict=True, max_length=129)] - ] = Field( - default=None, - description="Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="authenticatedUserToken", - ) - timestamp: Optional[StrictInt] = Field( - default=None, - description="Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. ", + index: str = Field(alias="index") + """ Index name (case-sensitive) to which the event's items belong. """ + filters: List[str] = Field(alias="filters") + """ Applied facet filters. Facet filters are `facet:value` pairs. Facet values must be URL-encoded, such as, `discount:10%25`. """ + user_token: str = Field(alias="userToken") + """ Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + authenticated_user_token: Optional[str] = Field( + default=None, alias="authenticatedUserToken" ) + """ Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + timestamp: Optional[int] = Field(default=None, alias="timestamp") + """ Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. """ @field_validator("event_name") def event_name_validate_regular_expression(cls, value): @@ -87,37 +74,30 @@ def authenticated_user_token_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ConvertedFilters from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ConvertedFilters from a dict""" if obj is None: return None @@ -125,15 +105,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "eventName": obj.get("eventName"), - "eventType": obj.get("eventType"), - "index": obj.get("index"), - "filters": obj.get("filters"), - "userToken": obj.get("userToken"), - "authenticatedUserToken": obj.get("authenticatedUserToken"), - "timestamp": obj.get("timestamp"), - } - ) - return _obj + obj["eventType"] = obj.get("eventType") + + return cls.model_validate(obj) diff --git a/algoliasearch/insights/models/converted_object_ids.py b/algoliasearch/insights/models/converted_object_ids.py index 2142c1ceb..19aa55a88 100644 --- a/algoliasearch/insights/models/converted_object_ids.py +++ b/algoliasearch/insights/models/converted_object_ids.py @@ -11,12 +11,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.insights.models.conversion_event import ConversionEvent @@ -27,35 +27,21 @@ class ConvertedObjectIDs(BaseModel): Use this event to track when users convert on items unrelated to a previous Algolia request. For example, if you don't use Algolia to build your category pages, use this event. To track conversion events related to Algolia requests, use the \"Converted object IDs after search\" event. """ - event_name: Annotated[str, Field(min_length=1, strict=True, max_length=64)] = Field( - description="Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. ", - alias="eventName", - ) + event_name: str = Field(alias="eventName") + """ Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. """ event_type: ConversionEvent = Field(alias="eventType") - index: StrictStr = Field( - description="Index name (case-sensitive) to which the event's items belong." - ) - object_ids: Annotated[List[StrictStr], Field(min_length=1, max_length=20)] = Field( - description="Object IDs of the records that are part of the event.", - alias="objectIDs", - ) - user_token: Annotated[str, Field(min_length=1, strict=True, max_length=129)] = ( - Field( - description="Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - ) - authenticated_user_token: Optional[ - Annotated[str, Field(min_length=1, strict=True, max_length=129)] - ] = Field( - default=None, - description="Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="authenticatedUserToken", - ) - timestamp: Optional[StrictInt] = Field( - default=None, - description="Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. ", + index: str = Field(alias="index") + """ Index name (case-sensitive) to which the event's items belong. """ + object_ids: List[str] = Field(alias="objectIDs") + """ Object IDs of the records that are part of the event. """ + user_token: str = Field(alias="userToken") + """ Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + authenticated_user_token: Optional[str] = Field( + default=None, alias="authenticatedUserToken" ) + """ Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + timestamp: Optional[int] = Field(default=None, alias="timestamp") + """ Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. """ @field_validator("event_name") def event_name_validate_regular_expression(cls, value): @@ -88,37 +74,30 @@ def authenticated_user_token_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ConvertedObjectIDs from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ConvertedObjectIDs from a dict""" if obj is None: return None @@ -126,15 +105,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "eventName": obj.get("eventName"), - "eventType": obj.get("eventType"), - "index": obj.get("index"), - "objectIDs": obj.get("objectIDs"), - "userToken": obj.get("userToken"), - "authenticatedUserToken": obj.get("authenticatedUserToken"), - "timestamp": obj.get("timestamp"), - } - ) - return _obj + obj["eventType"] = obj.get("eventType") + + return cls.model_validate(obj) diff --git a/algoliasearch/insights/models/converted_object_ids_after_search.py b/algoliasearch/insights/models/converted_object_ids_after_search.py index 88e1506be..7a9805803 100644 --- a/algoliasearch/insights/models/converted_object_ids_after_search.py +++ b/algoliasearch/insights/models/converted_object_ids_after_search.py @@ -11,12 +11,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.insights.models.conversion_event import ConversionEvent @@ -27,39 +27,23 @@ class ConvertedObjectIDsAfterSearch(BaseModel): Use this event to track when users convert after a previous Algolia request. For example, a user clicks on an item in the search results to view the product detail page. Then, the user adds the item to their shopping cart. If you're building your category pages with Algolia, you'll also use this event. """ - event_name: Annotated[str, Field(min_length=1, strict=True, max_length=64)] = Field( - description="Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. ", - alias="eventName", - ) + event_name: str = Field(alias="eventName") + """ Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. """ event_type: ConversionEvent = Field(alias="eventType") - index: StrictStr = Field( - description="Index name (case-sensitive) to which the event's items belong." - ) - object_ids: Annotated[List[StrictStr], Field(min_length=1, max_length=20)] = Field( - description="Object IDs of the records that are part of the event.", - alias="objectIDs", - ) - query_id: Annotated[str, Field(min_length=32, strict=True, max_length=32)] = Field( - description="Unique identifier for a search query. The query ID is required for events related to search or browse requests. If you add `clickAnalytics: true` as a search request parameter, the query ID is included in the API response. ", - alias="queryID", - ) - user_token: Annotated[str, Field(min_length=1, strict=True, max_length=129)] = ( - Field( - description="Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - ) - authenticated_user_token: Optional[ - Annotated[str, Field(min_length=1, strict=True, max_length=129)] - ] = Field( - default=None, - description="Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="authenticatedUserToken", - ) - timestamp: Optional[StrictInt] = Field( - default=None, - description="Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. ", + index: str = Field(alias="index") + """ Index name (case-sensitive) to which the event's items belong. """ + object_ids: List[str] = Field(alias="objectIDs") + """ Object IDs of the records that are part of the event. """ + query_id: str = Field(alias="queryID") + """ Unique identifier for a search query. The query ID is required for events related to search or browse requests. If you add `clickAnalytics: true` as a search request parameter, the query ID is included in the API response. """ + user_token: str = Field(alias="userToken") + """ Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + authenticated_user_token: Optional[str] = Field( + default=None, alias="authenticatedUserToken" ) + """ Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + timestamp: Optional[int] = Field(default=None, alias="timestamp") + """ Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. """ @field_validator("event_name") def event_name_validate_regular_expression(cls, value): @@ -99,37 +83,30 @@ def authenticated_user_token_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ConvertedObjectIDsAfterSearch from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ConvertedObjectIDsAfterSearch from a dict""" if obj is None: return None @@ -137,16 +114,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "eventName": obj.get("eventName"), - "eventType": obj.get("eventType"), - "index": obj.get("index"), - "objectIDs": obj.get("objectIDs"), - "queryID": obj.get("queryID"), - "userToken": obj.get("userToken"), - "authenticatedUserToken": obj.get("authenticatedUserToken"), - "timestamp": obj.get("timestamp"), - } - ) - return _obj + obj["eventType"] = obj.get("eventType") + + return cls.model_validate(obj) diff --git a/algoliasearch/insights/models/discount.py b/algoliasearch/insights/models/discount.py index be17ca5d9..cefe926e5 100644 --- a/algoliasearch/insights/models/discount.py +++ b/algoliasearch/insights/models/discount.py @@ -8,16 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import ( - BaseModel, - StrictFloat, - StrictInt, - StrictStr, - ValidationError, - model_serializer, -) +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -30,9 +23,12 @@ class Discount(BaseModel): Absolute value of the discount for this product, in units of `currency`. """ - oneof_schema_1_validator: Optional[Union[StrictFloat, StrictInt]] = None - oneof_schema_2_validator: Optional[StrictStr] = None + oneof_schema_1_validator: Optional[float] = Field(default=None) + + oneof_schema_2_validator: Optional[str] = Field(default=None) + actual_instance: Optional[Union[float, str]] = None + one_of_schemas: Set[str] = {"float", "str"} def __init__(self, *args, **kwargs) -> None: if args: @@ -56,7 +52,8 @@ def unwrap_actual_instance(self) -> Optional[Union[float, str]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of Discount from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -90,17 +87,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], float, str]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/insights/models/error_base.py b/algoliasearch/insights/models/error_base.py index 4317b330d..075d8a3ac 100644 --- a/algoliasearch/insights/models/error_base.py +++ b/algoliasearch/insights/models/error_base.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, ClassVar, Dict, List, Optional +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,50 +23,34 @@ class ErrorBase(BaseModel): Error. """ - message: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["message"] + message: Optional[str] = Field(default=None, alias="message") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + extra="allow", ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ErrorBase from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={ - "additional_properties", - }, exclude_none=True, exclude_unset=True, ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ErrorBase from a dict""" if obj is None: return None @@ -74,10 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"message": obj.get("message")}) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/insights/models/events_items.py b/algoliasearch/insights/models/events_items.py index 037eb01f7..b5b47be2f 100644 --- a/algoliasearch/insights/models/events_items.py +++ b/algoliasearch/insights/models/events_items.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -45,18 +45,38 @@ class EventsItems(BaseModel): EventsItems """ - oneof_schema_1_validator: Optional[ClickedObjectIDsAfterSearch] = None - oneof_schema_2_validator: Optional[AddedToCartObjectIDsAfterSearch] = None - oneof_schema_3_validator: Optional[PurchasedObjectIDsAfterSearch] = None - oneof_schema_4_validator: Optional[ConvertedObjectIDsAfterSearch] = None - oneof_schema_5_validator: Optional[ClickedObjectIDs] = None - oneof_schema_6_validator: Optional[PurchasedObjectIDs] = None - oneof_schema_7_validator: Optional[AddedToCartObjectIDs] = None - oneof_schema_8_validator: Optional[ConvertedObjectIDs] = None - oneof_schema_9_validator: Optional[ClickedFilters] = None - oneof_schema_10_validator: Optional[ConvertedFilters] = None - oneof_schema_11_validator: Optional[ViewedObjectIDs] = None - oneof_schema_12_validator: Optional[ViewedFilters] = None + oneof_schema_1_validator: Optional[ClickedObjectIDsAfterSearch] = Field( + default=None + ) + + oneof_schema_2_validator: Optional[AddedToCartObjectIDsAfterSearch] = Field( + default=None + ) + + oneof_schema_3_validator: Optional[PurchasedObjectIDsAfterSearch] = Field( + default=None + ) + + oneof_schema_4_validator: Optional[ConvertedObjectIDsAfterSearch] = Field( + default=None + ) + + oneof_schema_5_validator: Optional[ClickedObjectIDs] = Field(default=None) + + oneof_schema_6_validator: Optional[PurchasedObjectIDs] = Field(default=None) + + oneof_schema_7_validator: Optional[AddedToCartObjectIDs] = Field(default=None) + + oneof_schema_8_validator: Optional[ConvertedObjectIDs] = Field(default=None) + + oneof_schema_9_validator: Optional[ClickedFilters] = Field(default=None) + + oneof_schema_10_validator: Optional[ConvertedFilters] = Field(default=None) + + oneof_schema_11_validator: Optional[ViewedObjectIDs] = Field(default=None) + + oneof_schema_12_validator: Optional[ViewedFilters] = Field(default=None) + actual_instance: Optional[ Union[ AddedToCartObjectIDs, @@ -73,6 +93,20 @@ class EventsItems(BaseModel): ViewedObjectIDs, ] ] = None + one_of_schemas: Set[str] = { + "AddedToCartObjectIDs", + "AddedToCartObjectIDsAfterSearch", + "ClickedFilters", + "ClickedObjectIDs", + "ClickedObjectIDsAfterSearch", + "ConvertedFilters", + "ConvertedObjectIDs", + "ConvertedObjectIDsAfterSearch", + "PurchasedObjectIDs", + "PurchasedObjectIDsAfterSearch", + "ViewedFilters", + "ViewedObjectIDs", + } def __init__(self, *args, **kwargs) -> None: if args: @@ -113,7 +147,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of EventsItems from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -207,17 +242,39 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[ + Union[ + Dict[str, Any], + AddedToCartObjectIDs, + AddedToCartObjectIDsAfterSearch, + ClickedFilters, + ClickedObjectIDs, + ClickedObjectIDsAfterSearch, + ConvertedFilters, + ConvertedObjectIDs, + ConvertedObjectIDsAfterSearch, + PurchasedObjectIDs, + PurchasedObjectIDsAfterSearch, + ViewedFilters, + ViewedObjectIDs, + ] + ]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/insights/models/events_response.py b/algoliasearch/insights/models/events_response.py index c442faf2f..0ac3d4d0e 100644 --- a/algoliasearch/insights/models/events_response.py +++ b/algoliasearch/insights/models/events_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,45 +23,36 @@ class EventsResponse(BaseModel): The response of the Insights API. """ - message: Optional[StrictStr] = Field( - default=None, description="Details about the response, such as error messages." - ) - status: Optional[StrictInt] = Field( - default=None, description="The HTTP status code of the response." - ) + message: Optional[str] = Field(default=None, alias="message") + """ Details about the response, such as error messages. """ + status: Optional[int] = Field(default=None, alias="status") + """ The HTTP status code of the response. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of EventsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of EventsResponse from a dict""" if obj is None: return None @@ -69,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"message": obj.get("message"), "status": obj.get("status")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/insights/models/insights_events.py b/algoliasearch/insights/models/insights_events.py index 2ff093620..a071f4f9d 100644 --- a/algoliasearch/insights/models/insights_events.py +++ b/algoliasearch/insights/models/insights_events.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.insights.models.events_items import EventsItems @@ -26,48 +26,34 @@ class InsightsEvents(BaseModel): InsightsEvents """ - events: Annotated[List[EventsItems], Field(min_length=1, max_length=1000)] = Field( - description="Click and conversion events. **All** events must be valid, otherwise the API returns an error. " - ) + events: List[EventsItems] = Field(alias="events") + """ Click and conversion events. **All** events must be valid, otherwise the API returns an error. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of InsightsEvents from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.events: - for _item in self.events: - if _item: - _items.append(_item.to_dict()) - _dict["events"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of InsightsEvents from a dict""" if obj is None: return None @@ -75,13 +61,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "events": ( - [EventsItems.from_dict(_item) for _item in obj.get("events")] - if obj.get("events") is not None - else None - ) - } + obj["events"] = ( + [EventsItems.from_dict(_item) for _item in obj["events"]] + if obj.get("events") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/insights/models/object_data.py b/algoliasearch/insights/models/object_data.py index a9beaee19..df0ab0ef8 100644 --- a/algoliasearch/insights/models/object_data.py +++ b/algoliasearch/insights/models/object_data.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,49 +27,36 @@ class ObjectData(BaseModel): ObjectData """ - price: Optional[Price] = None - quantity: Optional[StrictInt] = Field( - default=None, - description="Quantity of a product that has been purchased or added to the cart. The total purchase value is the sum of `quantity` multiplied with the `price` for each purchased item. ", - ) - discount: Optional[Discount] = None + price: Optional[Price] = Field(default=None, alias="price") + quantity: Optional[int] = Field(default=None, alias="quantity") + """ Quantity of a product that has been purchased or added to the cart. The total purchase value is the sum of `quantity` multiplied with the `price` for each purchased item. """ + discount: Optional[Discount] = Field(default=None, alias="discount") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ObjectData from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.price: - _dict["price"] = self.price.to_dict() - if self.discount: - _dict["discount"] = self.discount.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ObjectData from a dict""" if obj is None: return None @@ -77,19 +64,13 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "price": ( - Price.from_dict(obj.get("price")) - if obj.get("price") is not None - else None - ), - "quantity": obj.get("quantity"), - "discount": ( - Discount.from_dict(obj.get("discount")) - if obj.get("discount") is not None - else None - ), - } + obj["price"] = ( + Price.from_dict(obj["price"]) if obj.get("price") is not None else None ) - return _obj + obj["discount"] = ( + Discount.from_dict(obj["discount"]) + if obj.get("discount") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/insights/models/object_data_after_search.py b/algoliasearch/insights/models/object_data_after_search.py index 09a1a5dee..b6356a8c3 100644 --- a/algoliasearch/insights/models/object_data_after_search.py +++ b/algoliasearch/insights/models/object_data_after_search.py @@ -11,12 +11,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.insights.models.discount import Discount @@ -28,19 +28,12 @@ class ObjectDataAfterSearch(BaseModel): ObjectDataAfterSearch """ - query_id: Optional[ - Annotated[str, Field(min_length=32, strict=True, max_length=32)] - ] = Field( - default=None, - description="Unique identifier for a search query, used to track purchase events with multiple records that originate from different searches.", - alias="queryID", - ) - price: Optional[Price] = None - quantity: Optional[StrictInt] = Field( - default=None, - description="Quantity of a product that has been purchased or added to the cart. The total purchase value is the sum of `quantity` multiplied with the `price` for each purchased item. ", - ) - discount: Optional[Discount] = None + query_id: Optional[str] = Field(default=None, alias="queryID") + """ Unique identifier for a search query, used to track purchase events with multiple records that originate from different searches. """ + price: Optional[Price] = Field(default=None, alias="price") + quantity: Optional[int] = Field(default=None, alias="quantity") + """ Quantity of a product that has been purchased or added to the cart. The total purchase value is the sum of `quantity` multiplied with the `price` for each purchased item. """ + discount: Optional[Discount] = Field(default=None, alias="discount") @field_validator("query_id") def query_id_validate_regular_expression(cls, value): @@ -53,41 +46,30 @@ def query_id_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ObjectDataAfterSearch from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.price: - _dict["price"] = self.price.to_dict() - if self.discount: - _dict["discount"] = self.discount.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ObjectDataAfterSearch from a dict""" if obj is None: return None @@ -95,20 +77,13 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "queryID": obj.get("queryID"), - "price": ( - Price.from_dict(obj.get("price")) - if obj.get("price") is not None - else None - ), - "quantity": obj.get("quantity"), - "discount": ( - Discount.from_dict(obj.get("discount")) - if obj.get("discount") is not None - else None - ), - } + obj["price"] = ( + Price.from_dict(obj["price"]) if obj.get("price") is not None else None + ) + obj["discount"] = ( + Discount.from_dict(obj["discount"]) + if obj.get("discount") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/insights/models/price.py b/algoliasearch/insights/models/price.py index d3b4fefad..8b477a7c3 100644 --- a/algoliasearch/insights/models/price.py +++ b/algoliasearch/insights/models/price.py @@ -8,16 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import ( - BaseModel, - StrictFloat, - StrictInt, - StrictStr, - ValidationError, - model_serializer, -) +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -30,9 +23,12 @@ class Price(BaseModel): Total price of a product, including any discounts, in units of `currency`. """ - oneof_schema_1_validator: Optional[Union[StrictFloat, StrictInt]] = None - oneof_schema_2_validator: Optional[StrictStr] = None + oneof_schema_1_validator: Optional[float] = Field(default=None) + + oneof_schema_2_validator: Optional[str] = Field(default=None) + actual_instance: Optional[Union[float, str]] = None + one_of_schemas: Set[str] = {"float", "str"} def __init__(self, *args, **kwargs) -> None: if args: @@ -56,7 +52,8 @@ def unwrap_actual_instance(self) -> Optional[Union[float, str]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of Price from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -90,17 +87,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], float, str]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/insights/models/purchased_object_ids.py b/algoliasearch/insights/models/purchased_object_ids.py index 9de857788..f8678faaa 100644 --- a/algoliasearch/insights/models/purchased_object_ids.py +++ b/algoliasearch/insights/models/purchased_object_ids.py @@ -11,12 +11,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.insights.models.conversion_event import ConversionEvent @@ -30,48 +30,27 @@ class PurchasedObjectIDs(BaseModel): Use this event to track when users make a purchase unrelated to a previous Algolia request. For example, if you don't use Algolia to build your category pages, use this event. To track purchase events related to Algolia requests, use the \"Purchased object IDs after search\" event. """ - event_name: Annotated[str, Field(min_length=1, strict=True, max_length=64)] = Field( - description="Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. ", - alias="eventName", - ) + event_name: str = Field(alias="eventName") + """ Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. """ event_type: ConversionEvent = Field(alias="eventType") event_subtype: PurchaseEvent = Field(alias="eventSubtype") - index: StrictStr = Field( - description="Index name (case-sensitive) to which the event's items belong." - ) - object_ids: Annotated[List[StrictStr], Field(min_length=1, max_length=20)] = Field( - description="Object IDs of the records that are part of the event.", - alias="objectIDs", - ) - user_token: Annotated[str, Field(min_length=1, strict=True, max_length=129)] = ( - Field( - description="Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - ) - authenticated_user_token: Optional[ - Annotated[str, Field(min_length=1, strict=True, max_length=129)] - ] = Field( - default=None, - description="Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="authenticatedUserToken", - ) - currency: Optional[StrictStr] = Field( - default=None, - description="Three-letter [currency code](https://www.iso.org/iso-4217-currency-codes.html).", + index: str = Field(alias="index") + """ Index name (case-sensitive) to which the event's items belong. """ + object_ids: List[str] = Field(alias="objectIDs") + """ Object IDs of the records that are part of the event. """ + user_token: str = Field(alias="userToken") + """ Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + authenticated_user_token: Optional[str] = Field( + default=None, alias="authenticatedUserToken" ) - object_data: Optional[ - Annotated[List[ObjectData], Field(min_length=1, max_length=20)] - ] = Field( - default=None, - description="Extra information about the records involved in a purchase or add-to-cart event. If specified, it must have the same length as `objectIDs`. ", - alias="objectData", - ) - timestamp: Optional[StrictInt] = Field( - default=None, - description="Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. ", - ) - value: Optional[Value] = None + """ Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + currency: Optional[str] = Field(default=None, alias="currency") + """ Three-letter [currency code](https://www.iso.org/iso-4217-currency-codes.html). """ + object_data: Optional[List[ObjectData]] = Field(default=None, alias="objectData") + """ Extra information about the records involved in a purchase or add-to-cart event. If specified, it must have the same length as `objectIDs`. """ + timestamp: Optional[int] = Field(default=None, alias="timestamp") + """ Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. """ + value: Optional[Value] = Field(default=None, alias="value") @field_validator("event_name") def event_name_validate_regular_expression(cls, value): @@ -104,45 +83,30 @@ def authenticated_user_token_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of PurchasedObjectIDs from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.object_data: - for _item in self.object_data: - if _item: - _items.append(_item.to_dict()) - _dict["objectData"] = _items - if self.value: - _dict["value"] = self.value.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of PurchasedObjectIDs from a dict""" if obj is None: return None @@ -150,27 +114,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "eventName": obj.get("eventName"), - "eventType": obj.get("eventType"), - "eventSubtype": obj.get("eventSubtype"), - "index": obj.get("index"), - "objectIDs": obj.get("objectIDs"), - "userToken": obj.get("userToken"), - "authenticatedUserToken": obj.get("authenticatedUserToken"), - "currency": obj.get("currency"), - "objectData": ( - [ObjectData.from_dict(_item) for _item in obj.get("objectData")] - if obj.get("objectData") is not None - else None - ), - "timestamp": obj.get("timestamp"), - "value": ( - Value.from_dict(obj.get("value")) - if obj.get("value") is not None - else None - ), - } + obj["eventType"] = obj.get("eventType") + obj["eventSubtype"] = obj.get("eventSubtype") + obj["objectData"] = ( + [ObjectData.from_dict(_item) for _item in obj["objectData"]] + if obj.get("objectData") is not None + else None + ) + obj["value"] = ( + Value.from_dict(obj["value"]) if obj.get("value") is not None else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/insights/models/purchased_object_ids_after_search.py b/algoliasearch/insights/models/purchased_object_ids_after_search.py index 04ed8ca54..bb1f1dfba 100644 --- a/algoliasearch/insights/models/purchased_object_ids_after_search.py +++ b/algoliasearch/insights/models/purchased_object_ids_after_search.py @@ -11,12 +11,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.insights.models.conversion_event import ConversionEvent @@ -30,47 +30,27 @@ class PurchasedObjectIDsAfterSearch(BaseModel): Use this event to track when users make a purchase after a previous Algolia request. If you're building your category pages with Algolia, you'll also use this event. """ - event_name: Annotated[str, Field(min_length=1, strict=True, max_length=64)] = Field( - description="Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. ", - alias="eventName", - ) + event_name: str = Field(alias="eventName") + """ Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. """ event_type: ConversionEvent = Field(alias="eventType") event_subtype: PurchaseEvent = Field(alias="eventSubtype") - index: StrictStr = Field( - description="Index name (case-sensitive) to which the event's items belong." - ) - object_ids: Annotated[List[StrictStr], Field(min_length=1, max_length=20)] = Field( - description="Object IDs of the records that are part of the event.", - alias="objectIDs", - ) - user_token: Annotated[str, Field(min_length=1, strict=True, max_length=129)] = ( - Field( - description="Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - ) - authenticated_user_token: Optional[ - Annotated[str, Field(min_length=1, strict=True, max_length=129)] - ] = Field( - default=None, - description="Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="authenticatedUserToken", - ) - currency: Optional[StrictStr] = Field( - default=None, - description="Three-letter [currency code](https://www.iso.org/iso-4217-currency-codes.html).", + index: str = Field(alias="index") + """ Index name (case-sensitive) to which the event's items belong. """ + object_ids: List[str] = Field(alias="objectIDs") + """ Object IDs of the records that are part of the event. """ + user_token: str = Field(alias="userToken") + """ Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + authenticated_user_token: Optional[str] = Field( + default=None, alias="authenticatedUserToken" ) - object_data: Annotated[ - List[ObjectDataAfterSearch], Field(min_length=1, max_length=20) - ] = Field( - description="Extra information about the records involved in a purchase or add-to-cart events. If provided, it must be the same length as `objectIDs`. ", - alias="objectData", - ) - timestamp: Optional[StrictInt] = Field( - default=None, - description="Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. ", - ) - value: Optional[Value] = None + """ Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + currency: Optional[str] = Field(default=None, alias="currency") + """ Three-letter [currency code](https://www.iso.org/iso-4217-currency-codes.html). """ + object_data: List[ObjectDataAfterSearch] = Field(alias="objectData") + """ Extra information about the records involved in a purchase or add-to-cart events. If provided, it must be the same length as `objectIDs`. """ + timestamp: Optional[int] = Field(default=None, alias="timestamp") + """ Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. """ + value: Optional[Value] = Field(default=None, alias="value") @field_validator("event_name") def event_name_validate_regular_expression(cls, value): @@ -103,45 +83,30 @@ def authenticated_user_token_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of PurchasedObjectIDsAfterSearch from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.object_data: - for _item in self.object_data: - if _item: - _items.append(_item.to_dict()) - _dict["objectData"] = _items - if self.value: - _dict["value"] = self.value.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of PurchasedObjectIDsAfterSearch from a dict""" if obj is None: return None @@ -149,30 +114,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "eventName": obj.get("eventName"), - "eventType": obj.get("eventType"), - "eventSubtype": obj.get("eventSubtype"), - "index": obj.get("index"), - "objectIDs": obj.get("objectIDs"), - "userToken": obj.get("userToken"), - "authenticatedUserToken": obj.get("authenticatedUserToken"), - "currency": obj.get("currency"), - "objectData": ( - [ - ObjectDataAfterSearch.from_dict(_item) - for _item in obj.get("objectData") - ] - if obj.get("objectData") is not None - else None - ), - "timestamp": obj.get("timestamp"), - "value": ( - Value.from_dict(obj.get("value")) - if obj.get("value") is not None - else None - ), - } + obj["eventType"] = obj.get("eventType") + obj["eventSubtype"] = obj.get("eventSubtype") + obj["objectData"] = ( + [ObjectDataAfterSearch.from_dict(_item) for _item in obj["objectData"]] + if obj.get("objectData") is not None + else None + ) + obj["value"] = ( + Value.from_dict(obj["value"]) if obj.get("value") is not None else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/insights/models/value.py b/algoliasearch/insights/models/value.py index 4d7cd2814..6d8307184 100644 --- a/algoliasearch/insights/models/value.py +++ b/algoliasearch/insights/models/value.py @@ -8,16 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import ( - BaseModel, - StrictFloat, - StrictInt, - StrictStr, - ValidationError, - model_serializer, -) +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -30,9 +23,12 @@ class Value(BaseModel): Total monetary value of this event in units of `currency`. """ - oneof_schema_1_validator: Optional[Union[StrictFloat, StrictInt]] = None - oneof_schema_2_validator: Optional[StrictStr] = None + oneof_schema_1_validator: Optional[float] = Field(default=None) + + oneof_schema_2_validator: Optional[str] = Field(default=None) + actual_instance: Optional[Union[float, str]] = None + one_of_schemas: Set[str] = {"float", "str"} def __init__(self, *args, **kwargs) -> None: if args: @@ -56,7 +52,8 @@ def unwrap_actual_instance(self) -> Optional[Union[float, str]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of Value from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -90,17 +87,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], float, str]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/insights/models/viewed_filters.py b/algoliasearch/insights/models/viewed_filters.py index c2de36f2f..7ba9156c0 100644 --- a/algoliasearch/insights/models/viewed_filters.py +++ b/algoliasearch/insights/models/viewed_filters.py @@ -11,12 +11,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.insights.models.view_event import ViewEvent @@ -27,34 +27,21 @@ class ViewedFilters(BaseModel): Use this method to capture active filters. For example, when browsing a category page, users see content filtered on that specific category. """ - event_name: Annotated[str, Field(min_length=1, strict=True, max_length=64)] = Field( - description="Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. ", - alias="eventName", - ) + event_name: str = Field(alias="eventName") + """ Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. """ event_type: ViewEvent = Field(alias="eventType") - index: StrictStr = Field( - description="Index name (case-sensitive) to which the event's items belong." - ) - filters: Annotated[List[StrictStr], Field(min_length=1, max_length=20)] = Field( - description="Applied facet filters. Facet filters are `facet:value` pairs. Facet values must be URL-encoded, such as, `discount:10%25`. " - ) - user_token: Annotated[str, Field(min_length=1, strict=True, max_length=129)] = ( - Field( - description="Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - ) - authenticated_user_token: Optional[ - Annotated[str, Field(min_length=1, strict=True, max_length=129)] - ] = Field( - default=None, - description="Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="authenticatedUserToken", - ) - timestamp: Optional[StrictInt] = Field( - default=None, - description="Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. ", + index: str = Field(alias="index") + """ Index name (case-sensitive) to which the event's items belong. """ + filters: List[str] = Field(alias="filters") + """ Applied facet filters. Facet filters are `facet:value` pairs. Facet values must be URL-encoded, such as, `discount:10%25`. """ + user_token: str = Field(alias="userToken") + """ Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + authenticated_user_token: Optional[str] = Field( + default=None, alias="authenticatedUserToken" ) + """ Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + timestamp: Optional[int] = Field(default=None, alias="timestamp") + """ Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. """ @field_validator("event_name") def event_name_validate_regular_expression(cls, value): @@ -87,37 +74,30 @@ def authenticated_user_token_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ViewedFilters from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ViewedFilters from a dict""" if obj is None: return None @@ -125,15 +105,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "eventName": obj.get("eventName"), - "eventType": obj.get("eventType"), - "index": obj.get("index"), - "filters": obj.get("filters"), - "userToken": obj.get("userToken"), - "authenticatedUserToken": obj.get("authenticatedUserToken"), - "timestamp": obj.get("timestamp"), - } - ) - return _obj + obj["eventType"] = obj.get("eventType") + + return cls.model_validate(obj) diff --git a/algoliasearch/insights/models/viewed_object_ids.py b/algoliasearch/insights/models/viewed_object_ids.py index acbedc457..2fbda952e 100644 --- a/algoliasearch/insights/models/viewed_object_ids.py +++ b/algoliasearch/insights/models/viewed_object_ids.py @@ -11,12 +11,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.insights.models.view_event import ViewEvent @@ -27,35 +27,21 @@ class ViewedObjectIDs(BaseModel): Use this event to track when users viewed items in the search results. """ - event_name: Annotated[str, Field(min_length=1, strict=True, max_length=64)] = Field( - description="Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. ", - alias="eventName", - ) + event_name: str = Field(alias="eventName") + """ Event name, up to 64 ASCII characters. Consider naming events consistently—for example, by adopting Segment's [object-action](https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/#the-object-action-framework) framework. """ event_type: ViewEvent = Field(alias="eventType") - index: StrictStr = Field( - description="Index name (case-sensitive) to which the event's items belong." - ) - object_ids: Annotated[List[StrictStr], Field(min_length=1, max_length=20)] = Field( - description="Object IDs of the records that are part of the event.", - alias="objectIDs", - ) - user_token: Annotated[str, Field(min_length=1, strict=True, max_length=129)] = ( - Field( - description="Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - ) - authenticated_user_token: Optional[ - Annotated[str, Field(min_length=1, strict=True, max_length=129)] - ] = Field( - default=None, - description="Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="authenticatedUserToken", - ) - timestamp: Optional[StrictInt] = Field( - default=None, - description="Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. ", + index: str = Field(alias="index") + """ Index name (case-sensitive) to which the event's items belong. """ + object_ids: List[str] = Field(alias="objectIDs") + """ Object IDs of the records that are part of the event. """ + user_token: str = Field(alias="userToken") + """ Anonymous or pseudonymous user identifier. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + authenticated_user_token: Optional[str] = Field( + default=None, alias="authenticatedUserToken" ) + """ Identifier for authenticated users. When the user signs in, you can get an identifier from your system and send it as `authenticatedUserToken`. This lets you keep using the `userToken` from before the user signed in, while providing a reliable way to identify users across sessions. Don't use personally identifiable information in user tokens. For more information, see [User token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + timestamp: Optional[int] = Field(default=None, alias="timestamp") + """ Timestamp of the event, measured in milliseconds since the Unix epoch. By default, the Insights API uses the time it receives an event as its timestamp. """ @field_validator("event_name") def event_name_validate_regular_expression(cls, value): @@ -88,37 +74,30 @@ def authenticated_user_token_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ViewedObjectIDs from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ViewedObjectIDs from a dict""" if obj is None: return None @@ -126,15 +105,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "eventName": obj.get("eventName"), - "eventType": obj.get("eventType"), - "index": obj.get("index"), - "objectIDs": obj.get("objectIDs"), - "userToken": obj.get("userToken"), - "authenticatedUserToken": obj.get("authenticatedUserToken"), - "timestamp": obj.get("timestamp"), - } - ) - return _obj + obj["eventType"] = obj.get("eventType") + + return cls.model_validate(obj) diff --git a/algoliasearch/monitoring/client.py b/algoliasearch/monitoring/client.py index 910aa1408..170ed46e0 100644 --- a/algoliasearch/monitoring/client.py +++ b/algoliasearch/monitoring/client.py @@ -12,11 +12,12 @@ from urllib.parse import quote from pydantic import Field, StrictStr +from typing_extensions import Annotated if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.http.api_response import ApiResponse from algoliasearch.http.request_options import RequestOptions diff --git a/algoliasearch/monitoring/models/error_base.py b/algoliasearch/monitoring/models/error_base.py index 4317b330d..075d8a3ac 100644 --- a/algoliasearch/monitoring/models/error_base.py +++ b/algoliasearch/monitoring/models/error_base.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, ClassVar, Dict, List, Optional +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,50 +23,34 @@ class ErrorBase(BaseModel): Error. """ - message: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["message"] + message: Optional[str] = Field(default=None, alias="message") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + extra="allow", ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ErrorBase from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={ - "additional_properties", - }, exclude_none=True, exclude_unset=True, ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ErrorBase from a dict""" if obj is None: return None @@ -74,10 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"message": obj.get("message")}) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/monitoring/models/incident.py b/algoliasearch/monitoring/models/incident.py index 5fb7dd488..e8ab1f79a 100644 --- a/algoliasearch/monitoring/models/incident.py +++ b/algoliasearch/monitoring/models/incident.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,43 +26,35 @@ class Incident(BaseModel): Incident details. """ - title: Optional[StrictStr] = Field( - default=None, description="Description of the incident." - ) - status: Optional[Status] = None + title: Optional[str] = Field(default=None, alias="title") + """ Description of the incident. """ + status: Optional[Status] = Field(default=None, alias="status") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Incident from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Incident from a dict""" if obj is None: return None @@ -70,7 +62,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"title": obj.get("title"), "status": obj.get("status")} - ) - return _obj + obj["status"] = obj.get("status") + + return cls.model_validate(obj) diff --git a/algoliasearch/monitoring/models/incident_entry.py b/algoliasearch/monitoring/models/incident_entry.py index 9df250c23..cf4b608f0 100644 --- a/algoliasearch/monitoring/models/incident_entry.py +++ b/algoliasearch/monitoring/models/incident_entry.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,46 +26,35 @@ class IncidentEntry(BaseModel): IncidentEntry """ - t: Optional[StrictInt] = Field( - default=None, - description="Timestamp, measured in milliseconds since the Unix epoch.", - ) - v: Optional[Incident] = None + t: Optional[int] = Field(default=None, alias="t") + """ Timestamp, measured in milliseconds since the Unix epoch. """ + v: Optional[Incident] = Field(default=None, alias="v") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of IncidentEntry from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.v: - _dict["v"] = self.v.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of IncidentEntry from a dict""" if obj is None: return None @@ -73,14 +62,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "t": obj.get("t"), - "v": ( - Incident.from_dict(obj.get("v")) - if obj.get("v") is not None - else None - ), - } - ) - return _obj + obj["v"] = Incident.from_dict(obj["v"]) if obj.get("v") is not None else None + + return cls.model_validate(obj) diff --git a/algoliasearch/monitoring/models/incidents_response.py b/algoliasearch/monitoring/models/incidents_response.py index 96e90e7ab..026891439 100644 --- a/algoliasearch/monitoring/models/incidents_response.py +++ b/algoliasearch/monitoring/models/incidents_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,48 +26,35 @@ class IncidentsResponse(BaseModel): IncidentsResponse """ - incidents: Optional[Dict[str, List[IncidentEntry]]] = None + incidents: Optional[Dict[str, List[IncidentEntry]]] = Field( + default=None, alias="incidents" + ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of IncidentsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _field_dict_of_array = {} - if self.incidents: - for _key in self.incidents: - if self.incidents[_key] is not None: - _field_dict_of_array[_key] = [ - _item.to_dict() for _item in self.incidents[_key] - ] - _dict["incidents"] = _field_dict_of_array - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of IncidentsResponse from a dict""" if obj is None: return None @@ -75,17 +62,14 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "incidents": dict( - ( - _k, - [IncidentEntry.from_dict(_item) for _item in _v] - if _v is not None - else None, - ) - for _k, _v in obj.get("incidents").items() - ) - } + obj["incidents"] = dict( + ( + _k, + [IncidentEntry.from_dict(_item) for _item in _v] + if _v is not None + else None, + ) + for _k, _v in obj.get("incidents", {}).items() ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/monitoring/models/indexing_metric.py b/algoliasearch/monitoring/models/indexing_metric.py index 661994240..3f0118f29 100644 --- a/algoliasearch/monitoring/models/indexing_metric.py +++ b/algoliasearch/monitoring/models/indexing_metric.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,48 +26,35 @@ class IndexingMetric(BaseModel): IndexingMetric """ - indexing: Optional[Dict[str, List[TimeEntry]]] = None + indexing: Optional[Dict[str, List[TimeEntry]]] = Field( + default=None, alias="indexing" + ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of IndexingMetric from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _field_dict_of_array = {} - if self.indexing: - for _key in self.indexing: - if self.indexing[_key] is not None: - _field_dict_of_array[_key] = [ - _item.to_dict() for _item in self.indexing[_key] - ] - _dict["indexing"] = _field_dict_of_array - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of IndexingMetric from a dict""" if obj is None: return None @@ -75,17 +62,14 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "indexing": dict( - ( - _k, - [TimeEntry.from_dict(_item) for _item in _v] - if _v is not None - else None, - ) - for _k, _v in obj.get("indexing").items() - ) - } + obj["indexing"] = dict( + ( + _k, + [TimeEntry.from_dict(_item) for _item in _v] + if _v is not None + else None, + ) + for _k, _v in obj.get("indexing", {}).items() ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/monitoring/models/indexing_time_response.py b/algoliasearch/monitoring/models/indexing_time_response.py index d76adbe92..0a08746fa 100644 --- a/algoliasearch/monitoring/models/indexing_time_response.py +++ b/algoliasearch/monitoring/models/indexing_time_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,42 +26,33 @@ class IndexingTimeResponse(BaseModel): IndexingTimeResponse """ - metrics: Optional[IndexingMetric] = None + metrics: Optional[IndexingMetric] = Field(default=None, alias="metrics") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of IndexingTimeResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.metrics: - _dict["metrics"] = self.metrics.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of IndexingTimeResponse from a dict""" if obj is None: return None @@ -69,13 +60,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "metrics": ( - IndexingMetric.from_dict(obj.get("metrics")) - if obj.get("metrics") is not None - else None - ) - } + obj["metrics"] = ( + IndexingMetric.from_dict(obj["metrics"]) + if obj.get("metrics") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/monitoring/models/infrastructure_response.py b/algoliasearch/monitoring/models/infrastructure_response.py index 59be547d1..1c3bb417d 100644 --- a/algoliasearch/monitoring/models/infrastructure_response.py +++ b/algoliasearch/monitoring/models/infrastructure_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,42 +26,33 @@ class InfrastructureResponse(BaseModel): InfrastructureResponse """ - metrics: Optional[Metrics] = None + metrics: Optional[Metrics] = Field(default=None, alias="metrics") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of InfrastructureResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.metrics: - _dict["metrics"] = self.metrics.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of InfrastructureResponse from a dict""" if obj is None: return None @@ -69,13 +60,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "metrics": ( - Metrics.from_dict(obj.get("metrics")) - if obj.get("metrics") is not None - else None - ) - } + obj["metrics"] = ( + Metrics.from_dict(obj["metrics"]) + if obj.get("metrics") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/monitoring/models/inventory_response.py b/algoliasearch/monitoring/models/inventory_response.py index 1fabaa9ab..5d4b0b214 100644 --- a/algoliasearch/monitoring/models/inventory_response.py +++ b/algoliasearch/monitoring/models/inventory_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,46 +26,33 @@ class InventoryResponse(BaseModel): InventoryResponse """ - inventory: Optional[List[Server]] = None + inventory: Optional[List[Server]] = Field(default=None, alias="inventory") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of InventoryResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.inventory: - for _item in self.inventory: - if _item: - _items.append(_item.to_dict()) - _dict["inventory"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of InventoryResponse from a dict""" if obj is None: return None @@ -73,13 +60,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "inventory": ( - [Server.from_dict(_item) for _item in obj.get("inventory")] - if obj.get("inventory") is not None - else None - ) - } + obj["inventory"] = ( + [Server.from_dict(_item) for _item in obj["inventory"]] + if obj.get("inventory") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/monitoring/models/latency_metric.py b/algoliasearch/monitoring/models/latency_metric.py index fceb239ec..5ebc98c9e 100644 --- a/algoliasearch/monitoring/models/latency_metric.py +++ b/algoliasearch/monitoring/models/latency_metric.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,48 +26,33 @@ class LatencyMetric(BaseModel): LatencyMetric """ - latency: Optional[Dict[str, List[TimeEntry]]] = None + latency: Optional[Dict[str, List[TimeEntry]]] = Field(default=None, alias="latency") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of LatencyMetric from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _field_dict_of_array = {} - if self.latency: - for _key in self.latency: - if self.latency[_key] is not None: - _field_dict_of_array[_key] = [ - _item.to_dict() for _item in self.latency[_key] - ] - _dict["latency"] = _field_dict_of_array - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of LatencyMetric from a dict""" if obj is None: return None @@ -75,17 +60,14 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "latency": dict( - ( - _k, - [TimeEntry.from_dict(_item) for _item in _v] - if _v is not None - else None, - ) - for _k, _v in obj.get("latency").items() - ) - } + obj["latency"] = dict( + ( + _k, + [TimeEntry.from_dict(_item) for _item in _v] + if _v is not None + else None, + ) + for _k, _v in obj.get("latency", {}).items() ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/monitoring/models/latency_response.py b/algoliasearch/monitoring/models/latency_response.py index 17fdf3b5f..53d739922 100644 --- a/algoliasearch/monitoring/models/latency_response.py +++ b/algoliasearch/monitoring/models/latency_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,42 +26,33 @@ class LatencyResponse(BaseModel): LatencyResponse """ - metrics: Optional[LatencyMetric] = None + metrics: Optional[LatencyMetric] = Field(default=None, alias="metrics") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of LatencyResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.metrics: - _dict["metrics"] = self.metrics.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of LatencyResponse from a dict""" if obj is None: return None @@ -69,13 +60,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "metrics": ( - LatencyMetric.from_dict(obj.get("metrics")) - if obj.get("metrics") is not None - else None - ) - } + obj["metrics"] = ( + LatencyMetric.from_dict(obj["metrics"]) + if obj.get("metrics") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/monitoring/models/metric.py b/algoliasearch/monitoring/models/metric.py index 0af500186..c76aeeaa7 100644 --- a/algoliasearch/monitoring/models/metric.py +++ b/algoliasearch/monitoring/models/metric.py @@ -25,10 +25,15 @@ class Metric(str, Enum): allowed enum values """ AVG_BUILD_TIME = "avg_build_time" + SSD_USAGE = "ssd_usage" + RAM_SEARCH_USAGE = "ram_search_usage" + RAM_INDEXING_USAGE = "ram_indexing_usage" + CPU_USAGE = "cpu_usage" + STAR = "*" @classmethod diff --git a/algoliasearch/monitoring/models/metrics.py b/algoliasearch/monitoring/models/metrics.py index d523b6758..8608de724 100644 --- a/algoliasearch/monitoring/models/metrics.py +++ b/algoliasearch/monitoring/models/metrics.py @@ -27,94 +27,51 @@ class Metrics(BaseModel): """ cpu_usage: Optional[Dict[str, List[ProbesMetric]]] = Field( - default=None, description="CPU idleness in %." + default=None, alias="cpu_usage" ) + """ CPU idleness in %. """ ram_indexing_usage: Optional[Dict[str, List[ProbesMetric]]] = Field( - default=None, description="RAM used for indexing in MB." + default=None, alias="ram_indexing_usage" ) + """ RAM used for indexing in MB. """ ram_search_usage: Optional[Dict[str, List[ProbesMetric]]] = Field( - default=None, description="RAM used for search in MB." + default=None, alias="ram_search_usage" ) + """ RAM used for search in MB. """ ssd_usage: Optional[Dict[str, List[ProbesMetric]]] = Field( - default=None, - description="Solid-state disk (SSD) usage expressed as % of RAM. 0% means no SSD usage. A value of 50% indicates 32 GB SSD usage for a machine with 64 RAM. ", + default=None, alias="ssd_usage" ) + """ Solid-state disk (SSD) usage expressed as % of RAM. 0% means no SSD usage. A value of 50% indicates 32 GB SSD usage for a machine with 64 RAM. """ avg_build_time: Optional[Dict[str, List[ProbesMetric]]] = Field( - default=None, description="Average build time of the indices in seconds." + default=None, alias="avg_build_time" ) + """ Average build time of the indices in seconds. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Metrics from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _field_dict_of_array = {} - if self.cpu_usage: - for _key in self.cpu_usage: - if self.cpu_usage[_key] is not None: - _field_dict_of_array[_key] = [ - _item.to_dict() for _item in self.cpu_usage[_key] - ] - _dict["cpu_usage"] = _field_dict_of_array - _field_dict_of_array = {} - if self.ram_indexing_usage: - for _key in self.ram_indexing_usage: - if self.ram_indexing_usage[_key] is not None: - _field_dict_of_array[_key] = [ - _item.to_dict() for _item in self.ram_indexing_usage[_key] - ] - _dict["ram_indexing_usage"] = _field_dict_of_array - _field_dict_of_array = {} - if self.ram_search_usage: - for _key in self.ram_search_usage: - if self.ram_search_usage[_key] is not None: - _field_dict_of_array[_key] = [ - _item.to_dict() for _item in self.ram_search_usage[_key] - ] - _dict["ram_search_usage"] = _field_dict_of_array - _field_dict_of_array = {} - if self.ssd_usage: - for _key in self.ssd_usage: - if self.ssd_usage[_key] is not None: - _field_dict_of_array[_key] = [ - _item.to_dict() for _item in self.ssd_usage[_key] - ] - _dict["ssd_usage"] = _field_dict_of_array - _field_dict_of_array = {} - if self.avg_build_time: - for _key in self.avg_build_time: - if self.avg_build_time[_key] is not None: - _field_dict_of_array[_key] = [ - _item.to_dict() for _item in self.avg_build_time[_key] - ] - _dict["avg_build_time"] = _field_dict_of_array - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Metrics from a dict""" if obj is None: return None @@ -122,53 +79,50 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "cpu_usage": dict( - ( - _k, - [ProbesMetric.from_dict(_item) for _item in _v] - if _v is not None - else None, - ) - for _k, _v in obj.get("cpu_usage").items() - ), - "ram_indexing_usage": dict( - ( - _k, - [ProbesMetric.from_dict(_item) for _item in _v] - if _v is not None - else None, - ) - for _k, _v in obj.get("ram_indexing_usage").items() - ), - "ram_search_usage": dict( - ( - _k, - [ProbesMetric.from_dict(_item) for _item in _v] - if _v is not None - else None, - ) - for _k, _v in obj.get("ram_search_usage").items() - ), - "ssd_usage": dict( - ( - _k, - [ProbesMetric.from_dict(_item) for _item in _v] - if _v is not None - else None, - ) - for _k, _v in obj.get("ssd_usage").items() - ), - "avg_build_time": dict( - ( - _k, - [ProbesMetric.from_dict(_item) for _item in _v] - if _v is not None - else None, - ) - for _k, _v in obj.get("avg_build_time").items() - ), - } + obj["cpu_usage"] = dict( + ( + _k, + [ProbesMetric.from_dict(_item) for _item in _v] + if _v is not None + else None, + ) + for _k, _v in obj.get("cpu_usage", {}).items() + ) + obj["ram_indexing_usage"] = dict( + ( + _k, + [ProbesMetric.from_dict(_item) for _item in _v] + if _v is not None + else None, + ) + for _k, _v in obj.get("ram_indexing_usage", {}).items() + ) + obj["ram_search_usage"] = dict( + ( + _k, + [ProbesMetric.from_dict(_item) for _item in _v] + if _v is not None + else None, + ) + for _k, _v in obj.get("ram_search_usage", {}).items() ) - return _obj + obj["ssd_usage"] = dict( + ( + _k, + [ProbesMetric.from_dict(_item) for _item in _v] + if _v is not None + else None, + ) + for _k, _v in obj.get("ssd_usage", {}).items() + ) + obj["avg_build_time"] = dict( + ( + _k, + [ProbesMetric.from_dict(_item) for _item in _v] + if _v is not None + else None, + ) + for _k, _v in obj.get("avg_build_time", {}).items() + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/monitoring/models/period.py b/algoliasearch/monitoring/models/period.py index 11b4ac50d..c1611fe51 100644 --- a/algoliasearch/monitoring/models/period.py +++ b/algoliasearch/monitoring/models/period.py @@ -25,9 +25,13 @@ class Period(str, Enum): allowed enum values """ MINUTE = "minute" + HOUR = "hour" + DAY = "day" + WEEK = "week" + MONTH = "month" @classmethod diff --git a/algoliasearch/monitoring/models/probes_metric.py b/algoliasearch/monitoring/models/probes_metric.py index d6dce4219..c7af87106 100644 --- a/algoliasearch/monitoring/models/probes_metric.py +++ b/algoliasearch/monitoring/models/probes_metric.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,44 +23,36 @@ class ProbesMetric(BaseModel): ProbesMetric """ - t: Optional[StrictInt] = Field( - default=None, - description="Timestamp, measured in milliseconds since the Unix epoch.", - ) - v: Optional[StrictInt] = Field(default=None, description="Value of the metric.") + t: Optional[int] = Field(default=None, alias="t") + """ Timestamp, measured in milliseconds since the Unix epoch. """ + v: Optional[int] = Field(default=None, alias="v") + """ Value of the metric. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ProbesMetric from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ProbesMetric from a dict""" if obj is None: return None @@ -68,5 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"t": obj.get("t"), "v": obj.get("v")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/monitoring/models/region.py b/algoliasearch/monitoring/models/region.py index e39af0155..8e8326390 100644 --- a/algoliasearch/monitoring/models/region.py +++ b/algoliasearch/monitoring/models/region.py @@ -25,19 +25,33 @@ class Region(str, Enum): allowed enum values """ AU = "au" + BR = "br" + CA = "ca" + DE = "de" + EU = "eu" + HK = "hk" + IN = "in" + JP = "jp" + SG = "sg" + UAE = "uae" + UK = "uk" + USC = "usc" + USE = "use" + USW = "usw" + ZA = "za" @classmethod diff --git a/algoliasearch/monitoring/models/server.py b/algoliasearch/monitoring/models/server.py index 7a4bf878f..ec0e3e9e4 100644 --- a/algoliasearch/monitoring/models/server.py +++ b/algoliasearch/monitoring/models/server.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,53 +28,43 @@ class Server(BaseModel): Server """ - name: Optional[StrictStr] = Field(default=None, description="Server name.") - region: Optional[Region] = None - is_slave: Optional[StrictBool] = Field( - default=False, - description="Included to support legacy applications. Use `is_replica` instead. ", - ) - is_replica: Optional[StrictBool] = Field( - default=False, description="Whether this server is a replica of another server." - ) - cluster: Optional[StrictStr] = Field( - default=None, description="Name of the cluster to which this server belongs." - ) - status: Optional[ServerStatus] = None - type: Optional[Type] = None + name: Optional[str] = Field(default=None, alias="name") + """ Server name. """ + region: Optional[Region] = Field(default=None, alias="region") + is_slave: Optional[bool] = Field(default=None, alias="is_slave") + """ Included to support legacy applications. Use `is_replica` instead. """ + is_replica: Optional[bool] = Field(default=None, alias="is_replica") + """ Whether this server is a replica of another server. """ + cluster: Optional[str] = Field(default=None, alias="cluster") + """ Name of the cluster to which this server belongs. """ + status: Optional[ServerStatus] = Field(default=None, alias="status") + type: Optional[Type] = Field(default=None, alias="type") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Server from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Server from a dict""" if obj is None: return None @@ -82,15 +72,8 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "name": obj.get("name"), - "region": obj.get("region"), - "is_slave": obj.get("is_slave"), - "is_replica": obj.get("is_replica"), - "cluster": obj.get("cluster"), - "status": obj.get("status"), - "type": obj.get("type"), - } - ) - return _obj + obj["region"] = obj.get("region") + obj["status"] = obj.get("status") + obj["type"] = obj.get("type") + + return cls.model_validate(obj) diff --git a/algoliasearch/monitoring/models/status.py b/algoliasearch/monitoring/models/status.py index 9e17273a6..b8fc1769b 100644 --- a/algoliasearch/monitoring/models/status.py +++ b/algoliasearch/monitoring/models/status.py @@ -25,8 +25,11 @@ class Status(str, Enum): allowed enum values """ OPERATIONAL = "operational" + DEGRADED_PERFORMANCE = "degraded_performance" + PARTIAL_OUTAGE = "partial_outage" + MAJOR_OUTAGE = "major_outage" @classmethod diff --git a/algoliasearch/monitoring/models/status_response.py b/algoliasearch/monitoring/models/status_response.py index 519e6e262..29fa453c1 100644 --- a/algoliasearch/monitoring/models/status_response.py +++ b/algoliasearch/monitoring/models/status_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,40 +26,33 @@ class StatusResponse(BaseModel): StatusResponse """ - status: Optional[Dict[str, Status]] = None + status: Optional[Dict[str, Status]] = Field(default=None, alias="status") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of StatusResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of StatusResponse from a dict""" if obj is None: return None @@ -67,7 +60,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"status": dict((_k, _v) for _k, _v in obj.get("status").items())} - ) - return _obj + obj["status"] = dict((_k, _v) for _k, _v in obj.get("status").items()) + + return cls.model_validate(obj) diff --git a/algoliasearch/monitoring/models/time_entry.py b/algoliasearch/monitoring/models/time_entry.py index 26676a883..f625f53f0 100644 --- a/algoliasearch/monitoring/models/time_entry.py +++ b/algoliasearch/monitoring/models/time_entry.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,44 +23,36 @@ class TimeEntry(BaseModel): TimeEntry """ - t: Optional[StrictInt] = Field( - default=None, - description="Timestamp, measured in milliseconds since the Unix epoch.", - ) - v: Optional[StrictInt] = Field(default=None, description="Time in ms.") + t: Optional[int] = Field(default=None, alias="t") + """ Timestamp, measured in milliseconds since the Unix epoch. """ + v: Optional[int] = Field(default=None, alias="v") + """ Time in ms. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TimeEntry from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TimeEntry from a dict""" if obj is None: return None @@ -68,5 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"t": obj.get("t"), "v": obj.get("v")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/personalization/client.py b/algoliasearch/personalization/client.py index 6dc786d35..1bcdc401f 100644 --- a/algoliasearch/personalization/client.py +++ b/algoliasearch/personalization/client.py @@ -12,11 +12,12 @@ from urllib.parse import quote from pydantic import Field, StrictStr +from typing_extensions import Annotated if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.http.api_response import ApiResponse from algoliasearch.http.request_options import RequestOptions diff --git a/algoliasearch/personalization/models/delete_user_profile_response.py b/algoliasearch/personalization/models/delete_user_profile_response.py index f6f0de675..5d21f8edc 100644 --- a/algoliasearch/personalization/models/delete_user_profile_response.py +++ b/algoliasearch/personalization/models/delete_user_profile_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,47 +23,36 @@ class DeleteUserProfileResponse(BaseModel): DeleteUserProfileResponse """ - user_token: StrictStr = Field( - description="Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - deleted_until: StrictStr = Field( - description="Date and time when the user profile can be safely considered to be deleted. Any events received after the `deletedUntil` date start a new user profile. ", - alias="deletedUntil", - ) + user_token: str = Field(alias="userToken") + """ Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + deleted_until: str = Field(alias="deletedUntil") + """ Date and time when the user profile can be safely considered to be deleted. Any events received after the `deletedUntil` date start a new user profile. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DeleteUserProfileResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DeleteUserProfileResponse from a dict""" if obj is None: return None @@ -71,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"userToken": obj.get("userToken"), "deletedUntil": obj.get("deletedUntil")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/personalization/models/error_base.py b/algoliasearch/personalization/models/error_base.py index 4317b330d..075d8a3ac 100644 --- a/algoliasearch/personalization/models/error_base.py +++ b/algoliasearch/personalization/models/error_base.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, ClassVar, Dict, List, Optional +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,50 +23,34 @@ class ErrorBase(BaseModel): Error. """ - message: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["message"] + message: Optional[str] = Field(default=None, alias="message") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + extra="allow", ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ErrorBase from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={ - "additional_properties", - }, exclude_none=True, exclude_unset=True, ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ErrorBase from a dict""" if obj is None: return None @@ -74,10 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"message": obj.get("message")}) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/personalization/models/event_scoring.py b/algoliasearch/personalization/models/event_scoring.py index ff877593e..ab675db4c 100644 --- a/algoliasearch/personalization/models/event_scoring.py +++ b/algoliasearch/personalization/models/event_scoring.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,42 +26,37 @@ class EventScoring(BaseModel): EventScoring """ - score: StrictInt = Field(description="Event score.") - event_name: StrictStr = Field(description="Event name.", alias="eventName") + score: int = Field(alias="score") + """ Event score. """ + event_name: str = Field(alias="eventName") + """ Event name. """ event_type: EventType = Field(alias="eventType") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of EventScoring from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of EventScoring from a dict""" if obj is None: return None @@ -69,11 +64,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "score": obj.get("score"), - "eventName": obj.get("eventName"), - "eventType": obj.get("eventType"), - } - ) - return _obj + obj["eventType"] = obj.get("eventType") + + return cls.model_validate(obj) diff --git a/algoliasearch/personalization/models/event_type.py b/algoliasearch/personalization/models/event_type.py index a3870c320..be105291f 100644 --- a/algoliasearch/personalization/models/event_type.py +++ b/algoliasearch/personalization/models/event_type.py @@ -25,7 +25,9 @@ class EventType(str, Enum): allowed enum values """ CLICK = "click" + CONVERSION = "conversion" + VIEW = "view" @classmethod diff --git a/algoliasearch/personalization/models/facet_scoring.py b/algoliasearch/personalization/models/facet_scoring.py index 1b144edec..88aa045a2 100644 --- a/algoliasearch/personalization/models/facet_scoring.py +++ b/algoliasearch/personalization/models/facet_scoring.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,36 @@ class FacetScoring(BaseModel): FacetScoring """ - score: StrictInt = Field(description="Event score.") - facet_name: StrictStr = Field( - description="Facet attribute name.", alias="facetName" - ) + score: int = Field(alias="score") + """ Event score. """ + facet_name: str = Field(alias="facetName") + """ Facet attribute name. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of FacetScoring from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of FacetScoring from a dict""" if obj is None: return None @@ -67,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"score": obj.get("score"), "facetName": obj.get("facetName")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/personalization/models/get_user_token_response.py b/algoliasearch/personalization/models/get_user_token_response.py index 7f219d6a3..973c54f87 100644 --- a/algoliasearch/personalization/models/get_user_token_response.py +++ b/algoliasearch/personalization/models/get_user_token_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,50 +23,38 @@ class GetUserTokenResponse(BaseModel): GetUserTokenResponse """ - user_token: StrictStr = Field( - description="Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - last_event_at: StrictStr = Field( - description="Date and time of the last event from this user, in RFC 3339 format.", - alias="lastEventAt", - ) - scores: Dict[str, Any] = Field( - description="Scores for different facet values. Scores represent the user affinity for a user profile towards specific facet values, given the personalization strategy and past events. " - ) + user_token: str = Field(alias="userToken") + """ Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + last_event_at: str = Field(alias="lastEventAt") + """ Date and time of the last event from this user, in RFC 3339 format. """ + scores: object = Field(alias="scores") + """ Scores for different facet values. Scores represent the user affinity for a user profile towards specific facet values, given the personalization strategy and past events. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetUserTokenResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetUserTokenResponse from a dict""" if obj is None: return None @@ -74,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "userToken": obj.get("userToken"), - "lastEventAt": obj.get("lastEventAt"), - "scores": obj.get("scores"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/personalization/models/personalization_strategy_params.py b/algoliasearch/personalization/models/personalization_strategy_params.py index 0c5c460e3..f2586796b 100644 --- a/algoliasearch/personalization/models/personalization_strategy_params.py +++ b/algoliasearch/personalization/models/personalization_strategy_params.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.personalization.models.event_scoring import EventScoring @@ -27,63 +27,38 @@ class PersonalizationStrategyParams(BaseModel): PersonalizationStrategyParams """ - event_scoring: List[EventScoring] = Field( - description="Scores associated with each event. The higher the scores, the higher the impact of those events on the personalization of search results. ", - alias="eventScoring", - ) - facet_scoring: List[FacetScoring] = Field( - description="Scores associated with each facet. The higher the scores, the higher the impact of those events on the personalization of search results. ", - alias="facetScoring", - ) - personalization_impact: Annotated[int, Field(le=100, strict=True, ge=0)] = Field( - description="Impact of personalization on the search results. If set to 0, personalization has no impact on the search results. ", - alias="personalizationImpact", - ) + event_scoring: List[EventScoring] = Field(alias="eventScoring") + """ Scores associated with each event. The higher the scores, the higher the impact of those events on the personalization of search results. """ + facet_scoring: List[FacetScoring] = Field(alias="facetScoring") + """ Scores associated with each facet. The higher the scores, the higher the impact of those events on the personalization of search results. """ + personalization_impact: int = Field(alias="personalizationImpact") + """ Impact of personalization on the search results. If set to 0, personalization has no impact on the search results. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of PersonalizationStrategyParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.event_scoring: - for _item in self.event_scoring: - if _item: - _items.append(_item.to_dict()) - _dict["eventScoring"] = _items - _items = [] - if self.facet_scoring: - for _item in self.facet_scoring: - if _item: - _items.append(_item.to_dict()) - _dict["facetScoring"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of PersonalizationStrategyParams from a dict""" if obj is None: return None @@ -91,19 +66,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "eventScoring": ( - [EventScoring.from_dict(_item) for _item in obj.get("eventScoring")] - if obj.get("eventScoring") is not None - else None - ), - "facetScoring": ( - [FacetScoring.from_dict(_item) for _item in obj.get("facetScoring")] - if obj.get("facetScoring") is not None - else None - ), - "personalizationImpact": obj.get("personalizationImpact"), - } + obj["eventScoring"] = ( + [EventScoring.from_dict(_item) for _item in obj["eventScoring"]] + if obj.get("eventScoring") is not None + else None + ) + obj["facetScoring"] = ( + [FacetScoring.from_dict(_item) for _item in obj["facetScoring"]] + if obj.get("facetScoring") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/personalization/models/set_personalization_strategy_response.py b/algoliasearch/personalization/models/set_personalization_strategy_response.py index 9474a0a82..529cbb371 100644 --- a/algoliasearch/personalization/models/set_personalization_strategy_response.py +++ b/algoliasearch/personalization/models/set_personalization_strategy_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,40 +23,34 @@ class SetPersonalizationStrategyResponse(BaseModel): SetPersonalizationStrategyResponse """ - message: StrictStr = Field(description="A message confirming the strategy update.") + message: str = Field(alias="message") + """ A message confirming the strategy update. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SetPersonalizationStrategyResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SetPersonalizationStrategyResponse from a dict""" if obj is None: return None @@ -64,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"message": obj.get("message")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/query_suggestions/client.py b/algoliasearch/query_suggestions/client.py index 1ae4a6137..3b065b7e6 100644 --- a/algoliasearch/query_suggestions/client.py +++ b/algoliasearch/query_suggestions/client.py @@ -12,11 +12,12 @@ from urllib.parse import quote from pydantic import Field, StrictStr +from typing_extensions import Annotated if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.http.api_response import ApiResponse from algoliasearch.http.request_options import RequestOptions diff --git a/algoliasearch/query_suggestions/models/base_response.py b/algoliasearch/query_suggestions/models/base_response.py index b9059e459..3c6847db1 100644 --- a/algoliasearch/query_suggestions/models/base_response.py +++ b/algoliasearch/query_suggestions/models/base_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,36 @@ class BaseResponse(BaseModel): BaseResponse """ - status: Optional[StrictInt] = Field(default=None, description="HTTP status code.") - message: Optional[StrictStr] = Field( - default=None, description="Details about the response, such as error messages." - ) + status: Optional[int] = Field(default=None, alias="status") + """ HTTP status code. """ + message: Optional[str] = Field(default=None, alias="message") + """ Details about the response, such as error messages. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of BaseResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of BaseResponse from a dict""" if obj is None: return None @@ -67,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"status": obj.get("status"), "message": obj.get("message")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/query_suggestions/models/config_status.py b/algoliasearch/query_suggestions/models/config_status.py index 7b85d405c..db3818e15 100644 --- a/algoliasearch/query_suggestions/models/config_status.py +++ b/algoliasearch/query_suggestions/models/config_status.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,64 +23,46 @@ class ConfigStatus(BaseModel): ConfigStatus """ - index_name: Optional[StrictStr] = Field( - default=None, - description="Name of the Query Suggestions index (case-sensitive).", - alias="indexName", + index_name: Optional[str] = Field(default=None, alias="indexName") + """ Name of the Query Suggestions index (case-sensitive). """ + is_running: Optional[bool] = Field(default=None, alias="isRunning") + """ Whether the creation or update of the Query Suggestions index is in progress. """ + last_built_at: Optional[str] = Field(default=None, alias="lastBuiltAt") + """ Date and time when the Query Suggestions index was last built, in RFC 3339 format. """ + last_successful_built_at: Optional[str] = Field( + default=None, alias="lastSuccessfulBuiltAt" ) - is_running: Optional[StrictBool] = Field( - default=None, - description="Whether the creation or update of the Query Suggestions index is in progress.", - alias="isRunning", - ) - last_built_at: Optional[StrictStr] = Field( - default=None, - description="Date and time when the Query Suggestions index was last built, in RFC 3339 format.", - alias="lastBuiltAt", - ) - last_successful_built_at: Optional[StrictStr] = Field( - default=None, - description="Date and time when the Query Suggestions index was last updated successfully.", - alias="lastSuccessfulBuiltAt", - ) - last_successful_build_duration: Optional[StrictStr] = Field( - default=None, - description="Duration of the last successful build in seconds.", - alias="lastSuccessfulBuildDuration", + """ Date and time when the Query Suggestions index was last updated successfully. """ + last_successful_build_duration: Optional[str] = Field( + default=None, alias="lastSuccessfulBuildDuration" ) + """ Duration of the last successful build in seconds. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ConfigStatus from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ConfigStatus from a dict""" if obj is None: return None @@ -88,13 +70,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "indexName": obj.get("indexName"), - "isRunning": obj.get("isRunning"), - "lastBuiltAt": obj.get("lastBuiltAt"), - "lastSuccessfulBuiltAt": obj.get("lastSuccessfulBuiltAt"), - "lastSuccessfulBuildDuration": obj.get("lastSuccessfulBuildDuration"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/query_suggestions/models/configuration.py b/algoliasearch/query_suggestions/models/configuration.py index e82df1405..072f83301 100644 --- a/algoliasearch/query_suggestions/models/configuration.py +++ b/algoliasearch/query_suggestions/models/configuration.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.query_suggestions.models.languages import Languages @@ -27,63 +27,44 @@ class Configuration(BaseModel): Query Suggestions configuration. """ - source_indices: Annotated[List[SourceIndex], Field(min_length=1)] = Field( - description="Algolia indices from which to get the popular searches for query suggestions.", - alias="sourceIndices", + source_indices: List[SourceIndex] = Field(alias="sourceIndices") + """ Algolia indices from which to get the popular searches for query suggestions. """ + languages: Optional[Languages] = Field(default=None, alias="languages") + exclude: Optional[List[str]] = Field(default=None, alias="exclude") + enable_personalization: Optional[bool] = Field( + default=None, alias="enablePersonalization" ) - languages: Optional[Languages] = None - exclude: Optional[List[StrictStr]] = None - enable_personalization: Optional[StrictBool] = Field( - default=False, - description="Whether to turn on personalized query suggestions.", - alias="enablePersonalization", - ) - allow_special_characters: Optional[StrictBool] = Field( - default=False, - description="Whether to include suggestions with special characters.", - alias="allowSpecialCharacters", + """ Whether to turn on personalized query suggestions. """ + allow_special_characters: Optional[bool] = Field( + default=None, alias="allowSpecialCharacters" ) + """ Whether to include suggestions with special characters. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Configuration from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.source_indices: - for _item in self.source_indices: - if _item: - _items.append(_item.to_dict()) - _dict["sourceIndices"] = _items - if self.languages: - _dict["languages"] = self.languages.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Configuration from a dict""" if obj is None: return None @@ -91,21 +72,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "sourceIndices": ( - [SourceIndex.from_dict(_item) for _item in obj.get("sourceIndices")] - if obj.get("sourceIndices") is not None - else None - ), - "languages": ( - Languages.from_dict(obj.get("languages")) - if obj.get("languages") is not None - else None - ), - "exclude": obj.get("exclude"), - "enablePersonalization": obj.get("enablePersonalization"), - "allowSpecialCharacters": obj.get("allowSpecialCharacters"), - } + obj["sourceIndices"] = ( + [SourceIndex.from_dict(_item) for _item in obj["sourceIndices"]] + if obj.get("sourceIndices") is not None + else None ) - return _obj + obj["languages"] = ( + Languages.from_dict(obj["languages"]) + if obj.get("languages") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/query_suggestions/models/configuration_response.py b/algoliasearch/query_suggestions/models/configuration_response.py index 8402956ef..20e9b3e90 100644 --- a/algoliasearch/query_suggestions/models/configuration_response.py +++ b/algoliasearch/query_suggestions/models/configuration_response.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.query_suggestions.models.languages import Languages @@ -27,69 +27,44 @@ class ConfigurationResponse(BaseModel): API response for retrieving Query Suggestions configurations. """ - app_id: StrictStr = Field( - description="Algolia application ID to which this Query Suggestions configuration belongs.", - alias="appID", - ) - index_name: StrictStr = Field( - description="Name of the Query Suggestions index (case-sensitive).", - alias="indexName", - ) - source_indices: Annotated[List[SourceIndex], Field(min_length=1)] = Field( - description="Algolia indices from which to get the popular searches for query suggestions.", - alias="sourceIndices", - ) - languages: Languages - exclude: Optional[List[StrictStr]] - enable_personalization: StrictBool = Field( - description="Whether to turn on personalized query suggestions.", - alias="enablePersonalization", - ) - allow_special_characters: StrictBool = Field( - description="Whether to include suggestions with special characters.", - alias="allowSpecialCharacters", - ) + app_id: str = Field(alias="appID") + """ Algolia application ID to which this Query Suggestions configuration belongs. """ + index_name: str = Field(alias="indexName") + """ Name of the Query Suggestions index (case-sensitive). """ + source_indices: List[SourceIndex] = Field(alias="sourceIndices") + """ Algolia indices from which to get the popular searches for query suggestions. """ + languages: Languages = Field(alias="languages") + exclude: List[str] = Field(alias="exclude") + enable_personalization: bool = Field(alias="enablePersonalization") + """ Whether to turn on personalized query suggestions. """ + allow_special_characters: bool = Field(alias="allowSpecialCharacters") + """ Whether to include suggestions with special characters. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ConfigurationResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.source_indices: - for _item in self.source_indices: - if _item: - _items.append(_item.to_dict()) - _dict["sourceIndices"] = _items - if self.languages: - _dict["languages"] = self.languages.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ConfigurationResponse from a dict""" if obj is None: return None @@ -97,23 +72,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "appID": obj.get("appID"), - "indexName": obj.get("indexName"), - "sourceIndices": ( - [SourceIndex.from_dict(_item) for _item in obj.get("sourceIndices")] - if obj.get("sourceIndices") is not None - else None - ), - "languages": ( - Languages.from_dict(obj.get("languages")) - if obj.get("languages") is not None - else None - ), - "exclude": obj.get("exclude"), - "enablePersonalization": obj.get("enablePersonalization"), - "allowSpecialCharacters": obj.get("allowSpecialCharacters"), - } + obj["sourceIndices"] = ( + [SourceIndex.from_dict(_item) for _item in obj["sourceIndices"]] + if obj.get("sourceIndices") is not None + else None ) - return _obj + obj["languages"] = ( + Languages.from_dict(obj["languages"]) + if obj.get("languages") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/query_suggestions/models/configuration_with_index.py b/algoliasearch/query_suggestions/models/configuration_with_index.py index 2752581d5..68d0bfa22 100644 --- a/algoliasearch/query_suggestions/models/configuration_with_index.py +++ b/algoliasearch/query_suggestions/models/configuration_with_index.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.query_suggestions.models.languages import Languages @@ -27,67 +27,46 @@ class ConfigurationWithIndex(BaseModel): Query Suggestions configuration. """ - source_indices: Annotated[List[SourceIndex], Field(min_length=1)] = Field( - description="Algolia indices from which to get the popular searches for query suggestions.", - alias="sourceIndices", + source_indices: List[SourceIndex] = Field(alias="sourceIndices") + """ Algolia indices from which to get the popular searches for query suggestions. """ + languages: Optional[Languages] = Field(default=None, alias="languages") + exclude: Optional[List[str]] = Field(default=None, alias="exclude") + enable_personalization: Optional[bool] = Field( + default=None, alias="enablePersonalization" ) - languages: Optional[Languages] = None - exclude: Optional[List[StrictStr]] = None - enable_personalization: Optional[StrictBool] = Field( - default=False, - description="Whether to turn on personalized query suggestions.", - alias="enablePersonalization", - ) - allow_special_characters: Optional[StrictBool] = Field( - default=False, - description="Whether to include suggestions with special characters.", - alias="allowSpecialCharacters", - ) - index_name: StrictStr = Field( - description="Name of the Query Suggestions index (case-sensitive).", - alias="indexName", + """ Whether to turn on personalized query suggestions. """ + allow_special_characters: Optional[bool] = Field( + default=None, alias="allowSpecialCharacters" ) + """ Whether to include suggestions with special characters. """ + index_name: str = Field(alias="indexName") + """ Name of the Query Suggestions index (case-sensitive). """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ConfigurationWithIndex from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.source_indices: - for _item in self.source_indices: - if _item: - _items.append(_item.to_dict()) - _dict["sourceIndices"] = _items - if self.languages: - _dict["languages"] = self.languages.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ConfigurationWithIndex from a dict""" if obj is None: return None @@ -95,22 +74,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "sourceIndices": ( - [SourceIndex.from_dict(_item) for _item in obj.get("sourceIndices")] - if obj.get("sourceIndices") is not None - else None - ), - "languages": ( - Languages.from_dict(obj.get("languages")) - if obj.get("languages") is not None - else None - ), - "exclude": obj.get("exclude"), - "enablePersonalization": obj.get("enablePersonalization"), - "allowSpecialCharacters": obj.get("allowSpecialCharacters"), - "indexName": obj.get("indexName"), - } + obj["sourceIndices"] = ( + [SourceIndex.from_dict(_item) for _item in obj["sourceIndices"]] + if obj.get("sourceIndices") is not None + else None + ) + obj["languages"] = ( + Languages.from_dict(obj["languages"]) + if obj.get("languages") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/query_suggestions/models/error_base.py b/algoliasearch/query_suggestions/models/error_base.py index 4317b330d..075d8a3ac 100644 --- a/algoliasearch/query_suggestions/models/error_base.py +++ b/algoliasearch/query_suggestions/models/error_base.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, ClassVar, Dict, List, Optional +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,50 +23,34 @@ class ErrorBase(BaseModel): Error. """ - message: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["message"] + message: Optional[str] = Field(default=None, alias="message") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + extra="allow", ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ErrorBase from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={ - "additional_properties", - }, exclude_none=True, exclude_unset=True, ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ErrorBase from a dict""" if obj is None: return None @@ -74,10 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"message": obj.get("message")}) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/query_suggestions/models/facet.py b/algoliasearch/query_suggestions/models/facet.py index 392a15b54..dfe651e4a 100644 --- a/algoliasearch/query_suggestions/models/facet.py +++ b/algoliasearch/query_suggestions/models/facet.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,36 @@ class Facet(BaseModel): Facet to use as category. """ - attribute: Optional[StrictStr] = Field(default=None, description="Facet name.") - amount: Optional[StrictInt] = Field( - default=None, description="Number of suggestions." - ) + attribute: Optional[str] = Field(default=None, alias="attribute") + """ Facet name. """ + amount: Optional[int] = Field(default=None, alias="amount") + """ Number of suggestions. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Facet from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Facet from a dict""" if obj is None: return None @@ -67,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"attribute": obj.get("attribute"), "amount": obj.get("amount")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/query_suggestions/models/languages.py b/algoliasearch/query_suggestions/models/languages.py index 835d4efb9..2ccb3a9fa 100644 --- a/algoliasearch/query_suggestions/models/languages.py +++ b/algoliasearch/query_suggestions/models/languages.py @@ -8,16 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import ( - BaseModel, - Field, - StrictBool, - StrictStr, - ValidationError, - model_serializer, -) +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -30,14 +23,12 @@ class Languages(BaseModel): Languages for deduplicating singular and plural suggestions. If specified, only the more popular form is included. """ - oneof_schema_1_validator: Optional[List[StrictStr]] = Field( - default=None, - description="Languages for which to deduplicate singular and plural forms.", - ) - oneof_schema_2_validator: Optional[StrictBool] = Field( - default=None, description="If true, deduplication is enabled for all languages." - ) + oneof_schema_1_validator: Optional[List[str]] = Field(default=None) + """ Languages for which to deduplicate singular and plural forms. """ + oneof_schema_2_validator: Optional[bool] = Field(default=None) + """ If true, deduplication is enabled for all languages. """ actual_instance: Optional[Union[List[str], bool]] = None + one_of_schemas: Set[str] = {"List[str]", "bool"} def __init__(self, *args, **kwargs) -> None: if args: @@ -61,7 +52,8 @@ def unwrap_actual_instance(self) -> Optional[Union[List[str], bool]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of Languages from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -95,17 +87,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], List[str], bool]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/query_suggestions/models/log_file.py b/algoliasearch/query_suggestions/models/log_file.py index bd143cc17..ce3fbcc4d 100644 --- a/algoliasearch/query_suggestions/models/log_file.py +++ b/algoliasearch/query_suggestions/models/log_file.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,51 +26,39 @@ class LogFile(BaseModel): LogFile """ - timestamp: Optional[StrictStr] = Field( - default=None, description="Date and time of the log entry, in RFC 3339 format." - ) - level: Optional[LogLevel] = None - message: Optional[StrictStr] = Field( - default=None, description="Details about this log entry." - ) - context_level: Optional[StrictInt] = Field( - default=None, - description="Level indicating the position of a suggestion in a hierarchy of records. For example, a `contextLevel` of 1 indicates that this suggestion belongs to a previous suggestion with `contextLevel` 0. ", - alias="contextLevel", - ) + timestamp: Optional[str] = Field(default=None, alias="timestamp") + """ Date and time of the log entry, in RFC 3339 format. """ + level: Optional[LogLevel] = Field(default=None, alias="level") + message: Optional[str] = Field(default=None, alias="message") + """ Details about this log entry. """ + context_level: Optional[int] = Field(default=None, alias="contextLevel") + """ Level indicating the position of a suggestion in a hierarchy of records. For example, a `contextLevel` of 1 indicates that this suggestion belongs to a previous suggestion with `contextLevel` 0. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of LogFile from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of LogFile from a dict""" if obj is None: return None @@ -78,12 +66,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "timestamp": obj.get("timestamp"), - "level": obj.get("level"), - "message": obj.get("message"), - "contextLevel": obj.get("contextLevel"), - } - ) - return _obj + obj["level"] = obj.get("level") + + return cls.model_validate(obj) diff --git a/algoliasearch/query_suggestions/models/log_level.py b/algoliasearch/query_suggestions/models/log_level.py index 98149eede..899ca4e63 100644 --- a/algoliasearch/query_suggestions/models/log_level.py +++ b/algoliasearch/query_suggestions/models/log_level.py @@ -25,7 +25,9 @@ class LogLevel(str, Enum): allowed enum values """ SKIP = "SKIP" + INFO = "INFO" + ERROR = "ERROR" @classmethod diff --git a/algoliasearch/query_suggestions/models/source_index.py b/algoliasearch/query_suggestions/models/source_index.py index 01bbe8e36..22711c6ba 100644 --- a/algoliasearch/query_suggestions/models/source_index.py +++ b/algoliasearch/query_suggestions/models/source_index.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.query_suggestions.models.facet import Facet @@ -26,69 +26,44 @@ class SourceIndex(BaseModel): Configuration of an Algolia index for Query Suggestions. """ - index_name: StrictStr = Field( - description="Name of the Algolia index (case-sensitive) to use as source for query suggestions.", - alias="indexName", - ) - replicas: Optional[StrictBool] = Field( - default=False, - description="If true, Query Suggestions uses all replica indices to find popular searches. If false, only the primary index is used. ", - ) - analytics_tags: Optional[List[StrictStr]] = Field( - default=None, alias="analyticsTags" - ) - facets: Optional[List[Facet]] = None - min_hits: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=5, - description="Minimum number of hits required to be included as a suggestion. A search query must at least generate `minHits` search results to be included in the Query Suggestions index. ", - alias="minHits", - ) - min_letters: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=4, - description="Minimum letters required to be included as a suggestion. A search query must be at least `minLetters` long to be included in the Query Suggestions index. ", - alias="minLetters", - ) - generate: Optional[List[List[StrictStr]]] = None - external: Optional[List[StrictStr]] = None + index_name: str = Field(alias="indexName") + """ Name of the Algolia index (case-sensitive) to use as source for query suggestions. """ + replicas: Optional[bool] = Field(default=None, alias="replicas") + """ If true, Query Suggestions uses all replica indices to find popular searches. If false, only the primary index is used. """ + analytics_tags: Optional[List[str]] = Field(default=None, alias="analyticsTags") + facets: Optional[List[Facet]] = Field(default=None, alias="facets") + min_hits: Optional[int] = Field(default=None, alias="minHits") + """ Minimum number of hits required to be included as a suggestion. A search query must at least generate `minHits` search results to be included in the Query Suggestions index. """ + min_letters: Optional[int] = Field(default=None, alias="minLetters") + """ Minimum letters required to be included as a suggestion. A search query must be at least `minLetters` long to be included in the Query Suggestions index. """ + generate: Optional[List[List[str]]] = Field(default=None, alias="generate") + external: Optional[List[str]] = Field(default=None, alias="external") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SourceIndex from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.facets: - for _item in self.facets: - if _item: - _items.append(_item.to_dict()) - _dict["facets"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SourceIndex from a dict""" if obj is None: return None @@ -96,20 +71,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "indexName": obj.get("indexName"), - "replicas": obj.get("replicas"), - "analyticsTags": obj.get("analyticsTags"), - "facets": ( - [Facet.from_dict(_item) for _item in obj.get("facets")] - if obj.get("facets") is not None - else None - ), - "minHits": obj.get("minHits"), - "minLetters": obj.get("minLetters"), - "generate": obj.get("generate"), - "external": obj.get("external"), - } + obj["facets"] = ( + [Facet.from_dict(_item) for _item in obj["facets"]] + if obj.get("facets") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/client.py b/algoliasearch/recommend/client.py index 5ba5f9435..8414016f3 100644 --- a/algoliasearch/recommend/client.py +++ b/algoliasearch/recommend/client.py @@ -12,11 +12,12 @@ from urllib.parse import quote from pydantic import Field, StrictInt, StrictStr +from typing_extensions import Annotated if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.http.api_response import ApiResponse from algoliasearch.http.request_options import RequestOptions diff --git a/algoliasearch/recommend/models/advanced_syntax_features.py b/algoliasearch/recommend/models/advanced_syntax_features.py index a6834c55b..b9ff26102 100644 --- a/algoliasearch/recommend/models/advanced_syntax_features.py +++ b/algoliasearch/recommend/models/advanced_syntax_features.py @@ -25,6 +25,7 @@ class AdvancedSyntaxFeatures(str, Enum): allowed enum values """ EXACTPHRASE = "exactPhrase" + EXCLUDEWORDS = "excludeWords" @classmethod diff --git a/algoliasearch/recommend/models/alternatives_as_exact.py b/algoliasearch/recommend/models/alternatives_as_exact.py index 8be3c9da6..988dff0ad 100644 --- a/algoliasearch/recommend/models/alternatives_as_exact.py +++ b/algoliasearch/recommend/models/alternatives_as_exact.py @@ -25,7 +25,9 @@ class AlternativesAsExact(str, Enum): allowed enum values """ IGNOREPLURALS = "ignorePlurals" + SINGLEWORDSYNONYM = "singleWordSynonym" + MULTIWORDSSYNONYM = "multiWordsSynonym" @classmethod diff --git a/algoliasearch/recommend/models/around_precision.py b/algoliasearch/recommend/models/around_precision.py index 6e5e0adf1..20778614b 100644 --- a/algoliasearch/recommend/models/around_precision.py +++ b/algoliasearch/recommend/models/around_precision.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, Field, StrictInt, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -26,12 +26,12 @@ class AroundPrecision(BaseModel): Precision of a coordinate-based search in meters to group results with similar distances. The Geo ranking criterion considers all matches within the same range of distances to be equal. """ - oneof_schema_1_validator: Optional[StrictInt] = Field( - default=10, - description="Distance in meters to group results by similar distances. For example, if you set `aroundPrecision` to 100, records wihin 100 meters to the central coordinate are considered to have the same distance, as are records between 100 and 199 meters. ", - ) - oneof_schema_2_validator: Optional[List[Range]] = None + oneof_schema_1_validator: Optional[int] = Field(default=None) + """ Distance in meters to group results by similar distances. For example, if you set `aroundPrecision` to 100, records wihin 100 meters to the central coordinate are considered to have the same distance, as are records between 100 and 199 meters. """ + oneof_schema_2_validator: Optional[List[Range]] = Field(default=None) + actual_instance: Optional[Union[List[Range], int]] = None + one_of_schemas: Set[str] = {"List[Range]", "int"} def __init__(self, *args, **kwargs) -> None: if args: @@ -55,7 +55,8 @@ def unwrap_actual_instance(self) -> Optional[Union[List[Range], int]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of AroundPrecision from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -89,17 +90,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], List[Range], int]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/recommend/models/around_radius.py b/algoliasearch/recommend/models/around_radius.py index 7c37ac3c5..5b993cf35 100644 --- a/algoliasearch/recommend/models/around_radius.py +++ b/algoliasearch/recommend/models/around_radius.py @@ -8,14 +8,14 @@ from json import dumps, loads from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.recommend.models.around_radius_all import AroundRadiusAll @@ -26,14 +26,12 @@ class AroundRadius(BaseModel): Maximum radius for a search around a central location. This parameter works in combination with the `aroundLatLng` and `aroundLatLngViaIP` parameters. By default, the search radius is determined automatically from the density of hits around the central location. The search radius is small if there are many hits close to the central coordinates. """ - oneof_schema_1_validator: Optional[Annotated[int, Field(strict=True, ge=1)]] = ( - Field( - default=None, - description="Maximum search radius around a central location in meters.", - ) - ) - oneof_schema_2_validator: Optional[AroundRadiusAll] = None + oneof_schema_1_validator: Optional[int] = Field(default=None) + """ Maximum search radius around a central location in meters. """ + oneof_schema_2_validator: Optional[AroundRadiusAll] = Field(default=None) + actual_instance: Optional[Union[AroundRadiusAll, int]] = None + one_of_schemas: Set[str] = {"AroundRadiusAll", "int"} def __init__(self, *args, **kwargs) -> None: if args: @@ -57,7 +55,8 @@ def unwrap_actual_instance(self) -> Optional[Union[AroundRadiusAll, int]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of AroundRadius from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -90,17 +89,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], AroundRadiusAll, int]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/recommend/models/auto_facet_filter.py b/algoliasearch/recommend/models/auto_facet_filter.py index 8afd954a4..0f95582fc 100644 --- a/algoliasearch/recommend/models/auto_facet_filter.py +++ b/algoliasearch/recommend/models/auto_facet_filter.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,44 +23,36 @@ class AutoFacetFilter(BaseModel): Facet attribute. Only recommendations with the same value (or only recommendations with a different value) as the original viewed item are included. """ - facet: Optional[StrictStr] = Field(default=None, description="Facet attribute.") - negative: Optional[StrictBool] = Field( - default=None, - description="Whether the filter is negative. If true, recommendations must not have the same value for the `facet` attribute. If false, recommendations must have the same value for the `facet` attribute. ", - ) + facet: Optional[str] = Field(default=None, alias="facet") + """ Facet attribute. """ + negative: Optional[bool] = Field(default=None, alias="negative") + """ Whether the filter is negative. If true, recommendations must not have the same value for the `facet` attribute. If false, recommendations must have the same value for the `facet` attribute. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AutoFacetFilter from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AutoFacetFilter from a dict""" if obj is None: return None @@ -68,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"facet": obj.get("facet"), "negative": obj.get("negative")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/boolean_string.py b/algoliasearch/recommend/models/boolean_string.py index 5cf024f8a..cd4f50891 100644 --- a/algoliasearch/recommend/models/boolean_string.py +++ b/algoliasearch/recommend/models/boolean_string.py @@ -25,6 +25,7 @@ class BooleanString(str, Enum): allowed enum values """ TRUE = "true" + FALSE = "false" @classmethod diff --git a/algoliasearch/recommend/models/bought_together_query.py b/algoliasearch/recommend/models/bought_together_query.py index 8e2e99b84..937b7eaba 100644 --- a/algoliasearch/recommend/models/bought_together_query.py +++ b/algoliasearch/recommend/models/bought_together_query.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.recommend.models.fbt_model import FbtModel @@ -27,64 +27,44 @@ class BoughtTogetherQuery(BaseModel): BoughtTogetherQuery """ - index_name: StrictStr = Field( - description="Index name (case-sensitive).", alias="indexName" - ) - threshold: Union[ - Annotated[float, Field(le=100, strict=True, ge=0)], - Annotated[int, Field(le=100, strict=True, ge=0)], - ] = Field( - description="Minimum score a recommendation must have to be included in the response." - ) - max_recommendations: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = ( - Field( - default=30, - description="Maximum number of recommendations to retrieve. By default, all recommendations are returned and no fallback request is made. Depending on the available recommendations and the other request parameters, the actual number of recommendations may be lower than this value. ", - alias="maxRecommendations", - ) - ) + index_name: str = Field(alias="indexName") + """ Index name (case-sensitive). """ + threshold: float = Field(alias="threshold") + """ Minimum score a recommendation must have to be included in the response. """ + max_recommendations: Optional[int] = Field(default=None, alias="maxRecommendations") + """ Maximum number of recommendations to retrieve. By default, all recommendations are returned and no fallback request is made. Depending on the available recommendations and the other request parameters, the actual number of recommendations may be lower than this value. """ query_parameters: Optional[RecommendSearchParams] = Field( default=None, alias="queryParameters" ) - model: FbtModel - object_id: StrictStr = Field( - description="Unique record identifier.", alias="objectID" - ) + model: FbtModel = Field(alias="model") + object_id: str = Field(alias="objectID") + """ Unique record identifier. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of BoughtTogetherQuery from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.query_parameters: - _dict["queryParameters"] = self.query_parameters.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of BoughtTogetherQuery from a dict""" if obj is None: return None @@ -92,18 +72,11 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "indexName": obj.get("indexName"), - "threshold": obj.get("threshold"), - "maxRecommendations": obj.get("maxRecommendations"), - "queryParameters": ( - RecommendSearchParams.from_dict(obj.get("queryParameters")) - if obj.get("queryParameters") is not None - else None - ), - "model": obj.get("model"), - "objectID": obj.get("objectID"), - } + obj["queryParameters"] = ( + RecommendSearchParams.from_dict(obj["queryParameters"]) + if obj.get("queryParameters") is not None + else None ) - return _obj + obj["model"] = obj.get("model") + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/condition.py b/algoliasearch/recommend/models/condition.py index a8e85ed88..2e8b8b739 100644 --- a/algoliasearch/recommend/models/condition.py +++ b/algoliasearch/recommend/models/condition.py @@ -11,12 +11,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class Condition(BaseModel): @@ -24,14 +24,10 @@ class Condition(BaseModel): Condition that triggers the rule. If not specified, the rule is triggered for all recommendations. """ - filters: Optional[StrictStr] = Field( - default=None, - description="Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). ", - ) - context: Optional[Annotated[str, Field(strict=True)]] = Field( - default=None, - description="An additional restriction that only triggers the rule, when the search has the same value as `ruleContexts` parameter. For example, if `context: mobile`, the rule is only triggered when the search request has a matching `ruleContexts: mobile`. A rule context must only contain alphanumeric characters. ", - ) + filters: Optional[str] = Field(default=None, alias="filters") + """ Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). """ + context: Optional[str] = Field(default=None, alias="context") + """ An additional restriction that only triggers the rule, when the search has the same value as `ruleContexts` parameter. For example, if `context: mobile`, the rule is only triggered when the search request has a matching `ruleContexts: mobile`. A rule context must only contain alphanumeric characters. """ @field_validator("context") def context_validate_regular_expression(cls, value): @@ -44,37 +40,30 @@ def context_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Condition from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Condition from a dict""" if obj is None: return None @@ -82,7 +71,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"filters": obj.get("filters"), "context": obj.get("context")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/consequence.py b/algoliasearch/recommend/models/consequence.py index 362601375..98168e52c 100644 --- a/algoliasearch/recommend/models/consequence.py +++ b/algoliasearch/recommend/models/consequence.py @@ -13,9 +13,9 @@ from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.recommend.models.hide_consequence_object import HideConsequenceObject @@ -30,63 +30,39 @@ class Consequence(BaseModel): Effect of the rule. """ - hide: Optional[Annotated[List[HideConsequenceObject], Field(min_length=1)]] = Field( - default=None, description="Exclude items from recommendations." + hide: Optional[List[HideConsequenceObject]] = Field(default=None, alias="hide") + """ Exclude items from recommendations. """ + promote: Optional[List[PromoteConsequenceObject]] = Field( + default=None, alias="promote" ) - promote: Optional[ - Annotated[List[PromoteConsequenceObject], Field(min_length=1)] - ] = Field( - default=None, - description="Place items at specific positions in the list of recommendations.", - ) - params: Optional[ParamsConsequence] = None + """ Place items at specific positions in the list of recommendations. """ + params: Optional[ParamsConsequence] = Field(default=None, alias="params") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Consequence from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.hide: - for _item in self.hide: - if _item: - _items.append(_item.to_dict()) - _dict["hide"] = _items - _items = [] - if self.promote: - for _item in self.promote: - if _item: - _items.append(_item.to_dict()) - _dict["promote"] = _items - if self.params: - _dict["params"] = self.params.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Consequence from a dict""" if obj is None: return None @@ -94,29 +70,20 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "hide": ( - [ - HideConsequenceObject.from_dict(_item) - for _item in obj.get("hide") - ] - if obj.get("hide") is not None - else None - ), - "promote": ( - [ - PromoteConsequenceObject.from_dict(_item) - for _item in obj.get("promote") - ] - if obj.get("promote") is not None - else None - ), - "params": ( - ParamsConsequence.from_dict(obj.get("params")) - if obj.get("params") is not None - else None - ), - } + obj["hide"] = ( + [HideConsequenceObject.from_dict(_item) for _item in obj["hide"]] + if obj.get("hide") is not None + else None ) - return _obj + obj["promote"] = ( + [PromoteConsequenceObject.from_dict(_item) for _item in obj["promote"]] + if obj.get("promote") is not None + else None + ) + obj["params"] = ( + ParamsConsequence.from_dict(obj["params"]) + if obj.get("params") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/deleted_at_response.py b/algoliasearch/recommend/models/deleted_at_response.py index 90f192f86..5de986f76 100644 --- a/algoliasearch/recommend/models/deleted_at_response.py +++ b/algoliasearch/recommend/models/deleted_at_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,47 +23,36 @@ class DeletedAtResponse(BaseModel): Response, taskID, and deletion timestamp. """ - task_id: StrictInt = Field( - description="Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. ", - alias="taskID", - ) - deleted_at: StrictStr = Field( - description="Date and time when the object was deleted, in RFC 3339 format.", - alias="deletedAt", - ) + task_id: int = Field(alias="taskID") + """ Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. """ + deleted_at: str = Field(alias="deletedAt") + """ Date and time when the object was deleted, in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DeletedAtResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DeletedAtResponse from a dict""" if obj is None: return None @@ -71,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"taskID": obj.get("taskID"), "deletedAt": obj.get("deletedAt")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/distinct.py b/algoliasearch/recommend/models/distinct.py index 474461db7..fcc03353d 100644 --- a/algoliasearch/recommend/models/distinct.py +++ b/algoliasearch/recommend/models/distinct.py @@ -8,14 +8,14 @@ from json import dumps, loads from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, Field, StrictBool, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class Distinct(BaseModel): @@ -23,17 +23,12 @@ class Distinct(BaseModel): Determines how many records of a group are included in the search results. Records with the same value for the `attributeForDistinct` attribute are considered a group. The `distinct` setting controls how many members of the group are returned. This is useful for [deduplication and grouping](https://www.algolia.com/doc/guides/managing-results/refine-results/grouping/#introducing-algolias-distinct-feature). The `distinct` setting is ignored if `attributeForDistinct` is not set. """ - oneof_schema_1_validator: Optional[StrictBool] = Field( - default=None, - description="Whether deduplication is turned on. If true, only one member of a group is shown in the search results.", - ) - oneof_schema_2_validator: Optional[ - Annotated[int, Field(le=4, strict=True, ge=0)] - ] = Field( - default=0, - description="Number of members of a group of records to include in the search results. - Don't use `distinct > 1` for records that might be [promoted by rules](https://www.algolia.com/doc/guides/managing-results/rules/merchandising-and-promoting/how-to/promote-hits/). The number of hits won't be correct and faceting won't work as expected. - With `distinct > 1`, the `hitsPerPage` parameter controls the number of returned groups. For example, with `hitsPerPage: 10` and `distinct: 2`, up to 20 records are returned. Likewise, the `nbHits` response attribute contains the number of returned groups. ", - ) + oneof_schema_1_validator: Optional[bool] = Field(default=None) + """ Whether deduplication is turned on. If true, only one member of a group is shown in the search results. """ + oneof_schema_2_validator: Optional[int] = Field(default=None) + """ Number of members of a group of records to include in the search results. - Don't use `distinct > 1` for records that might be [promoted by rules](https://www.algolia.com/doc/guides/managing-results/rules/merchandising-and-promoting/how-to/promote-hits/). The number of hits won't be correct and faceting won't work as expected. - With `distinct > 1`, the `hitsPerPage` parameter controls the number of returned groups. For example, with `hitsPerPage: 10` and `distinct: 2`, up to 20 records are returned. Likewise, the `nbHits` response attribute contains the number of returned groups. """ actual_instance: Optional[Union[bool, int]] = None + one_of_schemas: Set[str] = {"bool", "int"} def __init__(self, *args, **kwargs) -> None: if args: @@ -57,7 +52,8 @@ def unwrap_actual_instance(self) -> Optional[Union[bool, int]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of Distinct from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -91,17 +87,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], bool, int]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/recommend/models/error_base.py b/algoliasearch/recommend/models/error_base.py index 4317b330d..075d8a3ac 100644 --- a/algoliasearch/recommend/models/error_base.py +++ b/algoliasearch/recommend/models/error_base.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, ClassVar, Dict, List, Optional +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,50 +23,34 @@ class ErrorBase(BaseModel): Error. """ - message: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["message"] + message: Optional[str] = Field(default=None, alias="message") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + extra="allow", ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ErrorBase from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={ - "additional_properties", - }, exclude_none=True, exclude_unset=True, ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ErrorBase from a dict""" if obj is None: return None @@ -74,10 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"message": obj.get("message")}) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/exact_on_single_word_query.py b/algoliasearch/recommend/models/exact_on_single_word_query.py index 31b3fdfae..8eb32ce95 100644 --- a/algoliasearch/recommend/models/exact_on_single_word_query.py +++ b/algoliasearch/recommend/models/exact_on_single_word_query.py @@ -25,7 +25,9 @@ class ExactOnSingleWordQuery(str, Enum): allowed enum values """ ATTRIBUTE = "attribute" + NONE = "none" + WORD = "word" @classmethod diff --git a/algoliasearch/recommend/models/exhaustive.py b/algoliasearch/recommend/models/exhaustive.py index 008f6f857..1b7e3b403 100644 --- a/algoliasearch/recommend/models/exhaustive.py +++ b/algoliasearch/recommend/models/exhaustive.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,63 +23,42 @@ class Exhaustive(BaseModel): Whether certain properties of the search response are calculated exhaustive (exact) or approximated. """ - facets_count: Optional[StrictBool] = Field( - default=None, - description="Whether the facet count is exhaustive (`true`) or approximate (`false`). See the [related discussion](https://support.algolia.com/hc/en-us/articles/4406975248145-Why-are-my-facet-and-hit-counts-not-accurate-).", - alias="facetsCount", - ) - facet_values: Optional[StrictBool] = Field( - default=None, - description="The value is `false` if not all facet values are retrieved.", - alias="facetValues", - ) - nb_hits: Optional[StrictBool] = Field( - default=None, - description="Whether the `nbHits` is exhaustive (`true`) or approximate (`false`). When the query takes more than 50ms to be processed, the engine makes an approximation. This can happen when using complex filters on millions of records, when typo-tolerance was not exhaustive, or when enough hits have been retrieved (for example, after the engine finds 10,000 exact matches). `nbHits` is reported as non-exhaustive whenever an approximation is made, even if the approximation didn’t, in the end, impact the exhaustivity of the query.", - alias="nbHits", - ) - rules_match: Optional[StrictBool] = Field( - default=None, - description="Rules matching exhaustivity. The value is `false` if rules were enable for this query, and could not be fully processed due a timeout. This is generally caused by the number of alternatives (such as typos) which is too large.", - alias="rulesMatch", - ) - typo: Optional[StrictBool] = Field( - default=None, - description="Whether the typo search was exhaustive (`true`) or approximate (`false`). An approximation is done when the typo search query part takes more than 10% of the query budget (ie. 5ms by default) to be processed (this can happen when a lot of typo alternatives exist for the query). This field will not be included when typo-tolerance is entirely disabled.", - ) + facets_count: Optional[bool] = Field(default=None, alias="facetsCount") + """ Whether the facet count is exhaustive (`true`) or approximate (`false`). See the [related discussion](https://support.algolia.com/hc/en-us/articles/4406975248145-Why-are-my-facet-and-hit-counts-not-accurate-). """ + facet_values: Optional[bool] = Field(default=None, alias="facetValues") + """ The value is `false` if not all facet values are retrieved. """ + nb_hits: Optional[bool] = Field(default=None, alias="nbHits") + """ Whether the `nbHits` is exhaustive (`true`) or approximate (`false`). When the query takes more than 50ms to be processed, the engine makes an approximation. This can happen when using complex filters on millions of records, when typo-tolerance was not exhaustive, or when enough hits have been retrieved (for example, after the engine finds 10,000 exact matches). `nbHits` is reported as non-exhaustive whenever an approximation is made, even if the approximation didn’t, in the end, impact the exhaustivity of the query. """ + rules_match: Optional[bool] = Field(default=None, alias="rulesMatch") + """ Rules matching exhaustivity. The value is `false` if rules were enable for this query, and could not be fully processed due a timeout. This is generally caused by the number of alternatives (such as typos) which is too large. """ + typo: Optional[bool] = Field(default=None, alias="typo") + """ Whether the typo search was exhaustive (`true`) or approximate (`false`). An approximation is done when the typo search query part takes more than 10% of the query budget (ie. 5ms by default) to be processed (this can happen when a lot of typo alternatives exist for the query). This field will not be included when typo-tolerance is entirely disabled. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Exhaustive from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Exhaustive from a dict""" if obj is None: return None @@ -87,13 +66,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "facetsCount": obj.get("facetsCount"), - "facetValues": obj.get("facetValues"), - "nbHits": obj.get("nbHits"), - "rulesMatch": obj.get("rulesMatch"), - "typo": obj.get("typo"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/facet_filters.py b/algoliasearch/recommend/models/facet_filters.py index cd6492ec5..9669c5fb0 100644 --- a/algoliasearch/recommend/models/facet_filters.py +++ b/algoliasearch/recommend/models/facet_filters.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, StrictStr, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -23,9 +23,12 @@ class FacetFilters(BaseModel): Filter the search by facet values, so that only records with the same facet values are retrieved. **Prefer using the `filters` parameter, which supports all filter types and combinations with boolean operators.** - `[filter1, filter2]` is interpreted as `filter1 AND filter2`. - `[[filter1, filter2], filter3]` is interpreted as `filter1 OR filter2 AND filter3`. - `facet:-value` is interpreted as `NOT facet:value`. While it's best to avoid attributes that start with a `-`, you can still filter them by escaping with a backslash: `facet:\\-value`. """ - oneof_schema_1_validator: Optional[List[FacetFilters]] = None - oneof_schema_2_validator: Optional[StrictStr] = None + oneof_schema_1_validator: Optional[List[FacetFilters]] = Field(default=None) + + oneof_schema_2_validator: Optional[str] = Field(default=None) + actual_instance: Optional[Union[List[FacetFilters], str]] = None + one_of_schemas: Set[str] = {"List[FacetFilters]", "str"} def __init__(self, *args, **kwargs) -> None: if args: @@ -49,7 +52,8 @@ def unwrap_actual_instance(self) -> Optional[Union[List[FacetFilters], str]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of FacetFilters from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -83,17 +87,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], List[FacetFilters], str]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/recommend/models/facet_ordering.py b/algoliasearch/recommend/models/facet_ordering.py index a1ddeaa13..99d8bf4f0 100644 --- a/algoliasearch/recommend/models/facet_ordering.py +++ b/algoliasearch/recommend/models/facet_ordering.py @@ -27,51 +27,35 @@ class FacetOrdering(BaseModel): Order of facet names and facet values in your UI. """ - facets: Optional[IndexSettingsFacets] = None - values: Optional[Dict[str, Value]] = Field( - default=None, description="Order of facet values. One object for each facet." - ) + facets: Optional[IndexSettingsFacets] = Field(default=None, alias="facets") + values: Optional[Dict[str, Value]] = Field(default=None, alias="values") + """ Order of facet values. One object for each facet. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of FacetOrdering from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.facets: - _dict["facets"] = self.facets.to_dict() - _field_dict = {} - if self.values: - for _key in self.values: - if self.values[_key]: - _field_dict[_key] = self.values[_key].to_dict() - _dict["values"] = _field_dict - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of FacetOrdering from a dict""" if obj is None: return None @@ -79,21 +63,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "facets": ( - IndexSettingsFacets.from_dict(obj.get("facets")) - if obj.get("facets") is not None - else None - ), - "values": ( - dict( - (_k, Value.from_dict(_v)) - for _k, _v in obj.get("values").items() - ) - if obj.get("values") is not None - else None - ), - } + obj["facets"] = ( + IndexSettingsFacets.from_dict(obj["facets"]) + if obj.get("facets") is not None + else None ) - return _obj + obj["values"] = ( + dict((_k, Value.from_dict(_v)) for _k, _v in obj["values"].items()) + if obj.get("values") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/facet_stats.py b/algoliasearch/recommend/models/facet_stats.py index 2747ff786..ada778720 100644 --- a/algoliasearch/recommend/models/facet_stats.py +++ b/algoliasearch/recommend/models/facet_stats.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,51 +23,40 @@ class FacetStats(BaseModel): FacetStats """ - min: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, description="Minimum value in the results." - ) - max: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, description="Maximum value in the results." - ) - avg: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, description="Average facet value in the results." - ) - sum: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, description="Sum of all values in the results." - ) + min: Optional[float] = Field(default=None, alias="min") + """ Minimum value in the results. """ + max: Optional[float] = Field(default=None, alias="max") + """ Maximum value in the results. """ + avg: Optional[float] = Field(default=None, alias="avg") + """ Average facet value in the results. """ + sum: Optional[float] = Field(default=None, alias="sum") + """ Sum of all values in the results. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of FacetStats from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of FacetStats from a dict""" if obj is None: return None @@ -75,12 +64,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "min": obj.get("min"), - "max": obj.get("max"), - "avg": obj.get("avg"), - "sum": obj.get("sum"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/fallback_params.py b/algoliasearch/recommend/models/fallback_params.py index 135634fbe..5f8d24c48 100644 --- a/algoliasearch/recommend/models/fallback_params.py +++ b/algoliasearch/recommend/models/fallback_params.py @@ -8,22 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional -from pydantic import ( - BaseModel, - ConfigDict, - Field, - StrictBool, - StrictFloat, - StrictInt, - StrictStr, -) +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.recommend.models.advanced_syntax_features import ( @@ -57,15 +49,10 @@ class FallbackParams(BaseModel): FallbackParams """ - similar_query: Optional[StrictStr] = Field( - default="", - description="Keywords to be used instead of the search query to conduct a more broader search. Using the `similarQuery` parameter changes other settings: - `queryType` is set to `prefixNone`. - `removeStopWords` is set to true. - `words` is set as the first ranking criterion. - All remaining words are treated as `optionalWords`. Since the `similarQuery` is supposed to do a broad search, they usually return many results. Combine it with `filters` to narrow down the list of results. ", - alias="similarQuery", - ) - filters: Optional[StrictStr] = Field( - default=None, - description="Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). ", - ) + similar_query: Optional[str] = Field(default=None, alias="similarQuery") + """ Keywords to be used instead of the search query to conduct a more broader search. Using the `similarQuery` parameter changes other settings: - `queryType` is set to `prefixNone`. - `removeStopWords` is set to true. - `words` is set as the first ranking criterion. - All remaining words are treated as `optionalWords`. Since the `similarQuery` is supposed to do a broad search, they usually return many results. Combine it with `filters` to narrow down the list of results. """ + filters: Optional[str] = Field(default=None, alias="filters") + """ Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). """ facet_filters: Optional[FacetFilters] = Field(default=None, alias="facetFilters") optional_filters: Optional[OptionalFilters] = Field( default=None, alias="optionalFilters" @@ -74,431 +61,273 @@ class FallbackParams(BaseModel): default=None, alias="numericFilters" ) tag_filters: Optional[TagFilters] = Field(default=None, alias="tagFilters") - sum_or_filters_scores: Optional[StrictBool] = Field( - default=False, - description="Whether to sum all filter scores. If true, all filter scores are summed. Otherwise, the maximum filter score is kept. For more information, see [filter scores](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/#accumulating-scores-with-sumorfiltersscores). ", - alias="sumOrFiltersScores", - ) - restrict_searchable_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Restricts a search to a subset of your searchable attributes. Attribute names are case-sensitive. ", - alias="restrictSearchableAttributes", - ) - facets: Optional[List[StrictStr]] = Field( - default=None, - description="Facets for which to retrieve facet values that match the search criteria and the number of matching facet values. To retrieve all facets, use the wildcard character `*`. For more information, see [facets](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#contextual-facet-values-and-counts). ", - ) - faceting_after_distinct: Optional[StrictBool] = Field( - default=False, - description="Whether faceting should be applied after deduplication with `distinct`. This leads to accurate facet counts when using faceting in combination with `distinct`. It's usually better to use `afterDistinct` modifiers in the `attributesForFaceting` setting, as `facetingAfterDistinct` only computes correct facet counts if all records have the same facet values for the `attributeForDistinct`. ", - alias="facetingAfterDistinct", - ) - around_lat_lng: Optional[StrictStr] = Field( - default="", - description="Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude. Only records included within circle around this central location are included in the results. The radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings. This parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`. ", - alias="aroundLatLng", - ) - around_lat_lng_via_ip: Optional[StrictBool] = Field( - default=False, - description="Whether to obtain the coordinates from the request's IP address.", - alias="aroundLatLngViaIP", - ) + sum_or_filters_scores: Optional[bool] = Field( + default=None, alias="sumOrFiltersScores" + ) + """ Whether to sum all filter scores. If true, all filter scores are summed. Otherwise, the maximum filter score is kept. For more information, see [filter scores](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/#accumulating-scores-with-sumorfiltersscores). """ + restrict_searchable_attributes: Optional[List[str]] = Field( + default=None, alias="restrictSearchableAttributes" + ) + """ Restricts a search to a subset of your searchable attributes. Attribute names are case-sensitive. """ + facets: Optional[List[str]] = Field(default=None, alias="facets") + """ Facets for which to retrieve facet values that match the search criteria and the number of matching facet values. To retrieve all facets, use the wildcard character `*`. For more information, see [facets](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#contextual-facet-values-and-counts). """ + faceting_after_distinct: Optional[bool] = Field( + default=None, alias="facetingAfterDistinct" + ) + """ Whether faceting should be applied after deduplication with `distinct`. This leads to accurate facet counts when using faceting in combination with `distinct`. It's usually better to use `afterDistinct` modifiers in the `attributesForFaceting` setting, as `facetingAfterDistinct` only computes correct facet counts if all records have the same facet values for the `attributeForDistinct`. """ + around_lat_lng: Optional[str] = Field(default=None, alias="aroundLatLng") + """ Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude. Only records included within circle around this central location are included in the results. The radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings. This parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`. """ + around_lat_lng_via_ip: Optional[bool] = Field( + default=None, alias="aroundLatLngViaIP" + ) + """ Whether to obtain the coordinates from the request's IP address. """ around_radius: Optional[AroundRadius] = Field(default=None, alias="aroundRadius") around_precision: Optional[AroundPrecision] = Field( default=None, alias="aroundPrecision" ) - minimum_around_radius: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field( - default=None, - description="Minimum radius (in meters) for a search around a location when `aroundRadius` isn't set.", - alias="minimumAroundRadius", - ) - inside_bounding_box: Optional[ - List[ - Annotated[ - List[Union[StrictFloat, StrictInt]], Field(min_length=4, max_length=4) - ] - ] - ] = Field( - default=None, - description="Coordinates for a rectangular area in which to search. Each bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair: `[p1 lat, p1 long, p2 lat, p2 long]`. Provide multiple bounding boxes as nested arrays. For more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). ", - alias="insideBoundingBox", - ) - inside_polygon: Optional[ - List[ - Annotated[ - List[Union[StrictFloat, StrictInt]], - Field(min_length=6, max_length=20000), - ] - ] - ] = Field( - default=None, - description="Coordinates of a polygon in which to search. Polygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude. Provide multiple polygons as nested arrays. For more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). This parameter is ignored if you also specify `insideBoundingBox`. ", - alias="insidePolygon", - ) - natural_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="ISO language codes that adjust settings that are useful for processing natural language queries (as opposed to keyword searches): - Sets `removeStopWords` and `ignorePlurals` to the list of provided languages. - Sets `removeWordsIfNoResults` to `allOptional`. - Adds a `natural_language` attribute to `ruleContexts` and `analyticsTags`. ", - alias="naturalLanguages", - ) - rule_contexts: Optional[List[StrictStr]] = Field( - default=None, - description="Assigns a rule context to the search query. [Rule contexts](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/how-to/customize-search-results-by-platform/#whats-a-context) are strings that you can use to trigger matching rules. ", - alias="ruleContexts", - ) - personalization_impact: Optional[ - Annotated[int, Field(le=100, strict=True, ge=0)] - ] = Field( - default=100, - description="Impact that Personalization should have on this search. The higher this value is, the more Personalization determines the ranking compared to other factors. For more information, see [Understanding Personalization impact](https://www.algolia.com/doc/guides/personalization/personalizing-results/in-depth/configuring-personalization/#understanding-personalization-impact). ", - alias="personalizationImpact", - ) - user_token: Optional[StrictStr] = Field( - default=None, - description="Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - get_ranking_info: Optional[StrictBool] = Field( - default=False, - description="Whether the search response should include detailed ranking information.", - alias="getRankingInfo", - ) - synonyms: Optional[StrictBool] = Field( - default=True, - description="Whether to take into account an index's synonyms for this search.", - ) - click_analytics: Optional[StrictBool] = Field( - default=False, - description="Whether to include a `queryID` attribute in the response. The query ID is a unique identifier for a search query and is required for tracking [click and conversion events](https://www.algolia.com/guides/sending-events/getting-started/). ", - alias="clickAnalytics", - ) - analytics: Optional[StrictBool] = Field( - default=True, description="Whether this search will be included in Analytics." - ) - analytics_tags: Optional[List[StrictStr]] = Field( - default=None, - description="Tags to apply to the query for [segmenting analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/).", - alias="analyticsTags", - ) - percentile_computation: Optional[StrictBool] = Field( - default=True, - description="Whether to include this search when calculating processing-time percentiles.", - alias="percentileComputation", - ) - enable_ab_test: Optional[StrictBool] = Field( - default=True, - description="Whether to enable A/B testing for this search.", - alias="enableABTest", - ) - query: Optional[StrictStr] = Field(default="", description="Search query.") - attributes_for_faceting: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes used for [faceting](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/). Facets are attributes that let you categorize search results. They can be used for filtering search results. By default, no attribute is used for faceting. Attribute names are case-sensitive. **Modifiers** - `filterOnly("ATTRIBUTE")`. Allows using this attribute as a filter, but doesn\'t evalue the facet values. - `searchable("ATTRIBUTE")`. Allows searching for facet values. - `afterDistinct("ATTRIBUTE")`. Evaluates the facet count _after_ deduplication with `distinct`. This ensures accurate facet counts. You can apply this modifier to searchable facets: `afterDistinct(searchable(ATTRIBUTE))`. ', - alias="attributesForFaceting", - ) - replicas: Optional[List[StrictStr]] = Field( - default=None, - description="Creates [replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/). Replicas are copies of a primary index with the same records but different settings, synonyms, or rules. If you want to offer a different ranking or sorting of your search results, you'll use replica indices. All index operations on a primary index are automatically forwarded to its replicas. To add a replica index, you must provide the complete set of replicas to this parameter. If you omit a replica from this list, the replica turns into a regular, standalone index that will no longer by synced with the primary index. **Modifier** - `virtual(\"REPLICA\")`. Create a virtual replica, Virtual replicas don't increase the number of records and are optimized for [Relevant sorting](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/relevant-sort/). ", - ) - pagination_limited_to: Optional[Annotated[int, Field(le=20000, strict=True)]] = ( - Field( - default=1000, - description="Maximum number of search results that can be obtained through pagination. Higher pagination limits might slow down your search. For pagination limits above 1,000, the sorting of results beyond the 1,000th hit can't be guaranteed. ", - alias="paginationLimitedTo", - ) - ) - unretrievable_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes that can't be retrieved at query time. This can be useful if you want to use an attribute for ranking or to [restrict access](https://www.algolia.com/doc/guides/security/api-keys/how-to/user-restricted-access-to-data/), but don't want to include it in the search results. Attribute names are case-sensitive. ", - alias="unretrievableAttributes", + minimum_around_radius: Optional[int] = Field( + default=None, alias="minimumAroundRadius" ) - disable_typo_tolerance_on_words: Optional[List[StrictStr]] = Field( - default=None, - description="Words for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). This also turns off [word splitting and concatenation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/splitting-and-concatenation/) for the specified words. ", - alias="disableTypoToleranceOnWords", + """ Minimum radius (in meters) for a search around a location when `aroundRadius` isn't set. """ + inside_bounding_box: Optional[List[List[float]]] = Field( + default=None, alias="insideBoundingBox" ) - attributes_to_transliterate: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes, for which you want to support [Japanese transliteration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#japanese-transliteration-and-type-ahead). Transliteration supports searching in any of the Japanese writing systems. To support transliteration, you must set the indexing language to Japanese. Attribute names are case-sensitive. ", - alias="attributesToTransliterate", - ) - camel_case_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which to split [camel case](https://wikipedia.org/wiki/Camel_case) words. Attribute names are case-sensitive. ", - alias="camelCaseAttributes", - ) - decompounded_attributes: Optional[Dict[str, Any]] = Field( - default=None, - description="Searchable attributes to which Algolia should apply [word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-segmentation/) (decompounding). Attribute names are case-sensitive. Compound words are formed by combining two or more individual words, and are particularly prevalent in Germanic languages—for example, \"firefighter\". With decompounding, the individual components are indexed separately. You can specify different lists for different languages. Decompounding is supported for these languages: Dutch (`nl`), German (`de`), Finnish (`fi`), Danish (`da`), Swedish (`sv`), and Norwegian (`no`). Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). ", - alias="decompoundedAttributes", + """ Coordinates for a rectangular area in which to search. Each bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair: `[p1 lat, p1 long, p2 lat, p2 long]`. Provide multiple bounding boxes as nested arrays. For more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). """ + inside_polygon: Optional[List[List[float]]] = Field( + default=None, alias="insidePolygon" ) + """ Coordinates of a polygon in which to search. Polygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude. Provide multiple polygons as nested arrays. For more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). This parameter is ignored if you also specify `insideBoundingBox`. """ + natural_languages: Optional[List[SupportedLanguage]] = Field( + default=None, alias="naturalLanguages" + ) + """ ISO language codes that adjust settings that are useful for processing natural language queries (as opposed to keyword searches): - Sets `removeStopWords` and `ignorePlurals` to the list of provided languages. - Sets `removeWordsIfNoResults` to `allOptional`. - Adds a `natural_language` attribute to `ruleContexts` and `analyticsTags`. """ + rule_contexts: Optional[List[str]] = Field(default=None, alias="ruleContexts") + """ Assigns a rule context to the search query. [Rule contexts](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/how-to/customize-search-results-by-platform/#whats-a-context) are strings that you can use to trigger matching rules. """ + personalization_impact: Optional[int] = Field( + default=None, alias="personalizationImpact" + ) + """ Impact that Personalization should have on this search. The higher this value is, the more Personalization determines the ranking compared to other factors. For more information, see [Understanding Personalization impact](https://www.algolia.com/doc/guides/personalization/personalizing-results/in-depth/configuring-personalization/#understanding-personalization-impact). """ + user_token: Optional[str] = Field(default=None, alias="userToken") + """ Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + get_ranking_info: Optional[bool] = Field(default=None, alias="getRankingInfo") + """ Whether the search response should include detailed ranking information. """ + synonyms: Optional[bool] = Field(default=None, alias="synonyms") + """ Whether to take into account an index's synonyms for this search. """ + click_analytics: Optional[bool] = Field(default=None, alias="clickAnalytics") + """ Whether to include a `queryID` attribute in the response. The query ID is a unique identifier for a search query and is required for tracking [click and conversion events](https://www.algolia.com/guides/sending-events/getting-started/). """ + analytics: Optional[bool] = Field(default=None, alias="analytics") + """ Whether this search will be included in Analytics. """ + analytics_tags: Optional[List[str]] = Field(default=None, alias="analyticsTags") + """ Tags to apply to the query for [segmenting analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). """ + percentile_computation: Optional[bool] = Field( + default=None, alias="percentileComputation" + ) + """ Whether to include this search when calculating processing-time percentiles. """ + enable_ab_test: Optional[bool] = Field(default=None, alias="enableABTest") + """ Whether to enable A/B testing for this search. """ + query: Optional[str] = Field(default=None, alias="query") + """ Search query. """ + attributes_for_faceting: Optional[List[str]] = Field( + default=None, alias="attributesForFaceting" + ) + """ Attributes used for [faceting](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/). Facets are attributes that let you categorize search results. They can be used for filtering search results. By default, no attribute is used for faceting. Attribute names are case-sensitive. **Modifiers** - `filterOnly(\"ATTRIBUTE\")`. Allows using this attribute as a filter, but doesn't evalue the facet values. - `searchable(\"ATTRIBUTE\")`. Allows searching for facet values. - `afterDistinct(\"ATTRIBUTE\")`. Evaluates the facet count _after_ deduplication with `distinct`. This ensures accurate facet counts. You can apply this modifier to searchable facets: `afterDistinct(searchable(ATTRIBUTE))`. """ + replicas: Optional[List[str]] = Field(default=None, alias="replicas") + """ Creates [replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/). Replicas are copies of a primary index with the same records but different settings, synonyms, or rules. If you want to offer a different ranking or sorting of your search results, you'll use replica indices. All index operations on a primary index are automatically forwarded to its replicas. To add a replica index, you must provide the complete set of replicas to this parameter. If you omit a replica from this list, the replica turns into a regular, standalone index that will no longer by synced with the primary index. **Modifier** - `virtual(\"REPLICA\")`. Create a virtual replica, Virtual replicas don't increase the number of records and are optimized for [Relevant sorting](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/relevant-sort/). """ + pagination_limited_to: Optional[int] = Field( + default=None, alias="paginationLimitedTo" + ) + """ Maximum number of search results that can be obtained through pagination. Higher pagination limits might slow down your search. For pagination limits above 1,000, the sorting of results beyond the 1,000th hit can't be guaranteed. """ + unretrievable_attributes: Optional[List[str]] = Field( + default=None, alias="unretrievableAttributes" + ) + """ Attributes that can't be retrieved at query time. This can be useful if you want to use an attribute for ranking or to [restrict access](https://www.algolia.com/doc/guides/security/api-keys/how-to/user-restricted-access-to-data/), but don't want to include it in the search results. Attribute names are case-sensitive. """ + disable_typo_tolerance_on_words: Optional[List[str]] = Field( + default=None, alias="disableTypoToleranceOnWords" + ) + """ Words for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). This also turns off [word splitting and concatenation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/splitting-and-concatenation/) for the specified words. """ + attributes_to_transliterate: Optional[List[str]] = Field( + default=None, alias="attributesToTransliterate" + ) + """ Attributes, for which you want to support [Japanese transliteration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#japanese-transliteration-and-type-ahead). Transliteration supports searching in any of the Japanese writing systems. To support transliteration, you must set the indexing language to Japanese. Attribute names are case-sensitive. """ + camel_case_attributes: Optional[List[str]] = Field( + default=None, alias="camelCaseAttributes" + ) + """ Attributes for which to split [camel case](https://wikipedia.org/wiki/Camel_case) words. Attribute names are case-sensitive. """ + decompounded_attributes: Optional[object] = Field( + default=None, alias="decompoundedAttributes" + ) + """ Searchable attributes to which Algolia should apply [word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-segmentation/) (decompounding). Attribute names are case-sensitive. Compound words are formed by combining two or more individual words, and are particularly prevalent in Germanic languages—for example, \"firefighter\". With decompounding, the individual components are indexed separately. You can specify different lists for different languages. Decompounding is supported for these languages: Dutch (`nl`), German (`de`), Finnish (`fi`), Danish (`da`), Swedish (`sv`), and Norwegian (`no`). Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). """ index_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="Languages for language-specific processing steps, such as word detection and dictionary settings. **You should always specify an indexing language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). ", - alias="indexLanguages", - ) - disable_prefix_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Searchable attributes for which you want to turn off [prefix matching](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/#adjusting-prefix-search). Attribute names are case-sensitive. ", - alias="disablePrefixOnAttributes", - ) - allow_compression_of_integer_array: Optional[StrictBool] = Field( - default=False, - description="Whether arrays with exclusively non-negative integers should be compressed for better performance. If true, the compressed arrays may be reordered. ", - alias="allowCompressionOfIntegerArray", - ) - numeric_attributes_for_filtering: Optional[List[StrictStr]] = Field( - default=None, - description='Numeric attributes that can be used as [numerical filters](https://www.algolia.com/doc/guides/managing-results/rules/detecting-intent/how-to/applying-a-custom-filter-for-a-specific-query/#numerical-filters). Attribute names are case-sensitive. By default, all numeric attributes are available as numerical filters. For faster indexing, reduce the number of numeric attributes. If you want to turn off filtering for all numeric attributes, specifiy an attribute that doesn\'t exist in your index, such as `NO_NUMERIC_FILTERING`. **Modifier** - `equalOnly("ATTRIBUTE")`. Support only filtering based on equality comparisons `=` and `!=`. ', - alias="numericAttributesForFiltering", - ) - separators_to_index: Optional[StrictStr] = Field( - default="", - description="Controls which separators are indexed. Separators are all non-letter characters except spaces and currency characters, such as $€£¥. By default, separator characters aren't indexed. With `separatorsToIndex`, Algolia treats separator characters as separate words. For example, a search for `C#` would report two matches. ", - alias="separatorsToIndex", - ) - searchable_attributes: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes used for searching. Attribute names are case-sensitive. By default, all attributes are searchable and the [Attribute](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#attribute) ranking criterion is turned off. With a non-empty list, Algolia only returns results with matches in the selected attributes. In addition, the Attribute ranking criterion is turned on: matches in attributes that are higher in the list of `searchableAttributes` rank first. To make matches in two attributes rank equally, include them in a comma-separated string, such as `"title,alternate_title"`. Attributes with the same priority are always unordered. For more information, see [Searchable attributes](https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/how-to/setting-searchable-attributes/). **Modifier** - `unordered("ATTRIBUTE")`. Ignore the position of a match within the attribute. Without modifier, matches at the beginning of an attribute rank higer than matches at the end. ', - alias="searchableAttributes", - ) - user_data: Optional[Dict[str, Any]] = Field( - default=None, - description="An object with custom data. You can store up to 32kB as custom data. ", - alias="userData", - ) - custom_normalization: Optional[Dict[str, Dict[str, StrictStr]]] = Field( - default=None, - description="Characters and their normalized replacements. This overrides Algolia's default [normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/). ", - alias="customNormalization", - ) - attribute_for_distinct: Optional[StrictStr] = Field( - default=None, - description="Attribute that should be used to establish groups of results. Attribute names are case-sensitive. All records with the same value for this attribute are considered a group. You can combine `attributeForDistinct` with the `distinct` search parameter to control how many items per group are included in the search results. If you want to use the same attribute also for faceting, use the `afterDistinct` modifier of the `attributesForFaceting` setting. This applies faceting _after_ deduplication, which will result in accurate facet counts. ", - alias="attributeForDistinct", - ) - attributes_to_retrieve: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `["*", "-ATTRIBUTE"]`. - The `objectID` attribute is always included. ', - alias="attributesToRetrieve", - ) - ranking: Optional[List[StrictStr]] = Field( - default=None, - description='Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they\'re specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc("ATTRIBUTE")`. Sort the index by the values of an attribute, in ascending order. - `desc("ATTRIBUTE")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). ', - ) - relevancy_strictness: Optional[StrictInt] = Field( - default=100, - description="Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. ", - alias="relevancyStrictness", - ) - attributes_to_highlight: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). ", - alias="attributesToHighlight", - ) - attributes_to_snippet: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. ", - alias="attributesToSnippet", - ) - highlight_pre_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert before the highlighted parts in all highlighted results and snippets.", - alias="highlightPreTag", - ) - highlight_post_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert after the highlighted parts in all highlighted results and snippets.", - alias="highlightPostTag", - ) - snippet_ellipsis_text: Optional[StrictStr] = Field( - default="…", - description="String used as an ellipsis indicator when a snippet is truncated.", - alias="snippetEllipsisText", - ) - restrict_highlight_and_snippet_arrays: Optional[StrictBool] = Field( - default=False, - description="Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. ", - alias="restrictHighlightAndSnippetArrays", - ) - min_word_sizefor1_typo: Optional[StrictInt] = Field( - default=4, - description="Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor1Typo", - ) - min_word_sizefor2_typos: Optional[StrictInt] = Field( - default=8, - description="Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor2Typos", - ) + default=None, alias="indexLanguages" + ) + """ Languages for language-specific processing steps, such as word detection and dictionary settings. **You should always specify an indexing language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). """ + disable_prefix_on_attributes: Optional[List[str]] = Field( + default=None, alias="disablePrefixOnAttributes" + ) + """ Searchable attributes for which you want to turn off [prefix matching](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/#adjusting-prefix-search). Attribute names are case-sensitive. """ + allow_compression_of_integer_array: Optional[bool] = Field( + default=None, alias="allowCompressionOfIntegerArray" + ) + """ Whether arrays with exclusively non-negative integers should be compressed for better performance. If true, the compressed arrays may be reordered. """ + numeric_attributes_for_filtering: Optional[List[str]] = Field( + default=None, alias="numericAttributesForFiltering" + ) + """ Numeric attributes that can be used as [numerical filters](https://www.algolia.com/doc/guides/managing-results/rules/detecting-intent/how-to/applying-a-custom-filter-for-a-specific-query/#numerical-filters). Attribute names are case-sensitive. By default, all numeric attributes are available as numerical filters. For faster indexing, reduce the number of numeric attributes. If you want to turn off filtering for all numeric attributes, specifiy an attribute that doesn't exist in your index, such as `NO_NUMERIC_FILTERING`. **Modifier** - `equalOnly(\"ATTRIBUTE\")`. Support only filtering based on equality comparisons `=` and `!=`. """ + separators_to_index: Optional[str] = Field(default=None, alias="separatorsToIndex") + """ Controls which separators are indexed. Separators are all non-letter characters except spaces and currency characters, such as $€£¥. By default, separator characters aren't indexed. With `separatorsToIndex`, Algolia treats separator characters as separate words. For example, a search for `C#` would report two matches. """ + searchable_attributes: Optional[List[str]] = Field( + default=None, alias="searchableAttributes" + ) + """ Attributes used for searching. Attribute names are case-sensitive. By default, all attributes are searchable and the [Attribute](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#attribute) ranking criterion is turned off. With a non-empty list, Algolia only returns results with matches in the selected attributes. In addition, the Attribute ranking criterion is turned on: matches in attributes that are higher in the list of `searchableAttributes` rank first. To make matches in two attributes rank equally, include them in a comma-separated string, such as `\"title,alternate_title\"`. Attributes with the same priority are always unordered. For more information, see [Searchable attributes](https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/how-to/setting-searchable-attributes/). **Modifier** - `unordered(\"ATTRIBUTE\")`. Ignore the position of a match within the attribute. Without modifier, matches at the beginning of an attribute rank higer than matches at the end. """ + user_data: Optional[object] = Field(default=None, alias="userData") + """ An object with custom data. You can store up to 32kB as custom data. """ + custom_normalization: Optional[Dict[str, Dict[str, str]]] = Field( + default=None, alias="customNormalization" + ) + """ Characters and their normalized replacements. This overrides Algolia's default [normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/). """ + attribute_for_distinct: Optional[str] = Field( + default=None, alias="attributeForDistinct" + ) + """ Attribute that should be used to establish groups of results. Attribute names are case-sensitive. All records with the same value for this attribute are considered a group. You can combine `attributeForDistinct` with the `distinct` search parameter to control how many items per group are included in the search results. If you want to use the same attribute also for faceting, use the `afterDistinct` modifier of the `attributesForFaceting` setting. This applies faceting _after_ deduplication, which will result in accurate facet counts. """ + attributes_to_retrieve: Optional[List[str]] = Field( + default=None, alias="attributesToRetrieve" + ) + """ Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `[\"*\", \"-ATTRIBUTE\"]`. - The `objectID` attribute is always included. """ + ranking: Optional[List[str]] = Field(default=None, alias="ranking") + """ Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they're specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in ascending order. - `desc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). """ + relevancy_strictness: Optional[int] = Field( + default=None, alias="relevancyStrictness" + ) + """ Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. """ + attributes_to_highlight: Optional[List[str]] = Field( + default=None, alias="attributesToHighlight" + ) + """ Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). """ + attributes_to_snippet: Optional[List[str]] = Field( + default=None, alias="attributesToSnippet" + ) + """ Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. """ + highlight_pre_tag: Optional[str] = Field(default=None, alias="highlightPreTag") + """ HTML tag to insert before the highlighted parts in all highlighted results and snippets. """ + highlight_post_tag: Optional[str] = Field(default=None, alias="highlightPostTag") + """ HTML tag to insert after the highlighted parts in all highlighted results and snippets. """ + snippet_ellipsis_text: Optional[str] = Field( + default=None, alias="snippetEllipsisText" + ) + """ String used as an ellipsis indicator when a snippet is truncated. """ + restrict_highlight_and_snippet_arrays: Optional[bool] = Field( + default=None, alias="restrictHighlightAndSnippetArrays" + ) + """ Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. """ + min_word_sizefor1_typo: Optional[int] = Field( + default=None, alias="minWordSizefor1Typo" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ + min_word_sizefor2_typos: Optional[int] = Field( + default=None, alias="minWordSizefor2Typos" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ typo_tolerance: Optional[TypoTolerance] = Field(default=None, alias="typoTolerance") - allow_typos_on_numeric_tokens: Optional[StrictBool] = Field( - default=True, - description="Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. ", - alias="allowTyposOnNumericTokens", + allow_typos_on_numeric_tokens: Optional[bool] = Field( + default=None, alias="allowTyposOnNumericTokens" ) - disable_typo_tolerance_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. ", - alias="disableTypoToleranceOnAttributes", + """ Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. """ + disable_typo_tolerance_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableTypoToleranceOnAttributes" ) + """ Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. """ ignore_plurals: Optional[IgnorePlurals] = Field(default=None, alias="ignorePlurals") remove_stop_words: Optional[RemoveStopWords] = Field( default=None, alias="removeStopWords" ) query_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). ", - alias="queryLanguages", + default=None, alias="queryLanguages" ) - decompound_query: Optional[StrictBool] = Field( - default=True, - description="Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). ", - alias="decompoundQuery", - ) - enable_rules: Optional[StrictBool] = Field( - default=True, description="Whether to enable rules.", alias="enableRules" - ) - enable_personalization: Optional[StrictBool] = Field( - default=False, - description="Whether to enable Personalization.", - alias="enablePersonalization", + """ Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). """ + decompound_query: Optional[bool] = Field(default=None, alias="decompoundQuery") + """ Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). """ + enable_rules: Optional[bool] = Field(default=None, alias="enableRules") + """ Whether to enable rules. """ + enable_personalization: Optional[bool] = Field( + default=None, alias="enablePersonalization" ) + """ Whether to enable Personalization. """ query_type: Optional[QueryType] = Field(default=None, alias="queryType") remove_words_if_no_results: Optional[RemoveWordsIfNoResults] = Field( default=None, alias="removeWordsIfNoResults" ) - advanced_syntax: Optional[StrictBool] = Field( - default=False, - description="Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. ", - alias="advancedSyntax", - ) - optional_words: Optional[List[StrictStr]] = Field( - default=None, - description='Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn\'t include the optional words. For example, if the search query is "action video" and "video" is an optional word, the search engine runs two queries. One for "action video" and one for "action". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). ', - alias="optionalWords", - ) - disable_exact_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. ", - alias="disableExactOnAttributes", + advanced_syntax: Optional[bool] = Field(default=None, alias="advancedSyntax") + """ Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. """ + optional_words: Optional[List[str]] = Field(default=None, alias="optionalWords") + """ Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn't include the optional words. For example, if the search query is \"action video\" and \"video\" is an optional word, the search engine runs two queries. One for \"action video\" and one for \"action\". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). """ + disable_exact_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableExactOnAttributes" ) + """ Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. """ exact_on_single_word_query: Optional[ExactOnSingleWordQuery] = Field( default=None, alias="exactOnSingleWordQuery" ) alternatives_as_exact: Optional[List[AlternativesAsExact]] = Field( - default=None, - description='Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as "NY/NYC" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as "NY/New York" are considered exact matches. ', - alias="alternativesAsExact", + default=None, alias="alternativesAsExact" ) + """ Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as \"NY/NYC\" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as \"NY/New York\" are considered exact matches. """ advanced_syntax_features: Optional[List[AdvancedSyntaxFeatures]] = Field( - default=None, - description='Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue "iPhone case"` only returns records with the exact string "iPhone case". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain "search" but not "engine". This setting only has an effect if `advancedSyntax` is true. ', - alias="advancedSyntaxFeatures", - ) - distinct: Optional[Distinct] = None - replace_synonyms_in_highlight: Optional[StrictBool] = Field( - default=False, - description='Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either "home" or "house" are included in the search results, and either "home" or "house" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of "house" are replaced by "home" in the highlighted response. ', - alias="replaceSynonymsInHighlight", - ) - min_proximity: Optional[Annotated[int, Field(le=7, strict=True, ge=1)]] = Field( - default=1, - description="Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. ", - alias="minProximity", - ) - response_fields: Optional[List[StrictStr]] = Field( - default=None, - description="Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. ", - alias="responseFields", - ) - max_facet_hits: Optional[Annotated[int, Field(le=100, strict=True)]] = Field( - default=10, - description="Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values).", - alias="maxFacetHits", - ) - max_values_per_facet: Optional[Annotated[int, Field(le=1000, strict=True)]] = Field( - default=100, - description="Maximum number of facet values to return for each facet.", - alias="maxValuesPerFacet", - ) - sort_facet_values_by: Optional[StrictStr] = Field( - default="count", - description="Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). ", - alias="sortFacetValuesBy", - ) - attribute_criteria_computed_by_min_proximity: Optional[StrictBool] = Field( - default=False, - description="Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. ", - alias="attributeCriteriaComputedByMinProximity", - ) + default=None, alias="advancedSyntaxFeatures" + ) + """ Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue \"iPhone case\"` only returns records with the exact string \"iPhone case\". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain \"search\" but not \"engine\". This setting only has an effect if `advancedSyntax` is true. """ + distinct: Optional[Distinct] = Field(default=None, alias="distinct") + replace_synonyms_in_highlight: Optional[bool] = Field( + default=None, alias="replaceSynonymsInHighlight" + ) + """ Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either \"home\" or \"house\" are included in the search results, and either \"home\" or \"house\" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of \"house\" are replaced by \"home\" in the highlighted response. """ + min_proximity: Optional[int] = Field(default=None, alias="minProximity") + """ Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. """ + response_fields: Optional[List[str]] = Field(default=None, alias="responseFields") + """ Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. """ + max_facet_hits: Optional[int] = Field(default=None, alias="maxFacetHits") + """ Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values). """ + max_values_per_facet: Optional[int] = Field(default=None, alias="maxValuesPerFacet") + """ Maximum number of facet values to return for each facet. """ + sort_facet_values_by: Optional[str] = Field(default=None, alias="sortFacetValuesBy") + """ Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). """ + attribute_criteria_computed_by_min_proximity: Optional[bool] = Field( + default=None, alias="attributeCriteriaComputedByMinProximity" + ) + """ Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. """ rendering_content: Optional[RenderingContent] = Field( default=None, alias="renderingContent" ) - enable_re_ranking: Optional[StrictBool] = Field( - default=True, - description="Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. ", - alias="enableReRanking", - ) + enable_re_ranking: Optional[bool] = Field(default=None, alias="enableReRanking") + """ Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. """ re_ranking_apply_filter: Optional[ReRankingApplyFilter] = Field( default=None, alias="reRankingApplyFilter" ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of FallbackParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.facet_filters: - _dict["facetFilters"] = self.facet_filters.to_dict() - if self.optional_filters: - _dict["optionalFilters"] = self.optional_filters.to_dict() - if self.numeric_filters: - _dict["numericFilters"] = self.numeric_filters.to_dict() - if self.tag_filters: - _dict["tagFilters"] = self.tag_filters.to_dict() - if self.around_radius: - _dict["aroundRadius"] = self.around_radius.to_dict() - if self.around_precision: - _dict["aroundPrecision"] = self.around_precision.to_dict() - if self.typo_tolerance: - _dict["typoTolerance"] = self.typo_tolerance.to_dict() - if self.ignore_plurals: - _dict["ignorePlurals"] = self.ignore_plurals.to_dict() - if self.remove_stop_words: - _dict["removeStopWords"] = self.remove_stop_words.to_dict() - if self.distinct: - _dict["distinct"] = self.distinct.to_dict() - if self.rendering_content: - _dict["renderingContent"] = self.rendering_content.to_dict() - if self.re_ranking_apply_filter: - _dict["reRankingApplyFilter"] = self.re_ranking_apply_filter.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of FallbackParams from a dict""" if obj is None: return None @@ -506,151 +335,73 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "similarQuery": obj.get("similarQuery"), - "filters": obj.get("filters"), - "facetFilters": ( - FacetFilters.from_dict(obj.get("facetFilters")) - if obj.get("facetFilters") is not None - else None - ), - "optionalFilters": ( - OptionalFilters.from_dict(obj.get("optionalFilters")) - if obj.get("optionalFilters") is not None - else None - ), - "numericFilters": ( - NumericFilters.from_dict(obj.get("numericFilters")) - if obj.get("numericFilters") is not None - else None - ), - "tagFilters": ( - TagFilters.from_dict(obj.get("tagFilters")) - if obj.get("tagFilters") is not None - else None - ), - "sumOrFiltersScores": obj.get("sumOrFiltersScores"), - "restrictSearchableAttributes": obj.get("restrictSearchableAttributes"), - "facets": obj.get("facets"), - "facetingAfterDistinct": obj.get("facetingAfterDistinct"), - "aroundLatLng": obj.get("aroundLatLng"), - "aroundLatLngViaIP": obj.get("aroundLatLngViaIP"), - "aroundRadius": ( - AroundRadius.from_dict(obj.get("aroundRadius")) - if obj.get("aroundRadius") is not None - else None - ), - "aroundPrecision": ( - AroundPrecision.from_dict(obj.get("aroundPrecision")) - if obj.get("aroundPrecision") is not None - else None - ), - "minimumAroundRadius": obj.get("minimumAroundRadius"), - "insideBoundingBox": obj.get("insideBoundingBox"), - "insidePolygon": obj.get("insidePolygon"), - "naturalLanguages": obj.get("naturalLanguages"), - "ruleContexts": obj.get("ruleContexts"), - "personalizationImpact": obj.get("personalizationImpact"), - "userToken": obj.get("userToken"), - "getRankingInfo": obj.get("getRankingInfo"), - "synonyms": obj.get("synonyms"), - "clickAnalytics": obj.get("clickAnalytics"), - "analytics": obj.get("analytics"), - "analyticsTags": obj.get("analyticsTags"), - "percentileComputation": obj.get("percentileComputation"), - "enableABTest": obj.get("enableABTest"), - "query": obj.get("query"), - "attributesForFaceting": obj.get("attributesForFaceting"), - "replicas": obj.get("replicas"), - "paginationLimitedTo": obj.get("paginationLimitedTo"), - "unretrievableAttributes": obj.get("unretrievableAttributes"), - "disableTypoToleranceOnWords": obj.get("disableTypoToleranceOnWords"), - "attributesToTransliterate": obj.get("attributesToTransliterate"), - "camelCaseAttributes": obj.get("camelCaseAttributes"), - "decompoundedAttributes": obj.get("decompoundedAttributes"), - "indexLanguages": obj.get("indexLanguages"), - "disablePrefixOnAttributes": obj.get("disablePrefixOnAttributes"), - "allowCompressionOfIntegerArray": obj.get( - "allowCompressionOfIntegerArray" - ), - "numericAttributesForFiltering": obj.get( - "numericAttributesForFiltering" - ), - "separatorsToIndex": obj.get("separatorsToIndex"), - "searchableAttributes": obj.get("searchableAttributes"), - "userData": obj.get("userData"), - "customNormalization": obj.get("customNormalization"), - "attributeForDistinct": obj.get("attributeForDistinct"), - "attributesToRetrieve": obj.get("attributesToRetrieve"), - "ranking": obj.get("ranking"), - "relevancyStrictness": obj.get("relevancyStrictness"), - "attributesToHighlight": obj.get("attributesToHighlight"), - "attributesToSnippet": obj.get("attributesToSnippet"), - "highlightPreTag": obj.get("highlightPreTag"), - "highlightPostTag": obj.get("highlightPostTag"), - "snippetEllipsisText": obj.get("snippetEllipsisText"), - "restrictHighlightAndSnippetArrays": obj.get( - "restrictHighlightAndSnippetArrays" - ), - "minWordSizefor1Typo": obj.get("minWordSizefor1Typo"), - "minWordSizefor2Typos": obj.get("minWordSizefor2Typos"), - "typoTolerance": ( - TypoTolerance.from_dict(obj.get("typoTolerance")) - if obj.get("typoTolerance") is not None - else None - ), - "allowTyposOnNumericTokens": obj.get("allowTyposOnNumericTokens"), - "disableTypoToleranceOnAttributes": obj.get( - "disableTypoToleranceOnAttributes" - ), - "ignorePlurals": ( - IgnorePlurals.from_dict(obj.get("ignorePlurals")) - if obj.get("ignorePlurals") is not None - else None - ), - "removeStopWords": ( - RemoveStopWords.from_dict(obj.get("removeStopWords")) - if obj.get("removeStopWords") is not None - else None - ), - "queryLanguages": obj.get("queryLanguages"), - "decompoundQuery": obj.get("decompoundQuery"), - "enableRules": obj.get("enableRules"), - "enablePersonalization": obj.get("enablePersonalization"), - "queryType": obj.get("queryType"), - "removeWordsIfNoResults": obj.get("removeWordsIfNoResults"), - "advancedSyntax": obj.get("advancedSyntax"), - "optionalWords": obj.get("optionalWords"), - "disableExactOnAttributes": obj.get("disableExactOnAttributes"), - "exactOnSingleWordQuery": obj.get("exactOnSingleWordQuery"), - "alternativesAsExact": obj.get("alternativesAsExact"), - "advancedSyntaxFeatures": obj.get("advancedSyntaxFeatures"), - "distinct": ( - Distinct.from_dict(obj.get("distinct")) - if obj.get("distinct") is not None - else None - ), - "replaceSynonymsInHighlight": obj.get("replaceSynonymsInHighlight"), - "minProximity": obj.get("minProximity"), - "responseFields": obj.get("responseFields"), - "maxFacetHits": obj.get("maxFacetHits"), - "maxValuesPerFacet": obj.get("maxValuesPerFacet"), - "sortFacetValuesBy": obj.get("sortFacetValuesBy"), - "attributeCriteriaComputedByMinProximity": obj.get( - "attributeCriteriaComputedByMinProximity" - ), - "renderingContent": ( - RenderingContent.from_dict(obj.get("renderingContent")) - if obj.get("renderingContent") is not None - else None - ), - "enableReRanking": obj.get("enableReRanking"), - "reRankingApplyFilter": ( - ReRankingApplyFilter.from_dict(obj.get("reRankingApplyFilter")) - if obj.get("reRankingApplyFilter") is not None - else None - ), - } + obj["facetFilters"] = ( + FacetFilters.from_dict(obj["facetFilters"]) + if obj.get("facetFilters") is not None + else None + ) + obj["optionalFilters"] = ( + OptionalFilters.from_dict(obj["optionalFilters"]) + if obj.get("optionalFilters") is not None + else None + ) + obj["numericFilters"] = ( + NumericFilters.from_dict(obj["numericFilters"]) + if obj.get("numericFilters") is not None + else None + ) + obj["tagFilters"] = ( + TagFilters.from_dict(obj["tagFilters"]) + if obj.get("tagFilters") is not None + else None + ) + obj["aroundRadius"] = ( + AroundRadius.from_dict(obj["aroundRadius"]) + if obj.get("aroundRadius") is not None + else None ) - return _obj + obj["aroundPrecision"] = ( + AroundPrecision.from_dict(obj["aroundPrecision"]) + if obj.get("aroundPrecision") is not None + else None + ) + obj["naturalLanguages"] = obj.get("naturalLanguages") + obj["indexLanguages"] = obj.get("indexLanguages") + obj["typoTolerance"] = ( + TypoTolerance.from_dict(obj["typoTolerance"]) + if obj.get("typoTolerance") is not None + else None + ) + obj["ignorePlurals"] = ( + IgnorePlurals.from_dict(obj["ignorePlurals"]) + if obj.get("ignorePlurals") is not None + else None + ) + obj["removeStopWords"] = ( + RemoveStopWords.from_dict(obj["removeStopWords"]) + if obj.get("removeStopWords") is not None + else None + ) + obj["queryLanguages"] = obj.get("queryLanguages") + obj["queryType"] = obj.get("queryType") + obj["removeWordsIfNoResults"] = obj.get("removeWordsIfNoResults") + obj["exactOnSingleWordQuery"] = obj.get("exactOnSingleWordQuery") + obj["alternativesAsExact"] = obj.get("alternativesAsExact") + obj["advancedSyntaxFeatures"] = obj.get("advancedSyntaxFeatures") + obj["distinct"] = ( + Distinct.from_dict(obj["distinct"]) + if obj.get("distinct") is not None + else None + ) + obj["renderingContent"] = ( + RenderingContent.from_dict(obj["renderingContent"]) + if obj.get("renderingContent") is not None + else None + ) + obj["reRankingApplyFilter"] = ( + ReRankingApplyFilter.from_dict(obj["reRankingApplyFilter"]) + if obj.get("reRankingApplyFilter") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/get_recommend_task_response.py b/algoliasearch/recommend/models/get_recommend_task_response.py index 752dcb9bb..9b8ef23f6 100644 --- a/algoliasearch/recommend/models/get_recommend_task_response.py +++ b/algoliasearch/recommend/models/get_recommend_task_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,40 +26,33 @@ class GetRecommendTaskResponse(BaseModel): GetRecommendTaskResponse """ - status: TaskStatus + status: TaskStatus = Field(alias="status") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetRecommendTaskResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetRecommendTaskResponse from a dict""" if obj is None: return None @@ -67,5 +60,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"status": obj.get("status")}) - return _obj + obj["status"] = obj.get("status") + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/get_recommendations_params.py b/algoliasearch/recommend/models/get_recommendations_params.py index 21bad2e31..f275f2885 100644 --- a/algoliasearch/recommend/models/get_recommendations_params.py +++ b/algoliasearch/recommend/models/get_recommendations_params.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -28,48 +28,34 @@ class GetRecommendationsParams(BaseModel): Recommend request body. """ - requests: List[RecommendationsRequest] = Field( - description="Recommendation request with parameters depending on the requested model." - ) + requests: List[RecommendationsRequest] = Field(alias="requests") + """ Recommendation request with parameters depending on the requested model. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetRecommendationsParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.requests: - for _item in self.requests: - if _item: - _items.append(_item.to_dict()) - _dict["requests"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetRecommendationsParams from a dict""" if obj is None: return None @@ -77,16 +63,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "requests": ( - [ - RecommendationsRequest.from_dict(_item) - for _item in obj.get("requests") - ] - if obj.get("requests") is not None - else None - ) - } + obj["requests"] = ( + [RecommendationsRequest.from_dict(_item) for _item in obj["requests"]] + if obj.get("requests") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/get_recommendations_response.py b/algoliasearch/recommend/models/get_recommendations_response.py index aa07d4ee6..a2cbc3597 100644 --- a/algoliasearch/recommend/models/get_recommendations_response.py +++ b/algoliasearch/recommend/models/get_recommendations_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,46 +28,33 @@ class GetRecommendationsResponse(BaseModel): GetRecommendationsResponse """ - results: List[RecommendationsResults] + results: List[RecommendationsResults] = Field(alias="results") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetRecommendationsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.results: - for _item in self.results: - if _item: - _items.append(_item.to_dict()) - _dict["results"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetRecommendationsResponse from a dict""" if obj is None: return None @@ -75,16 +62,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "results": ( - [ - RecommendationsResults.from_dict(_item) - for _item in obj.get("results") - ] - if obj.get("results") is not None - else None - ) - } + obj["results"] = ( + [RecommendationsResults.from_dict(_item) for _item in obj["results"]] + if obj.get("results") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/hide_consequence_object.py b/algoliasearch/recommend/models/hide_consequence_object.py index af1695adc..a0cf7dc77 100644 --- a/algoliasearch/recommend/models/hide_consequence_object.py +++ b/algoliasearch/recommend/models/hide_consequence_object.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,42 +23,34 @@ class HideConsequenceObject(BaseModel): Object ID of the recommendation you want to exclude. """ - object_id: Optional[StrictStr] = Field( - default=None, description="Unique record identifier.", alias="objectID" - ) + object_id: Optional[str] = Field(default=None, alias="objectID") + """ Unique record identifier. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of HideConsequenceObject from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of HideConsequenceObject from a dict""" if obj is None: return None @@ -66,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"objectID": obj.get("objectID")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/highlight_result.py b/algoliasearch/recommend/models/highlight_result.py index fae785a74..d65f9507b 100644 --- a/algoliasearch/recommend/models/highlight_result.py +++ b/algoliasearch/recommend/models/highlight_result.py @@ -8,7 +8,7 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union from pydantic import BaseModel, Field, ValidationError, model_serializer @@ -26,18 +26,20 @@ class HighlightResult(BaseModel): HighlightResult """ - oneof_schema_1_validator: Optional[HighlightResultOption] = None - oneof_schema_2_validator: Optional[Dict[str, HighlightResult]] = Field( - default=None, - description="Surround words that match the query with HTML tags for highlighting.", - ) - oneof_schema_3_validator: Optional[List[HighlightResult]] = Field( - default=None, - description="Surround words that match the query with HTML tags for highlighting.", - ) + oneof_schema_1_validator: Optional[HighlightResultOption] = Field(default=None) + + oneof_schema_2_validator: Optional[Dict[str, HighlightResult]] = Field(default=None) + """ Surround words that match the query with HTML tags for highlighting. """ + oneof_schema_3_validator: Optional[List[HighlightResult]] = Field(default=None) + """ Surround words that match the query with HTML tags for highlighting. """ actual_instance: Optional[ Union[Dict[str, HighlightResult], HighlightResultOption, List[HighlightResult]] ] = None + one_of_schemas: Set[str] = { + "Dict[str, HighlightResult]", + "HighlightResultOption", + "List[HighlightResult]", + } def __init__(self, *args, **kwargs) -> None: if args: @@ -65,7 +67,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of HighlightResult from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -105,17 +108,30 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[ + Union[ + Dict[str, Any], + Dict[str, HighlightResult], + HighlightResultOption, + List[HighlightResult], + ] + ]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/recommend/models/highlight_result_option.py b/algoliasearch/recommend/models/highlight_result_option.py index 068bcd271..635f52ae4 100644 --- a/algoliasearch/recommend/models/highlight_result_option.py +++ b/algoliasearch/recommend/models/highlight_result_option.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,51 +26,39 @@ class HighlightResultOption(BaseModel): Surround words that match the query with HTML tags for highlighting. """ - value: StrictStr = Field( - description="Highlighted attribute value, including HTML tags." - ) + value: str = Field(alias="value") + """ Highlighted attribute value, including HTML tags. """ match_level: MatchLevel = Field(alias="matchLevel") - matched_words: List[StrictStr] = Field( - description="List of matched words from the search query.", alias="matchedWords" - ) - fully_highlighted: Optional[StrictBool] = Field( - default=None, - description="Whether the entire attribute value is highlighted.", - alias="fullyHighlighted", - ) + matched_words: List[str] = Field(alias="matchedWords") + """ List of matched words from the search query. """ + fully_highlighted: Optional[bool] = Field(default=None, alias="fullyHighlighted") + """ Whether the entire attribute value is highlighted. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of HighlightResultOption from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of HighlightResultOption from a dict""" if obj is None: return None @@ -78,12 +66,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "value": obj.get("value"), - "matchLevel": obj.get("matchLevel"), - "matchedWords": obj.get("matchedWords"), - "fullyHighlighted": obj.get("fullyHighlighted"), - } - ) - return _obj + obj["matchLevel"] = obj.get("matchLevel") + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/ignore_plurals.py b/algoliasearch/recommend/models/ignore_plurals.py index eb311a57b..572f7b396 100644 --- a/algoliasearch/recommend/models/ignore_plurals.py +++ b/algoliasearch/recommend/models/ignore_plurals.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, Field, StrictBool, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -27,18 +27,16 @@ class IgnorePlurals(BaseModel): Treat singular, plurals, and other forms of declensions as equivalent. You should only use this feature for the languages used in your index. """ - oneof_schema_1_validator: Optional[List[SupportedLanguage]] = Field( - default=None, - description="ISO code for languages for which this feature should be active. This overrides languages you set with `queryLanguages`. ", - ) - oneof_schema_2_validator: Optional[BooleanString] = None - oneof_schema_3_validator: Optional[StrictBool] = Field( - default=False, - description="If true, `ignorePlurals` is active for all languages included in `queryLanguages`, or for all supported languages, if `queryLanguges` is empty. If false, singulars, plurals, and other declensions won't be considered equivalent. ", - ) + oneof_schema_1_validator: Optional[List[SupportedLanguage]] = Field(default=None) + """ ISO code for languages for which this feature should be active. This overrides languages you set with `queryLanguages`. """ + oneof_schema_2_validator: Optional[BooleanString] = Field(default=None) + + oneof_schema_3_validator: Optional[bool] = Field(default=None) + """ If true, `ignorePlurals` is active for all languages included in `queryLanguages`, or for all supported languages, if `queryLanguges` is empty. If false, singulars, plurals, and other declensions won't be considered equivalent. """ actual_instance: Optional[Union[BooleanString, List[SupportedLanguage], bool]] = ( None ) + one_of_schemas: Set[str] = {"BooleanString", "List[SupportedLanguage]", "bool"} def __init__(self, *args, **kwargs) -> None: if args: @@ -64,7 +62,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of IgnorePlurals from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -104,17 +103,23 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[Union[Dict[str, Any], BooleanString, List[SupportedLanguage], bool]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/recommend/models/index_settings_facets.py b/algoliasearch/recommend/models/index_settings_facets.py index 36a7a4390..212bc1b81 100644 --- a/algoliasearch/recommend/models/index_settings_facets.py +++ b/algoliasearch/recommend/models/index_settings_facets.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,34 @@ class IndexSettingsFacets(BaseModel): Order of facet names. """ - order: Optional[List[StrictStr]] = Field( - default=None, - description="Explicit order of facets or facet values. This setting lets you always show specific facets or facet values at the top of the list. ", - ) + order: Optional[List[str]] = Field(default=None, alias="order") + """ Explicit order of facets or facet values. This setting lets you always show specific facets or facet values at the top of the list. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of IndexSettingsFacets from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of IndexSettingsFacets from a dict""" if obj is None: return None @@ -67,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"order": obj.get("order")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/looking_similar_query.py b/algoliasearch/recommend/models/looking_similar_query.py index faae3a3ca..580cfb606 100644 --- a/algoliasearch/recommend/models/looking_similar_query.py +++ b/algoliasearch/recommend/models/looking_similar_query.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.recommend.models.fallback_params import FallbackParams @@ -28,69 +28,47 @@ class LookingSimilarQuery(BaseModel): LookingSimilarQuery """ - index_name: StrictStr = Field( - description="Index name (case-sensitive).", alias="indexName" - ) - threshold: Union[ - Annotated[float, Field(le=100, strict=True, ge=0)], - Annotated[int, Field(le=100, strict=True, ge=0)], - ] = Field( - description="Minimum score a recommendation must have to be included in the response." - ) - max_recommendations: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = ( - Field( - default=30, - description="Maximum number of recommendations to retrieve. By default, all recommendations are returned and no fallback request is made. Depending on the available recommendations and the other request parameters, the actual number of recommendations may be lower than this value. ", - alias="maxRecommendations", - ) - ) + index_name: str = Field(alias="indexName") + """ Index name (case-sensitive). """ + threshold: float = Field(alias="threshold") + """ Minimum score a recommendation must have to be included in the response. """ + max_recommendations: Optional[int] = Field(default=None, alias="maxRecommendations") + """ Maximum number of recommendations to retrieve. By default, all recommendations are returned and no fallback request is made. Depending on the available recommendations and the other request parameters, the actual number of recommendations may be lower than this value. """ query_parameters: Optional[RecommendSearchParams] = Field( default=None, alias="queryParameters" ) - model: LookingSimilarModel - object_id: StrictStr = Field( - description="Unique record identifier.", alias="objectID" - ) + model: LookingSimilarModel = Field(alias="model") + object_id: str = Field(alias="objectID") + """ Unique record identifier. """ fallback_parameters: Optional[FallbackParams] = Field( default=None, alias="fallbackParameters" ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of LookingSimilarQuery from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.query_parameters: - _dict["queryParameters"] = self.query_parameters.to_dict() - if self.fallback_parameters: - _dict["fallbackParameters"] = self.fallback_parameters.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of LookingSimilarQuery from a dict""" if obj is None: return None @@ -98,23 +76,16 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "indexName": obj.get("indexName"), - "threshold": obj.get("threshold"), - "maxRecommendations": obj.get("maxRecommendations"), - "queryParameters": ( - RecommendSearchParams.from_dict(obj.get("queryParameters")) - if obj.get("queryParameters") is not None - else None - ), - "model": obj.get("model"), - "objectID": obj.get("objectID"), - "fallbackParameters": ( - FallbackParams.from_dict(obj.get("fallbackParameters")) - if obj.get("fallbackParameters") is not None - else None - ), - } + obj["queryParameters"] = ( + RecommendSearchParams.from_dict(obj["queryParameters"]) + if obj.get("queryParameters") is not None + else None ) - return _obj + obj["model"] = obj.get("model") + obj["fallbackParameters"] = ( + FallbackParams.from_dict(obj["fallbackParameters"]) + if obj.get("fallbackParameters") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/match_level.py b/algoliasearch/recommend/models/match_level.py index 373e611e9..e1bfbaf0b 100644 --- a/algoliasearch/recommend/models/match_level.py +++ b/algoliasearch/recommend/models/match_level.py @@ -25,7 +25,9 @@ class MatchLevel(str, Enum): allowed enum values """ NONE = "none" + PARTIAL = "partial" + FULL = "full" @classmethod diff --git a/algoliasearch/recommend/models/matched_geo_location.py b/algoliasearch/recommend/models/matched_geo_location.py index 94c88ca7e..b5de4a639 100644 --- a/algoliasearch/recommend/models/matched_geo_location.py +++ b/algoliasearch/recommend/models/matched_geo_location.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,49 +23,38 @@ class MatchedGeoLocation(BaseModel): MatchedGeoLocation """ - lat: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, description="Latitude of the matched location." - ) - lng: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, description="Longitude of the matched location." - ) - distance: Optional[StrictInt] = Field( - default=None, - description="Distance between the matched location and the search location (in meters).", - ) + lat: Optional[float] = Field(default=None, alias="lat") + """ Latitude of the matched location. """ + lng: Optional[float] = Field(default=None, alias="lng") + """ Longitude of the matched location. """ + distance: Optional[int] = Field(default=None, alias="distance") + """ Distance between the matched location and the search location (in meters). """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of MatchedGeoLocation from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of MatchedGeoLocation from a dict""" if obj is None: return None @@ -73,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "lat": obj.get("lat"), - "lng": obj.get("lng"), - "distance": obj.get("distance"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/numeric_filters.py b/algoliasearch/recommend/models/numeric_filters.py index e96417a1f..bd805e7e8 100644 --- a/algoliasearch/recommend/models/numeric_filters.py +++ b/algoliasearch/recommend/models/numeric_filters.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, StrictStr, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -23,9 +23,12 @@ class NumericFilters(BaseModel): Filter by numeric facets. **Prefer using the `filters` parameter, which supports all filter types and combinations with boolean operators.** You can use numeric comparison operators: `<`, `<=`, `=`, `!=`, `>`, `>=`. Comparsions are precise up to 3 decimals. You can also provide ranges: `facet: TO `. The range includes the lower and upper boundaries. The same combination rules apply as for `facetFilters`. """ - oneof_schema_1_validator: Optional[List[NumericFilters]] = None - oneof_schema_2_validator: Optional[StrictStr] = None + oneof_schema_1_validator: Optional[List[NumericFilters]] = Field(default=None) + + oneof_schema_2_validator: Optional[str] = Field(default=None) + actual_instance: Optional[Union[List[NumericFilters], str]] = None + one_of_schemas: Set[str] = {"List[NumericFilters]", "str"} def __init__(self, *args, **kwargs) -> None: if args: @@ -49,7 +52,8 @@ def unwrap_actual_instance(self) -> Optional[Union[List[NumericFilters], str]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of NumericFilters from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -83,17 +87,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], List[NumericFilters], str]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/recommend/models/optional_filters.py b/algoliasearch/recommend/models/optional_filters.py index 737b83ab5..08edec6fb 100644 --- a/algoliasearch/recommend/models/optional_filters.py +++ b/algoliasearch/recommend/models/optional_filters.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, StrictStr, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -23,9 +23,12 @@ class OptionalFilters(BaseModel): Filters to promote or demote records in the search results. Optional filters work like facet filters, but they don't exclude records from the search results. Records that match the optional filter rank before records that don't match. If you're using a negative filter `facet:-value`, matching records rank after records that don't match. - Optional filters don't work on virtual replicas. - Optional filters are applied _after_ sort-by attributes. - Optional filters don't work with numeric attributes. """ - oneof_schema_1_validator: Optional[List[OptionalFilters]] = None - oneof_schema_2_validator: Optional[StrictStr] = None + oneof_schema_1_validator: Optional[List[OptionalFilters]] = Field(default=None) + + oneof_schema_2_validator: Optional[str] = Field(default=None) + actual_instance: Optional[Union[List[OptionalFilters], str]] = None + one_of_schemas: Set[str] = {"List[OptionalFilters]", "str"} def __init__(self, *args, **kwargs) -> None: if args: @@ -49,7 +52,8 @@ def unwrap_actual_instance(self) -> Optional[Union[List[OptionalFilters], str]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of OptionalFilters from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -83,17 +87,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], List[OptionalFilters], str]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/recommend/models/params_consequence.py b/algoliasearch/recommend/models/params_consequence.py index ff2920e86..4151f170d 100644 --- a/algoliasearch/recommend/models/params_consequence.py +++ b/algoliasearch/recommend/models/params_consequence.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,58 +27,39 @@ class ParamsConsequence(BaseModel): """ automatic_facet_filters: Optional[List[AutoFacetFilter]] = Field( - default=None, - description="Filter recommendations that match or don't match the same `facet:facet_value` combination as the viewed item.", - alias="automaticFacetFilters", - ) - filters: Optional[StrictStr] = Field( - default=None, - description="Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). ", - ) - optional_filters: Optional[List[StrictStr]] = Field( - default=None, - description="Filters to promote or demote records in the search results. Optional filters work like facet filters, but they don't exclude records from the search results. Records that match the optional filter rank before records that don't match. Matches with higher weights (``) rank before matches with lower weights. If you're using a negative filter `facet:-value`, matching records rank after records that don't match. ", - alias="optionalFilters", + default=None, alias="automaticFacetFilters" ) + """ Filter recommendations that match or don't match the same `facet:facet_value` combination as the viewed item. """ + filters: Optional[str] = Field(default=None, alias="filters") + """ Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). """ + optional_filters: Optional[List[str]] = Field(default=None, alias="optionalFilters") + """ Filters to promote or demote records in the search results. Optional filters work like facet filters, but they don't exclude records from the search results. Records that match the optional filter rank before records that don't match. Matches with higher weights (``) rank before matches with lower weights. If you're using a negative filter `facet:-value`, matching records rank after records that don't match. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ParamsConsequence from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.automatic_facet_filters: - for _item in self.automatic_facet_filters: - if _item: - _items.append(_item.to_dict()) - _dict["automaticFacetFilters"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ParamsConsequence from a dict""" if obj is None: return None @@ -86,18 +67,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "automaticFacetFilters": ( - [ - AutoFacetFilter.from_dict(_item) - for _item in obj.get("automaticFacetFilters") - ] - if obj.get("automaticFacetFilters") is not None - else None - ), - "filters": obj.get("filters"), - "optionalFilters": obj.get("optionalFilters"), - } + obj["automaticFacetFilters"] = ( + [AutoFacetFilter.from_dict(_item) for _item in obj["automaticFacetFilters"]] + if obj.get("automaticFacetFilters") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/personalization.py b/algoliasearch/recommend/models/personalization.py index 81aafb7ca..a6dcf022c 100644 --- a/algoliasearch/recommend/models/personalization.py +++ b/algoliasearch/recommend/models/personalization.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,48 +23,38 @@ class Personalization(BaseModel): Personalization """ - filters_score: Optional[StrictInt] = Field( - default=None, description="The score of the filters.", alias="filtersScore" - ) - ranking_score: Optional[StrictInt] = Field( - default=None, description="The score of the ranking.", alias="rankingScore" - ) - score: Optional[StrictInt] = Field( - default=None, description="The score of the event." - ) + filters_score: Optional[int] = Field(default=None, alias="filtersScore") + """ The score of the filters. """ + ranking_score: Optional[int] = Field(default=None, alias="rankingScore") + """ The score of the ranking. """ + score: Optional[int] = Field(default=None, alias="score") + """ The score of the event. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Personalization from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Personalization from a dict""" if obj is None: return None @@ -72,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "filtersScore": obj.get("filtersScore"), - "rankingScore": obj.get("rankingScore"), - "score": obj.get("score"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/promote_consequence_object.py b/algoliasearch/recommend/models/promote_consequence_object.py index 05942e6e9..7edbfda57 100644 --- a/algoliasearch/recommend/models/promote_consequence_object.py +++ b/algoliasearch/recommend/models/promote_consequence_object.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class PromoteConsequenceObject(BaseModel): @@ -23,46 +23,36 @@ class PromoteConsequenceObject(BaseModel): Object ID and position of the recommendation you want to pin. """ - object_id: Optional[StrictStr] = Field( - default=None, description="Unique record identifier.", alias="objectID" - ) - position: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=None, - description="Index in the list of recommendations where to place this item.", - ) + object_id: Optional[str] = Field(default=None, alias="objectID") + """ Unique record identifier. """ + position: Optional[int] = Field(default=None, alias="position") + """ Index in the list of recommendations where to place this item. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of PromoteConsequenceObject from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of PromoteConsequenceObject from a dict""" if obj is None: return None @@ -70,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"objectID": obj.get("objectID"), "position": obj.get("position")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/query_type.py b/algoliasearch/recommend/models/query_type.py index bf9d1b5b0..8ceeac433 100644 --- a/algoliasearch/recommend/models/query_type.py +++ b/algoliasearch/recommend/models/query_type.py @@ -25,7 +25,9 @@ class QueryType(str, Enum): allowed enum values """ PREFIXLAST = "prefixLast" + PREFIXALL = "prefixAll" + PREFIXNONE = "prefixNone" @classmethod diff --git a/algoliasearch/recommend/models/range.py b/algoliasearch/recommend/models/range.py index 14f3b0086..4cda204fa 100644 --- a/algoliasearch/recommend/models/range.py +++ b/algoliasearch/recommend/models/range.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,48 +23,36 @@ class Range(BaseModel): Range object with lower and upper values in meters to define custom ranges. """ - var_from: Optional[StrictInt] = Field( - default=None, - description="Lower boundary of a range in meters. The Geo ranking criterion considers all records within the range to be equal.", - alias="from", - ) - value: Optional[StrictInt] = Field( - default=None, - description="Upper boundary of a range in meters. The Geo ranking criterion considers all records within the range to be equal.", - ) + var_from: Optional[int] = Field(default=None, alias="from") + """ Lower boundary of a range in meters. The Geo ranking criterion considers all records within the range to be equal. """ + value: Optional[int] = Field(default=None, alias="value") + """ Upper boundary of a range in meters. The Geo ranking criterion considers all records within the range to be equal. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Range from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Range from a dict""" if obj is None: return None @@ -72,5 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"from": obj.get("from"), "value": obj.get("value")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/ranking_info.py b/algoliasearch/recommend/models/ranking_info.py index 4c45b6781..769876ae7 100644 --- a/algoliasearch/recommend/models/ranking_info.py +++ b/algoliasearch/recommend/models/ranking_info.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.recommend.models.matched_geo_location import MatchedGeoLocation @@ -27,90 +27,62 @@ class RankingInfo(BaseModel): Object with detailed information about the record's ranking. """ - filters: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=None, description="Whether a filter matched the query." - ) - first_matched_word: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Position of the first matched word in the best matching attribute of the record.", - alias="firstMatchedWord", - ) - geo_distance: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Distance between the geo location in the search query and the best matching geo location in the record, divided by the geo precision (in meters).", - alias="geoDistance", - ) - geo_precision: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field( - default=None, - description="Precision used when computing the geo distance, in meters.", - alias="geoPrecision", - ) + filters: Optional[int] = Field(default=None, alias="filters") + """ Whether a filter matched the query. """ + first_matched_word: int = Field(alias="firstMatchedWord") + """ Position of the first matched word in the best matching attribute of the record. """ + geo_distance: int = Field(alias="geoDistance") + """ Distance between the geo location in the search query and the best matching geo location in the record, divided by the geo precision (in meters). """ + geo_precision: Optional[int] = Field(default=None, alias="geoPrecision") + """ Precision used when computing the geo distance, in meters. """ matched_geo_location: Optional[MatchedGeoLocation] = Field( default=None, alias="matchedGeoLocation" ) - personalization: Optional[Personalization] = None - nb_exact_words: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of exactly matched words.", alias="nbExactWords" - ) - nb_typos: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of typos encountered when matching the record.", - alias="nbTypos", - ) - promoted: Optional[StrictBool] = Field( - default=None, description="Whether the record was promoted by a rule." - ) - proximity_distance: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=None, - description="Number of words between multiple matches in the query plus 1. For single word queries, `proximityDistance` is 0.", - alias="proximityDistance", + personalization: Optional[Personalization] = Field( + default=None, alias="personalization" ) - user_score: StrictInt = Field( - description="Overall ranking of the record, expressed as a single integer. This attribute is internal.", - alias="userScore", - ) - words: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field( - default=None, description="Number of matched words." - ) - promoted_by_re_ranking: Optional[StrictBool] = Field( - default=None, - description="Whether the record is re-ranked.", - alias="promotedByReRanking", + nb_exact_words: int = Field(alias="nbExactWords") + """ Number of exactly matched words. """ + nb_typos: int = Field(alias="nbTypos") + """ Number of typos encountered when matching the record. """ + promoted: Optional[bool] = Field(default=None, alias="promoted") + """ Whether the record was promoted by a rule. """ + proximity_distance: Optional[int] = Field(default=None, alias="proximityDistance") + """ Number of words between multiple matches in the query plus 1. For single word queries, `proximityDistance` is 0. """ + user_score: int = Field(alias="userScore") + """ Overall ranking of the record, expressed as a single integer. This attribute is internal. """ + words: Optional[int] = Field(default=None, alias="words") + """ Number of matched words. """ + promoted_by_re_ranking: Optional[bool] = Field( + default=None, alias="promotedByReRanking" ) + """ Whether the record is re-ranked. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RankingInfo from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.matched_geo_location: - _dict["matchedGeoLocation"] = self.matched_geo_location.to_dict() - if self.personalization: - _dict["personalization"] = self.personalization.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RankingInfo from a dict""" if obj is None: return None @@ -118,29 +90,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "filters": obj.get("filters"), - "firstMatchedWord": obj.get("firstMatchedWord"), - "geoDistance": obj.get("geoDistance"), - "geoPrecision": obj.get("geoPrecision"), - "matchedGeoLocation": ( - MatchedGeoLocation.from_dict(obj.get("matchedGeoLocation")) - if obj.get("matchedGeoLocation") is not None - else None - ), - "personalization": ( - Personalization.from_dict(obj.get("personalization")) - if obj.get("personalization") is not None - else None - ), - "nbExactWords": obj.get("nbExactWords"), - "nbTypos": obj.get("nbTypos"), - "promoted": obj.get("promoted"), - "proximityDistance": obj.get("proximityDistance"), - "userScore": obj.get("userScore"), - "words": obj.get("words"), - "promotedByReRanking": obj.get("promotedByReRanking"), - } + obj["matchedGeoLocation"] = ( + MatchedGeoLocation.from_dict(obj["matchedGeoLocation"]) + if obj.get("matchedGeoLocation") is not None + else None + ) + obj["personalization"] = ( + Personalization.from_dict(obj["personalization"]) + if obj.get("personalization") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/re_ranking_apply_filter.py b/algoliasearch/recommend/models/re_ranking_apply_filter.py index 051b772b3..39053345c 100644 --- a/algoliasearch/recommend/models/re_ranking_apply_filter.py +++ b/algoliasearch/recommend/models/re_ranking_apply_filter.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, StrictStr, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -23,9 +23,12 @@ class ReRankingApplyFilter(BaseModel): Restrict [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/) to records that match these filters. """ - oneof_schema_1_validator: Optional[List[ReRankingApplyFilter]] = None - oneof_schema_2_validator: Optional[StrictStr] = None + oneof_schema_1_validator: Optional[List[ReRankingApplyFilter]] = Field(default=None) + + oneof_schema_2_validator: Optional[str] = Field(default=None) + actual_instance: Optional[Union[List[ReRankingApplyFilter], str]] = None + one_of_schemas: Set[str] = {"List[ReRankingApplyFilter]", "str"} def __init__(self, *args, **kwargs) -> None: if args: @@ -51,7 +54,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of ReRankingApplyFilter from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -85,17 +89,23 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[Union[Dict[str, Any], List[ReRankingApplyFilter], str]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/recommend/models/recommend_hit.py b/algoliasearch/recommend/models/recommend_hit.py index 6b45893c7..b0a0fa5c9 100644 --- a/algoliasearch/recommend/models/recommend_hit.py +++ b/algoliasearch/recommend/models/recommend_hit.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, ClassVar, Dict, List, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.recommend.models.highlight_result import HighlightResult @@ -28,89 +28,47 @@ class RecommendHit(BaseModel): Recommend hit. """ - object_id: StrictStr = Field( - description="Unique record identifier.", alias="objectID" - ) + object_id: str = Field(alias="objectID") + """ Unique record identifier. """ highlight_result: Optional[Dict[str, HighlightResult]] = Field( - default=None, - description="Surround words that match the query with HTML tags for highlighting.", - alias="_highlightResult", + default=None, alias="_highlightResult" ) + """ Surround words that match the query with HTML tags for highlighting. """ snippet_result: Optional[Dict[str, SnippetResult]] = Field( - default=None, - description="Snippets that show the context around a matching search query.", - alias="_snippetResult", + default=None, alias="_snippetResult" ) + """ Snippets that show the context around a matching search query. """ ranking_info: Optional[RankingInfo] = Field(default=None, alias="_rankingInfo") - distinct_seq_id: Optional[StrictInt] = Field(default=None, alias="_distinctSeqID") - score: Union[ - Annotated[float, Field(le=100, strict=True, ge=0)], - Annotated[int, Field(le=100, strict=True, ge=0)], - ] = Field(description="Recommendation score.", alias="_score") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = [ - "objectID", - "_highlightResult", - "_snippetResult", - "_rankingInfo", - "_distinctSeqID", - "_score", - ] + distinct_seq_id: Optional[int] = Field(default=None, alias="_distinctSeqID") + score: float = Field(alias="_score") + """ Recommendation score. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + extra="allow", ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RecommendHit from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={ - "additional_properties", - }, exclude_none=True, exclude_unset=True, ) - _field_dict = {} - if self.highlight_result: - for _key in self.highlight_result: - if self.highlight_result[_key]: - _field_dict[_key] = self.highlight_result[_key].to_dict() - _dict["_highlightResult"] = _field_dict - _field_dict = {} - if self.snippet_result: - for _key in self.snippet_result: - if self.snippet_result[_key]: - _field_dict[_key] = self.snippet_result[_key].to_dict() - _dict["_snippetResult"] = _field_dict - if self.ranking_info: - _dict["_rankingInfo"] = self.ranking_info.to_dict() - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RecommendHit from a dict""" if obj is None: return None @@ -118,37 +76,26 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "objectID": obj.get("objectID"), - "_highlightResult": ( - dict( - (_k, HighlightResult.from_dict(_v)) - for _k, _v in obj.get("_highlightResult").items() - ) - if obj.get("_highlightResult") is not None - else None - ), - "_snippetResult": ( - dict( - (_k, SnippetResult.from_dict(_v)) - for _k, _v in obj.get("_snippetResult").items() - ) - if obj.get("_snippetResult") is not None - else None - ), - "_rankingInfo": ( - RankingInfo.from_dict(obj.get("_rankingInfo")) - if obj.get("_rankingInfo") is not None - else None - ), - "_distinctSeqID": obj.get("_distinctSeqID"), - "_score": obj.get("_score"), - } + obj["_highlightResult"] = ( + dict( + (_k, HighlightResult.from_dict(_v)) + for _k, _v in obj["_highlightResult"].items() + ) + if obj.get("_highlightResult") is not None + else None + ) + obj["_snippetResult"] = ( + dict( + (_k, SnippetResult.from_dict(_v)) + for _k, _v in obj["_snippetResult"].items() + ) + if obj.get("_snippetResult") is not None + else None + ) + obj["_rankingInfo"] = ( + RankingInfo.from_dict(obj["_rankingInfo"]) + if obj.get("_rankingInfo") is not None + else None ) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/recommend_models.py b/algoliasearch/recommend/models/recommend_models.py index 4e917beb0..fca839f9e 100644 --- a/algoliasearch/recommend/models/recommend_models.py +++ b/algoliasearch/recommend/models/recommend_models.py @@ -25,8 +25,11 @@ class RecommendModels(str, Enum): allowed enum values """ RELATED_MINUS_PRODUCTS = "related-products" + BOUGHT_MINUS_TOGETHER = "bought-together" + TRENDING_MINUS_FACETS = "trending-facets" + TRENDING_MINUS_ITEMS = "trending-items" @classmethod diff --git a/algoliasearch/recommend/models/recommend_rule.py b/algoliasearch/recommend/models/recommend_rule.py index 5bca4b0de..4905071b8 100644 --- a/algoliasearch/recommend/models/recommend_rule.py +++ b/algoliasearch/recommend/models/recommend_rule.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -29,60 +29,40 @@ class RecommendRule(BaseModel): """ metadata: Optional[RuleMetadata] = Field(default=None, alias="_metadata") - object_id: Optional[StrictStr] = Field( - default=None, - description="Unique identifier of a rule object.", - alias="objectID", - ) - condition: Optional[Condition] = None - consequence: Optional[Consequence] = None - description: Optional[StrictStr] = Field( - default=None, - description="Description of the rule's purpose. This can be helpful for display in the Algolia dashboard.", - ) - enabled: Optional[StrictBool] = Field( - default=True, - description="Indicates whether to enable the rule. If it isn't enabled, it isn't applied at query time.", - ) + object_id: Optional[str] = Field(default=None, alias="objectID") + """ Unique identifier of a rule object. """ + condition: Optional[Condition] = Field(default=None, alias="condition") + consequence: Optional[Consequence] = Field(default=None, alias="consequence") + description: Optional[str] = Field(default=None, alias="description") + """ Description of the rule's purpose. This can be helpful for display in the Algolia dashboard. """ + enabled: Optional[bool] = Field(default=None, alias="enabled") + """ Indicates whether to enable the rule. If it isn't enabled, it isn't applied at query time. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RecommendRule from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.metadata: - _dict["_metadata"] = self.metadata.to_dict() - if self.condition: - _dict["condition"] = self.condition.to_dict() - if self.consequence: - _dict["consequence"] = self.consequence.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RecommendRule from a dict""" if obj is None: return None @@ -90,26 +70,20 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "_metadata": ( - RuleMetadata.from_dict(obj.get("_metadata")) - if obj.get("_metadata") is not None - else None - ), - "objectID": obj.get("objectID"), - "condition": ( - Condition.from_dict(obj.get("condition")) - if obj.get("condition") is not None - else None - ), - "consequence": ( - Consequence.from_dict(obj.get("consequence")) - if obj.get("consequence") is not None - else None - ), - "description": obj.get("description"), - "enabled": obj.get("enabled"), - } + obj["_metadata"] = ( + RuleMetadata.from_dict(obj["_metadata"]) + if obj.get("_metadata") is not None + else None + ) + obj["condition"] = ( + Condition.from_dict(obj["condition"]) + if obj.get("condition") is not None + else None ) - return _obj + obj["consequence"] = ( + Consequence.from_dict(obj["consequence"]) + if obj.get("consequence") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/recommend_search_params.py b/algoliasearch/recommend/models/recommend_search_params.py index 49aea2fd0..44f5c5924 100644 --- a/algoliasearch/recommend/models/recommend_search_params.py +++ b/algoliasearch/recommend/models/recommend_search_params.py @@ -8,22 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional -from pydantic import ( - BaseModel, - ConfigDict, - Field, - StrictBool, - StrictFloat, - StrictInt, - StrictStr, -) +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.recommend.models.advanced_syntax_features import ( @@ -57,15 +49,10 @@ class RecommendSearchParams(BaseModel): Search parameters for filtering the recommendations. """ - similar_query: Optional[StrictStr] = Field( - default="", - description="Keywords to be used instead of the search query to conduct a more broader search. Using the `similarQuery` parameter changes other settings: - `queryType` is set to `prefixNone`. - `removeStopWords` is set to true. - `words` is set as the first ranking criterion. - All remaining words are treated as `optionalWords`. Since the `similarQuery` is supposed to do a broad search, they usually return many results. Combine it with `filters` to narrow down the list of results. ", - alias="similarQuery", - ) - filters: Optional[StrictStr] = Field( - default=None, - description="Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). ", - ) + similar_query: Optional[str] = Field(default=None, alias="similarQuery") + """ Keywords to be used instead of the search query to conduct a more broader search. Using the `similarQuery` parameter changes other settings: - `queryType` is set to `prefixNone`. - `removeStopWords` is set to true. - `words` is set as the first ranking criterion. - All remaining words are treated as `optionalWords`. Since the `similarQuery` is supposed to do a broad search, they usually return many results. Combine it with `filters` to narrow down the list of results. """ + filters: Optional[str] = Field(default=None, alias="filters") + """ Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). """ facet_filters: Optional[FacetFilters] = Field(default=None, alias="facetFilters") optional_filters: Optional[OptionalFilters] = Field( default=None, alias="optionalFilters" @@ -74,431 +61,273 @@ class RecommendSearchParams(BaseModel): default=None, alias="numericFilters" ) tag_filters: Optional[TagFilters] = Field(default=None, alias="tagFilters") - sum_or_filters_scores: Optional[StrictBool] = Field( - default=False, - description="Whether to sum all filter scores. If true, all filter scores are summed. Otherwise, the maximum filter score is kept. For more information, see [filter scores](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/#accumulating-scores-with-sumorfiltersscores). ", - alias="sumOrFiltersScores", - ) - restrict_searchable_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Restricts a search to a subset of your searchable attributes. Attribute names are case-sensitive. ", - alias="restrictSearchableAttributes", - ) - facets: Optional[List[StrictStr]] = Field( - default=None, - description="Facets for which to retrieve facet values that match the search criteria and the number of matching facet values. To retrieve all facets, use the wildcard character `*`. For more information, see [facets](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#contextual-facet-values-and-counts). ", - ) - faceting_after_distinct: Optional[StrictBool] = Field( - default=False, - description="Whether faceting should be applied after deduplication with `distinct`. This leads to accurate facet counts when using faceting in combination with `distinct`. It's usually better to use `afterDistinct` modifiers in the `attributesForFaceting` setting, as `facetingAfterDistinct` only computes correct facet counts if all records have the same facet values for the `attributeForDistinct`. ", - alias="facetingAfterDistinct", - ) - around_lat_lng: Optional[StrictStr] = Field( - default="", - description="Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude. Only records included within circle around this central location are included in the results. The radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings. This parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`. ", - alias="aroundLatLng", - ) - around_lat_lng_via_ip: Optional[StrictBool] = Field( - default=False, - description="Whether to obtain the coordinates from the request's IP address.", - alias="aroundLatLngViaIP", - ) + sum_or_filters_scores: Optional[bool] = Field( + default=None, alias="sumOrFiltersScores" + ) + """ Whether to sum all filter scores. If true, all filter scores are summed. Otherwise, the maximum filter score is kept. For more information, see [filter scores](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/#accumulating-scores-with-sumorfiltersscores). """ + restrict_searchable_attributes: Optional[List[str]] = Field( + default=None, alias="restrictSearchableAttributes" + ) + """ Restricts a search to a subset of your searchable attributes. Attribute names are case-sensitive. """ + facets: Optional[List[str]] = Field(default=None, alias="facets") + """ Facets for which to retrieve facet values that match the search criteria and the number of matching facet values. To retrieve all facets, use the wildcard character `*`. For more information, see [facets](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#contextual-facet-values-and-counts). """ + faceting_after_distinct: Optional[bool] = Field( + default=None, alias="facetingAfterDistinct" + ) + """ Whether faceting should be applied after deduplication with `distinct`. This leads to accurate facet counts when using faceting in combination with `distinct`. It's usually better to use `afterDistinct` modifiers in the `attributesForFaceting` setting, as `facetingAfterDistinct` only computes correct facet counts if all records have the same facet values for the `attributeForDistinct`. """ + around_lat_lng: Optional[str] = Field(default=None, alias="aroundLatLng") + """ Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude. Only records included within circle around this central location are included in the results. The radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings. This parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`. """ + around_lat_lng_via_ip: Optional[bool] = Field( + default=None, alias="aroundLatLngViaIP" + ) + """ Whether to obtain the coordinates from the request's IP address. """ around_radius: Optional[AroundRadius] = Field(default=None, alias="aroundRadius") around_precision: Optional[AroundPrecision] = Field( default=None, alias="aroundPrecision" ) - minimum_around_radius: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field( - default=None, - description="Minimum radius (in meters) for a search around a location when `aroundRadius` isn't set.", - alias="minimumAroundRadius", - ) - inside_bounding_box: Optional[ - List[ - Annotated[ - List[Union[StrictFloat, StrictInt]], Field(min_length=4, max_length=4) - ] - ] - ] = Field( - default=None, - description="Coordinates for a rectangular area in which to search. Each bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair: `[p1 lat, p1 long, p2 lat, p2 long]`. Provide multiple bounding boxes as nested arrays. For more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). ", - alias="insideBoundingBox", - ) - inside_polygon: Optional[ - List[ - Annotated[ - List[Union[StrictFloat, StrictInt]], - Field(min_length=6, max_length=20000), - ] - ] - ] = Field( - default=None, - description="Coordinates of a polygon in which to search. Polygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude. Provide multiple polygons as nested arrays. For more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). This parameter is ignored if you also specify `insideBoundingBox`. ", - alias="insidePolygon", - ) - natural_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="ISO language codes that adjust settings that are useful for processing natural language queries (as opposed to keyword searches): - Sets `removeStopWords` and `ignorePlurals` to the list of provided languages. - Sets `removeWordsIfNoResults` to `allOptional`. - Adds a `natural_language` attribute to `ruleContexts` and `analyticsTags`. ", - alias="naturalLanguages", - ) - rule_contexts: Optional[List[StrictStr]] = Field( - default=None, - description="Assigns a rule context to the search query. [Rule contexts](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/how-to/customize-search-results-by-platform/#whats-a-context) are strings that you can use to trigger matching rules. ", - alias="ruleContexts", - ) - personalization_impact: Optional[ - Annotated[int, Field(le=100, strict=True, ge=0)] - ] = Field( - default=100, - description="Impact that Personalization should have on this search. The higher this value is, the more Personalization determines the ranking compared to other factors. For more information, see [Understanding Personalization impact](https://www.algolia.com/doc/guides/personalization/personalizing-results/in-depth/configuring-personalization/#understanding-personalization-impact). ", - alias="personalizationImpact", - ) - user_token: Optional[StrictStr] = Field( - default=None, - description="Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - get_ranking_info: Optional[StrictBool] = Field( - default=False, - description="Whether the search response should include detailed ranking information.", - alias="getRankingInfo", - ) - synonyms: Optional[StrictBool] = Field( - default=True, - description="Whether to take into account an index's synonyms for this search.", - ) - click_analytics: Optional[StrictBool] = Field( - default=False, - description="Whether to include a `queryID` attribute in the response. The query ID is a unique identifier for a search query and is required for tracking [click and conversion events](https://www.algolia.com/guides/sending-events/getting-started/). ", - alias="clickAnalytics", - ) - analytics: Optional[StrictBool] = Field( - default=True, description="Whether this search will be included in Analytics." - ) - analytics_tags: Optional[List[StrictStr]] = Field( - default=None, - description="Tags to apply to the query for [segmenting analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/).", - alias="analyticsTags", - ) - percentile_computation: Optional[StrictBool] = Field( - default=True, - description="Whether to include this search when calculating processing-time percentiles.", - alias="percentileComputation", - ) - enable_ab_test: Optional[StrictBool] = Field( - default=True, - description="Whether to enable A/B testing for this search.", - alias="enableABTest", - ) - query: Optional[StrictStr] = Field(default="", description="Search query.") - attributes_for_faceting: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes used for [faceting](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/). Facets are attributes that let you categorize search results. They can be used for filtering search results. By default, no attribute is used for faceting. Attribute names are case-sensitive. **Modifiers** - `filterOnly("ATTRIBUTE")`. Allows using this attribute as a filter, but doesn\'t evalue the facet values. - `searchable("ATTRIBUTE")`. Allows searching for facet values. - `afterDistinct("ATTRIBUTE")`. Evaluates the facet count _after_ deduplication with `distinct`. This ensures accurate facet counts. You can apply this modifier to searchable facets: `afterDistinct(searchable(ATTRIBUTE))`. ', - alias="attributesForFaceting", - ) - replicas: Optional[List[StrictStr]] = Field( - default=None, - description="Creates [replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/). Replicas are copies of a primary index with the same records but different settings, synonyms, or rules. If you want to offer a different ranking or sorting of your search results, you'll use replica indices. All index operations on a primary index are automatically forwarded to its replicas. To add a replica index, you must provide the complete set of replicas to this parameter. If you omit a replica from this list, the replica turns into a regular, standalone index that will no longer by synced with the primary index. **Modifier** - `virtual(\"REPLICA\")`. Create a virtual replica, Virtual replicas don't increase the number of records and are optimized for [Relevant sorting](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/relevant-sort/). ", - ) - pagination_limited_to: Optional[Annotated[int, Field(le=20000, strict=True)]] = ( - Field( - default=1000, - description="Maximum number of search results that can be obtained through pagination. Higher pagination limits might slow down your search. For pagination limits above 1,000, the sorting of results beyond the 1,000th hit can't be guaranteed. ", - alias="paginationLimitedTo", - ) - ) - unretrievable_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes that can't be retrieved at query time. This can be useful if you want to use an attribute for ranking or to [restrict access](https://www.algolia.com/doc/guides/security/api-keys/how-to/user-restricted-access-to-data/), but don't want to include it in the search results. Attribute names are case-sensitive. ", - alias="unretrievableAttributes", + minimum_around_radius: Optional[int] = Field( + default=None, alias="minimumAroundRadius" ) - disable_typo_tolerance_on_words: Optional[List[StrictStr]] = Field( - default=None, - description="Words for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). This also turns off [word splitting and concatenation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/splitting-and-concatenation/) for the specified words. ", - alias="disableTypoToleranceOnWords", + """ Minimum radius (in meters) for a search around a location when `aroundRadius` isn't set. """ + inside_bounding_box: Optional[List[List[float]]] = Field( + default=None, alias="insideBoundingBox" ) - attributes_to_transliterate: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes, for which you want to support [Japanese transliteration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#japanese-transliteration-and-type-ahead). Transliteration supports searching in any of the Japanese writing systems. To support transliteration, you must set the indexing language to Japanese. Attribute names are case-sensitive. ", - alias="attributesToTransliterate", - ) - camel_case_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which to split [camel case](https://wikipedia.org/wiki/Camel_case) words. Attribute names are case-sensitive. ", - alias="camelCaseAttributes", - ) - decompounded_attributes: Optional[Dict[str, Any]] = Field( - default=None, - description="Searchable attributes to which Algolia should apply [word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-segmentation/) (decompounding). Attribute names are case-sensitive. Compound words are formed by combining two or more individual words, and are particularly prevalent in Germanic languages—for example, \"firefighter\". With decompounding, the individual components are indexed separately. You can specify different lists for different languages. Decompounding is supported for these languages: Dutch (`nl`), German (`de`), Finnish (`fi`), Danish (`da`), Swedish (`sv`), and Norwegian (`no`). Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). ", - alias="decompoundedAttributes", + """ Coordinates for a rectangular area in which to search. Each bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair: `[p1 lat, p1 long, p2 lat, p2 long]`. Provide multiple bounding boxes as nested arrays. For more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). """ + inside_polygon: Optional[List[List[float]]] = Field( + default=None, alias="insidePolygon" ) + """ Coordinates of a polygon in which to search. Polygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude. Provide multiple polygons as nested arrays. For more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). This parameter is ignored if you also specify `insideBoundingBox`. """ + natural_languages: Optional[List[SupportedLanguage]] = Field( + default=None, alias="naturalLanguages" + ) + """ ISO language codes that adjust settings that are useful for processing natural language queries (as opposed to keyword searches): - Sets `removeStopWords` and `ignorePlurals` to the list of provided languages. - Sets `removeWordsIfNoResults` to `allOptional`. - Adds a `natural_language` attribute to `ruleContexts` and `analyticsTags`. """ + rule_contexts: Optional[List[str]] = Field(default=None, alias="ruleContexts") + """ Assigns a rule context to the search query. [Rule contexts](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/how-to/customize-search-results-by-platform/#whats-a-context) are strings that you can use to trigger matching rules. """ + personalization_impact: Optional[int] = Field( + default=None, alias="personalizationImpact" + ) + """ Impact that Personalization should have on this search. The higher this value is, the more Personalization determines the ranking compared to other factors. For more information, see [Understanding Personalization impact](https://www.algolia.com/doc/guides/personalization/personalizing-results/in-depth/configuring-personalization/#understanding-personalization-impact). """ + user_token: Optional[str] = Field(default=None, alias="userToken") + """ Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + get_ranking_info: Optional[bool] = Field(default=None, alias="getRankingInfo") + """ Whether the search response should include detailed ranking information. """ + synonyms: Optional[bool] = Field(default=None, alias="synonyms") + """ Whether to take into account an index's synonyms for this search. """ + click_analytics: Optional[bool] = Field(default=None, alias="clickAnalytics") + """ Whether to include a `queryID` attribute in the response. The query ID is a unique identifier for a search query and is required for tracking [click and conversion events](https://www.algolia.com/guides/sending-events/getting-started/). """ + analytics: Optional[bool] = Field(default=None, alias="analytics") + """ Whether this search will be included in Analytics. """ + analytics_tags: Optional[List[str]] = Field(default=None, alias="analyticsTags") + """ Tags to apply to the query for [segmenting analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). """ + percentile_computation: Optional[bool] = Field( + default=None, alias="percentileComputation" + ) + """ Whether to include this search when calculating processing-time percentiles. """ + enable_ab_test: Optional[bool] = Field(default=None, alias="enableABTest") + """ Whether to enable A/B testing for this search. """ + query: Optional[str] = Field(default=None, alias="query") + """ Search query. """ + attributes_for_faceting: Optional[List[str]] = Field( + default=None, alias="attributesForFaceting" + ) + """ Attributes used for [faceting](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/). Facets are attributes that let you categorize search results. They can be used for filtering search results. By default, no attribute is used for faceting. Attribute names are case-sensitive. **Modifiers** - `filterOnly(\"ATTRIBUTE\")`. Allows using this attribute as a filter, but doesn't evalue the facet values. - `searchable(\"ATTRIBUTE\")`. Allows searching for facet values. - `afterDistinct(\"ATTRIBUTE\")`. Evaluates the facet count _after_ deduplication with `distinct`. This ensures accurate facet counts. You can apply this modifier to searchable facets: `afterDistinct(searchable(ATTRIBUTE))`. """ + replicas: Optional[List[str]] = Field(default=None, alias="replicas") + """ Creates [replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/). Replicas are copies of a primary index with the same records but different settings, synonyms, or rules. If you want to offer a different ranking or sorting of your search results, you'll use replica indices. All index operations on a primary index are automatically forwarded to its replicas. To add a replica index, you must provide the complete set of replicas to this parameter. If you omit a replica from this list, the replica turns into a regular, standalone index that will no longer by synced with the primary index. **Modifier** - `virtual(\"REPLICA\")`. Create a virtual replica, Virtual replicas don't increase the number of records and are optimized for [Relevant sorting](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/relevant-sort/). """ + pagination_limited_to: Optional[int] = Field( + default=None, alias="paginationLimitedTo" + ) + """ Maximum number of search results that can be obtained through pagination. Higher pagination limits might slow down your search. For pagination limits above 1,000, the sorting of results beyond the 1,000th hit can't be guaranteed. """ + unretrievable_attributes: Optional[List[str]] = Field( + default=None, alias="unretrievableAttributes" + ) + """ Attributes that can't be retrieved at query time. This can be useful if you want to use an attribute for ranking or to [restrict access](https://www.algolia.com/doc/guides/security/api-keys/how-to/user-restricted-access-to-data/), but don't want to include it in the search results. Attribute names are case-sensitive. """ + disable_typo_tolerance_on_words: Optional[List[str]] = Field( + default=None, alias="disableTypoToleranceOnWords" + ) + """ Words for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). This also turns off [word splitting and concatenation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/splitting-and-concatenation/) for the specified words. """ + attributes_to_transliterate: Optional[List[str]] = Field( + default=None, alias="attributesToTransliterate" + ) + """ Attributes, for which you want to support [Japanese transliteration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#japanese-transliteration-and-type-ahead). Transliteration supports searching in any of the Japanese writing systems. To support transliteration, you must set the indexing language to Japanese. Attribute names are case-sensitive. """ + camel_case_attributes: Optional[List[str]] = Field( + default=None, alias="camelCaseAttributes" + ) + """ Attributes for which to split [camel case](https://wikipedia.org/wiki/Camel_case) words. Attribute names are case-sensitive. """ + decompounded_attributes: Optional[object] = Field( + default=None, alias="decompoundedAttributes" + ) + """ Searchable attributes to which Algolia should apply [word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-segmentation/) (decompounding). Attribute names are case-sensitive. Compound words are formed by combining two or more individual words, and are particularly prevalent in Germanic languages—for example, \"firefighter\". With decompounding, the individual components are indexed separately. You can specify different lists for different languages. Decompounding is supported for these languages: Dutch (`nl`), German (`de`), Finnish (`fi`), Danish (`da`), Swedish (`sv`), and Norwegian (`no`). Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). """ index_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="Languages for language-specific processing steps, such as word detection and dictionary settings. **You should always specify an indexing language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). ", - alias="indexLanguages", - ) - disable_prefix_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Searchable attributes for which you want to turn off [prefix matching](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/#adjusting-prefix-search). Attribute names are case-sensitive. ", - alias="disablePrefixOnAttributes", - ) - allow_compression_of_integer_array: Optional[StrictBool] = Field( - default=False, - description="Whether arrays with exclusively non-negative integers should be compressed for better performance. If true, the compressed arrays may be reordered. ", - alias="allowCompressionOfIntegerArray", - ) - numeric_attributes_for_filtering: Optional[List[StrictStr]] = Field( - default=None, - description='Numeric attributes that can be used as [numerical filters](https://www.algolia.com/doc/guides/managing-results/rules/detecting-intent/how-to/applying-a-custom-filter-for-a-specific-query/#numerical-filters). Attribute names are case-sensitive. By default, all numeric attributes are available as numerical filters. For faster indexing, reduce the number of numeric attributes. If you want to turn off filtering for all numeric attributes, specifiy an attribute that doesn\'t exist in your index, such as `NO_NUMERIC_FILTERING`. **Modifier** - `equalOnly("ATTRIBUTE")`. Support only filtering based on equality comparisons `=` and `!=`. ', - alias="numericAttributesForFiltering", - ) - separators_to_index: Optional[StrictStr] = Field( - default="", - description="Controls which separators are indexed. Separators are all non-letter characters except spaces and currency characters, such as $€£¥. By default, separator characters aren't indexed. With `separatorsToIndex`, Algolia treats separator characters as separate words. For example, a search for `C#` would report two matches. ", - alias="separatorsToIndex", - ) - searchable_attributes: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes used for searching. Attribute names are case-sensitive. By default, all attributes are searchable and the [Attribute](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#attribute) ranking criterion is turned off. With a non-empty list, Algolia only returns results with matches in the selected attributes. In addition, the Attribute ranking criterion is turned on: matches in attributes that are higher in the list of `searchableAttributes` rank first. To make matches in two attributes rank equally, include them in a comma-separated string, such as `"title,alternate_title"`. Attributes with the same priority are always unordered. For more information, see [Searchable attributes](https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/how-to/setting-searchable-attributes/). **Modifier** - `unordered("ATTRIBUTE")`. Ignore the position of a match within the attribute. Without modifier, matches at the beginning of an attribute rank higer than matches at the end. ', - alias="searchableAttributes", - ) - user_data: Optional[Dict[str, Any]] = Field( - default=None, - description="An object with custom data. You can store up to 32kB as custom data. ", - alias="userData", - ) - custom_normalization: Optional[Dict[str, Dict[str, StrictStr]]] = Field( - default=None, - description="Characters and their normalized replacements. This overrides Algolia's default [normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/). ", - alias="customNormalization", - ) - attribute_for_distinct: Optional[StrictStr] = Field( - default=None, - description="Attribute that should be used to establish groups of results. Attribute names are case-sensitive. All records with the same value for this attribute are considered a group. You can combine `attributeForDistinct` with the `distinct` search parameter to control how many items per group are included in the search results. If you want to use the same attribute also for faceting, use the `afterDistinct` modifier of the `attributesForFaceting` setting. This applies faceting _after_ deduplication, which will result in accurate facet counts. ", - alias="attributeForDistinct", - ) - attributes_to_retrieve: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `["*", "-ATTRIBUTE"]`. - The `objectID` attribute is always included. ', - alias="attributesToRetrieve", - ) - ranking: Optional[List[StrictStr]] = Field( - default=None, - description='Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they\'re specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc("ATTRIBUTE")`. Sort the index by the values of an attribute, in ascending order. - `desc("ATTRIBUTE")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). ', - ) - relevancy_strictness: Optional[StrictInt] = Field( - default=100, - description="Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. ", - alias="relevancyStrictness", - ) - attributes_to_highlight: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). ", - alias="attributesToHighlight", - ) - attributes_to_snippet: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. ", - alias="attributesToSnippet", - ) - highlight_pre_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert before the highlighted parts in all highlighted results and snippets.", - alias="highlightPreTag", - ) - highlight_post_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert after the highlighted parts in all highlighted results and snippets.", - alias="highlightPostTag", - ) - snippet_ellipsis_text: Optional[StrictStr] = Field( - default="…", - description="String used as an ellipsis indicator when a snippet is truncated.", - alias="snippetEllipsisText", - ) - restrict_highlight_and_snippet_arrays: Optional[StrictBool] = Field( - default=False, - description="Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. ", - alias="restrictHighlightAndSnippetArrays", - ) - min_word_sizefor1_typo: Optional[StrictInt] = Field( - default=4, - description="Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor1Typo", - ) - min_word_sizefor2_typos: Optional[StrictInt] = Field( - default=8, - description="Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor2Typos", - ) + default=None, alias="indexLanguages" + ) + """ Languages for language-specific processing steps, such as word detection and dictionary settings. **You should always specify an indexing language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). """ + disable_prefix_on_attributes: Optional[List[str]] = Field( + default=None, alias="disablePrefixOnAttributes" + ) + """ Searchable attributes for which you want to turn off [prefix matching](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/#adjusting-prefix-search). Attribute names are case-sensitive. """ + allow_compression_of_integer_array: Optional[bool] = Field( + default=None, alias="allowCompressionOfIntegerArray" + ) + """ Whether arrays with exclusively non-negative integers should be compressed for better performance. If true, the compressed arrays may be reordered. """ + numeric_attributes_for_filtering: Optional[List[str]] = Field( + default=None, alias="numericAttributesForFiltering" + ) + """ Numeric attributes that can be used as [numerical filters](https://www.algolia.com/doc/guides/managing-results/rules/detecting-intent/how-to/applying-a-custom-filter-for-a-specific-query/#numerical-filters). Attribute names are case-sensitive. By default, all numeric attributes are available as numerical filters. For faster indexing, reduce the number of numeric attributes. If you want to turn off filtering for all numeric attributes, specifiy an attribute that doesn't exist in your index, such as `NO_NUMERIC_FILTERING`. **Modifier** - `equalOnly(\"ATTRIBUTE\")`. Support only filtering based on equality comparisons `=` and `!=`. """ + separators_to_index: Optional[str] = Field(default=None, alias="separatorsToIndex") + """ Controls which separators are indexed. Separators are all non-letter characters except spaces and currency characters, such as $€£¥. By default, separator characters aren't indexed. With `separatorsToIndex`, Algolia treats separator characters as separate words. For example, a search for `C#` would report two matches. """ + searchable_attributes: Optional[List[str]] = Field( + default=None, alias="searchableAttributes" + ) + """ Attributes used for searching. Attribute names are case-sensitive. By default, all attributes are searchable and the [Attribute](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#attribute) ranking criterion is turned off. With a non-empty list, Algolia only returns results with matches in the selected attributes. In addition, the Attribute ranking criterion is turned on: matches in attributes that are higher in the list of `searchableAttributes` rank first. To make matches in two attributes rank equally, include them in a comma-separated string, such as `\"title,alternate_title\"`. Attributes with the same priority are always unordered. For more information, see [Searchable attributes](https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/how-to/setting-searchable-attributes/). **Modifier** - `unordered(\"ATTRIBUTE\")`. Ignore the position of a match within the attribute. Without modifier, matches at the beginning of an attribute rank higer than matches at the end. """ + user_data: Optional[object] = Field(default=None, alias="userData") + """ An object with custom data. You can store up to 32kB as custom data. """ + custom_normalization: Optional[Dict[str, Dict[str, str]]] = Field( + default=None, alias="customNormalization" + ) + """ Characters and their normalized replacements. This overrides Algolia's default [normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/). """ + attribute_for_distinct: Optional[str] = Field( + default=None, alias="attributeForDistinct" + ) + """ Attribute that should be used to establish groups of results. Attribute names are case-sensitive. All records with the same value for this attribute are considered a group. You can combine `attributeForDistinct` with the `distinct` search parameter to control how many items per group are included in the search results. If you want to use the same attribute also for faceting, use the `afterDistinct` modifier of the `attributesForFaceting` setting. This applies faceting _after_ deduplication, which will result in accurate facet counts. """ + attributes_to_retrieve: Optional[List[str]] = Field( + default=None, alias="attributesToRetrieve" + ) + """ Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `[\"*\", \"-ATTRIBUTE\"]`. - The `objectID` attribute is always included. """ + ranking: Optional[List[str]] = Field(default=None, alias="ranking") + """ Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they're specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in ascending order. - `desc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). """ + relevancy_strictness: Optional[int] = Field( + default=None, alias="relevancyStrictness" + ) + """ Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. """ + attributes_to_highlight: Optional[List[str]] = Field( + default=None, alias="attributesToHighlight" + ) + """ Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). """ + attributes_to_snippet: Optional[List[str]] = Field( + default=None, alias="attributesToSnippet" + ) + """ Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. """ + highlight_pre_tag: Optional[str] = Field(default=None, alias="highlightPreTag") + """ HTML tag to insert before the highlighted parts in all highlighted results and snippets. """ + highlight_post_tag: Optional[str] = Field(default=None, alias="highlightPostTag") + """ HTML tag to insert after the highlighted parts in all highlighted results and snippets. """ + snippet_ellipsis_text: Optional[str] = Field( + default=None, alias="snippetEllipsisText" + ) + """ String used as an ellipsis indicator when a snippet is truncated. """ + restrict_highlight_and_snippet_arrays: Optional[bool] = Field( + default=None, alias="restrictHighlightAndSnippetArrays" + ) + """ Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. """ + min_word_sizefor1_typo: Optional[int] = Field( + default=None, alias="minWordSizefor1Typo" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ + min_word_sizefor2_typos: Optional[int] = Field( + default=None, alias="minWordSizefor2Typos" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ typo_tolerance: Optional[TypoTolerance] = Field(default=None, alias="typoTolerance") - allow_typos_on_numeric_tokens: Optional[StrictBool] = Field( - default=True, - description="Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. ", - alias="allowTyposOnNumericTokens", + allow_typos_on_numeric_tokens: Optional[bool] = Field( + default=None, alias="allowTyposOnNumericTokens" ) - disable_typo_tolerance_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. ", - alias="disableTypoToleranceOnAttributes", + """ Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. """ + disable_typo_tolerance_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableTypoToleranceOnAttributes" ) + """ Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. """ ignore_plurals: Optional[IgnorePlurals] = Field(default=None, alias="ignorePlurals") remove_stop_words: Optional[RemoveStopWords] = Field( default=None, alias="removeStopWords" ) query_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). ", - alias="queryLanguages", + default=None, alias="queryLanguages" ) - decompound_query: Optional[StrictBool] = Field( - default=True, - description="Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). ", - alias="decompoundQuery", - ) - enable_rules: Optional[StrictBool] = Field( - default=True, description="Whether to enable rules.", alias="enableRules" - ) - enable_personalization: Optional[StrictBool] = Field( - default=False, - description="Whether to enable Personalization.", - alias="enablePersonalization", + """ Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). """ + decompound_query: Optional[bool] = Field(default=None, alias="decompoundQuery") + """ Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). """ + enable_rules: Optional[bool] = Field(default=None, alias="enableRules") + """ Whether to enable rules. """ + enable_personalization: Optional[bool] = Field( + default=None, alias="enablePersonalization" ) + """ Whether to enable Personalization. """ query_type: Optional[QueryType] = Field(default=None, alias="queryType") remove_words_if_no_results: Optional[RemoveWordsIfNoResults] = Field( default=None, alias="removeWordsIfNoResults" ) - advanced_syntax: Optional[StrictBool] = Field( - default=False, - description="Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. ", - alias="advancedSyntax", - ) - optional_words: Optional[List[StrictStr]] = Field( - default=None, - description='Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn\'t include the optional words. For example, if the search query is "action video" and "video" is an optional word, the search engine runs two queries. One for "action video" and one for "action". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). ', - alias="optionalWords", - ) - disable_exact_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. ", - alias="disableExactOnAttributes", + advanced_syntax: Optional[bool] = Field(default=None, alias="advancedSyntax") + """ Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. """ + optional_words: Optional[List[str]] = Field(default=None, alias="optionalWords") + """ Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn't include the optional words. For example, if the search query is \"action video\" and \"video\" is an optional word, the search engine runs two queries. One for \"action video\" and one for \"action\". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). """ + disable_exact_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableExactOnAttributes" ) + """ Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. """ exact_on_single_word_query: Optional[ExactOnSingleWordQuery] = Field( default=None, alias="exactOnSingleWordQuery" ) alternatives_as_exact: Optional[List[AlternativesAsExact]] = Field( - default=None, - description='Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as "NY/NYC" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as "NY/New York" are considered exact matches. ', - alias="alternativesAsExact", + default=None, alias="alternativesAsExact" ) + """ Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as \"NY/NYC\" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as \"NY/New York\" are considered exact matches. """ advanced_syntax_features: Optional[List[AdvancedSyntaxFeatures]] = Field( - default=None, - description='Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue "iPhone case"` only returns records with the exact string "iPhone case". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain "search" but not "engine". This setting only has an effect if `advancedSyntax` is true. ', - alias="advancedSyntaxFeatures", - ) - distinct: Optional[Distinct] = None - replace_synonyms_in_highlight: Optional[StrictBool] = Field( - default=False, - description='Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either "home" or "house" are included in the search results, and either "home" or "house" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of "house" are replaced by "home" in the highlighted response. ', - alias="replaceSynonymsInHighlight", - ) - min_proximity: Optional[Annotated[int, Field(le=7, strict=True, ge=1)]] = Field( - default=1, - description="Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. ", - alias="minProximity", - ) - response_fields: Optional[List[StrictStr]] = Field( - default=None, - description="Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. ", - alias="responseFields", - ) - max_facet_hits: Optional[Annotated[int, Field(le=100, strict=True)]] = Field( - default=10, - description="Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values).", - alias="maxFacetHits", - ) - max_values_per_facet: Optional[Annotated[int, Field(le=1000, strict=True)]] = Field( - default=100, - description="Maximum number of facet values to return for each facet.", - alias="maxValuesPerFacet", - ) - sort_facet_values_by: Optional[StrictStr] = Field( - default="count", - description="Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). ", - alias="sortFacetValuesBy", - ) - attribute_criteria_computed_by_min_proximity: Optional[StrictBool] = Field( - default=False, - description="Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. ", - alias="attributeCriteriaComputedByMinProximity", - ) + default=None, alias="advancedSyntaxFeatures" + ) + """ Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue \"iPhone case\"` only returns records with the exact string \"iPhone case\". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain \"search\" but not \"engine\". This setting only has an effect if `advancedSyntax` is true. """ + distinct: Optional[Distinct] = Field(default=None, alias="distinct") + replace_synonyms_in_highlight: Optional[bool] = Field( + default=None, alias="replaceSynonymsInHighlight" + ) + """ Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either \"home\" or \"house\" are included in the search results, and either \"home\" or \"house\" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of \"house\" are replaced by \"home\" in the highlighted response. """ + min_proximity: Optional[int] = Field(default=None, alias="minProximity") + """ Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. """ + response_fields: Optional[List[str]] = Field(default=None, alias="responseFields") + """ Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. """ + max_facet_hits: Optional[int] = Field(default=None, alias="maxFacetHits") + """ Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values). """ + max_values_per_facet: Optional[int] = Field(default=None, alias="maxValuesPerFacet") + """ Maximum number of facet values to return for each facet. """ + sort_facet_values_by: Optional[str] = Field(default=None, alias="sortFacetValuesBy") + """ Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). """ + attribute_criteria_computed_by_min_proximity: Optional[bool] = Field( + default=None, alias="attributeCriteriaComputedByMinProximity" + ) + """ Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. """ rendering_content: Optional[RenderingContent] = Field( default=None, alias="renderingContent" ) - enable_re_ranking: Optional[StrictBool] = Field( - default=True, - description="Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. ", - alias="enableReRanking", - ) + enable_re_ranking: Optional[bool] = Field(default=None, alias="enableReRanking") + """ Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. """ re_ranking_apply_filter: Optional[ReRankingApplyFilter] = Field( default=None, alias="reRankingApplyFilter" ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RecommendSearchParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.facet_filters: - _dict["facetFilters"] = self.facet_filters.to_dict() - if self.optional_filters: - _dict["optionalFilters"] = self.optional_filters.to_dict() - if self.numeric_filters: - _dict["numericFilters"] = self.numeric_filters.to_dict() - if self.tag_filters: - _dict["tagFilters"] = self.tag_filters.to_dict() - if self.around_radius: - _dict["aroundRadius"] = self.around_radius.to_dict() - if self.around_precision: - _dict["aroundPrecision"] = self.around_precision.to_dict() - if self.typo_tolerance: - _dict["typoTolerance"] = self.typo_tolerance.to_dict() - if self.ignore_plurals: - _dict["ignorePlurals"] = self.ignore_plurals.to_dict() - if self.remove_stop_words: - _dict["removeStopWords"] = self.remove_stop_words.to_dict() - if self.distinct: - _dict["distinct"] = self.distinct.to_dict() - if self.rendering_content: - _dict["renderingContent"] = self.rendering_content.to_dict() - if self.re_ranking_apply_filter: - _dict["reRankingApplyFilter"] = self.re_ranking_apply_filter.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RecommendSearchParams from a dict""" if obj is None: return None @@ -506,151 +335,73 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "similarQuery": obj.get("similarQuery"), - "filters": obj.get("filters"), - "facetFilters": ( - FacetFilters.from_dict(obj.get("facetFilters")) - if obj.get("facetFilters") is not None - else None - ), - "optionalFilters": ( - OptionalFilters.from_dict(obj.get("optionalFilters")) - if obj.get("optionalFilters") is not None - else None - ), - "numericFilters": ( - NumericFilters.from_dict(obj.get("numericFilters")) - if obj.get("numericFilters") is not None - else None - ), - "tagFilters": ( - TagFilters.from_dict(obj.get("tagFilters")) - if obj.get("tagFilters") is not None - else None - ), - "sumOrFiltersScores": obj.get("sumOrFiltersScores"), - "restrictSearchableAttributes": obj.get("restrictSearchableAttributes"), - "facets": obj.get("facets"), - "facetingAfterDistinct": obj.get("facetingAfterDistinct"), - "aroundLatLng": obj.get("aroundLatLng"), - "aroundLatLngViaIP": obj.get("aroundLatLngViaIP"), - "aroundRadius": ( - AroundRadius.from_dict(obj.get("aroundRadius")) - if obj.get("aroundRadius") is not None - else None - ), - "aroundPrecision": ( - AroundPrecision.from_dict(obj.get("aroundPrecision")) - if obj.get("aroundPrecision") is not None - else None - ), - "minimumAroundRadius": obj.get("minimumAroundRadius"), - "insideBoundingBox": obj.get("insideBoundingBox"), - "insidePolygon": obj.get("insidePolygon"), - "naturalLanguages": obj.get("naturalLanguages"), - "ruleContexts": obj.get("ruleContexts"), - "personalizationImpact": obj.get("personalizationImpact"), - "userToken": obj.get("userToken"), - "getRankingInfo": obj.get("getRankingInfo"), - "synonyms": obj.get("synonyms"), - "clickAnalytics": obj.get("clickAnalytics"), - "analytics": obj.get("analytics"), - "analyticsTags": obj.get("analyticsTags"), - "percentileComputation": obj.get("percentileComputation"), - "enableABTest": obj.get("enableABTest"), - "query": obj.get("query"), - "attributesForFaceting": obj.get("attributesForFaceting"), - "replicas": obj.get("replicas"), - "paginationLimitedTo": obj.get("paginationLimitedTo"), - "unretrievableAttributes": obj.get("unretrievableAttributes"), - "disableTypoToleranceOnWords": obj.get("disableTypoToleranceOnWords"), - "attributesToTransliterate": obj.get("attributesToTransliterate"), - "camelCaseAttributes": obj.get("camelCaseAttributes"), - "decompoundedAttributes": obj.get("decompoundedAttributes"), - "indexLanguages": obj.get("indexLanguages"), - "disablePrefixOnAttributes": obj.get("disablePrefixOnAttributes"), - "allowCompressionOfIntegerArray": obj.get( - "allowCompressionOfIntegerArray" - ), - "numericAttributesForFiltering": obj.get( - "numericAttributesForFiltering" - ), - "separatorsToIndex": obj.get("separatorsToIndex"), - "searchableAttributes": obj.get("searchableAttributes"), - "userData": obj.get("userData"), - "customNormalization": obj.get("customNormalization"), - "attributeForDistinct": obj.get("attributeForDistinct"), - "attributesToRetrieve": obj.get("attributesToRetrieve"), - "ranking": obj.get("ranking"), - "relevancyStrictness": obj.get("relevancyStrictness"), - "attributesToHighlight": obj.get("attributesToHighlight"), - "attributesToSnippet": obj.get("attributesToSnippet"), - "highlightPreTag": obj.get("highlightPreTag"), - "highlightPostTag": obj.get("highlightPostTag"), - "snippetEllipsisText": obj.get("snippetEllipsisText"), - "restrictHighlightAndSnippetArrays": obj.get( - "restrictHighlightAndSnippetArrays" - ), - "minWordSizefor1Typo": obj.get("minWordSizefor1Typo"), - "minWordSizefor2Typos": obj.get("minWordSizefor2Typos"), - "typoTolerance": ( - TypoTolerance.from_dict(obj.get("typoTolerance")) - if obj.get("typoTolerance") is not None - else None - ), - "allowTyposOnNumericTokens": obj.get("allowTyposOnNumericTokens"), - "disableTypoToleranceOnAttributes": obj.get( - "disableTypoToleranceOnAttributes" - ), - "ignorePlurals": ( - IgnorePlurals.from_dict(obj.get("ignorePlurals")) - if obj.get("ignorePlurals") is not None - else None - ), - "removeStopWords": ( - RemoveStopWords.from_dict(obj.get("removeStopWords")) - if obj.get("removeStopWords") is not None - else None - ), - "queryLanguages": obj.get("queryLanguages"), - "decompoundQuery": obj.get("decompoundQuery"), - "enableRules": obj.get("enableRules"), - "enablePersonalization": obj.get("enablePersonalization"), - "queryType": obj.get("queryType"), - "removeWordsIfNoResults": obj.get("removeWordsIfNoResults"), - "advancedSyntax": obj.get("advancedSyntax"), - "optionalWords": obj.get("optionalWords"), - "disableExactOnAttributes": obj.get("disableExactOnAttributes"), - "exactOnSingleWordQuery": obj.get("exactOnSingleWordQuery"), - "alternativesAsExact": obj.get("alternativesAsExact"), - "advancedSyntaxFeatures": obj.get("advancedSyntaxFeatures"), - "distinct": ( - Distinct.from_dict(obj.get("distinct")) - if obj.get("distinct") is not None - else None - ), - "replaceSynonymsInHighlight": obj.get("replaceSynonymsInHighlight"), - "minProximity": obj.get("minProximity"), - "responseFields": obj.get("responseFields"), - "maxFacetHits": obj.get("maxFacetHits"), - "maxValuesPerFacet": obj.get("maxValuesPerFacet"), - "sortFacetValuesBy": obj.get("sortFacetValuesBy"), - "attributeCriteriaComputedByMinProximity": obj.get( - "attributeCriteriaComputedByMinProximity" - ), - "renderingContent": ( - RenderingContent.from_dict(obj.get("renderingContent")) - if obj.get("renderingContent") is not None - else None - ), - "enableReRanking": obj.get("enableReRanking"), - "reRankingApplyFilter": ( - ReRankingApplyFilter.from_dict(obj.get("reRankingApplyFilter")) - if obj.get("reRankingApplyFilter") is not None - else None - ), - } + obj["facetFilters"] = ( + FacetFilters.from_dict(obj["facetFilters"]) + if obj.get("facetFilters") is not None + else None + ) + obj["optionalFilters"] = ( + OptionalFilters.from_dict(obj["optionalFilters"]) + if obj.get("optionalFilters") is not None + else None + ) + obj["numericFilters"] = ( + NumericFilters.from_dict(obj["numericFilters"]) + if obj.get("numericFilters") is not None + else None + ) + obj["tagFilters"] = ( + TagFilters.from_dict(obj["tagFilters"]) + if obj.get("tagFilters") is not None + else None + ) + obj["aroundRadius"] = ( + AroundRadius.from_dict(obj["aroundRadius"]) + if obj.get("aroundRadius") is not None + else None ) - return _obj + obj["aroundPrecision"] = ( + AroundPrecision.from_dict(obj["aroundPrecision"]) + if obj.get("aroundPrecision") is not None + else None + ) + obj["naturalLanguages"] = obj.get("naturalLanguages") + obj["indexLanguages"] = obj.get("indexLanguages") + obj["typoTolerance"] = ( + TypoTolerance.from_dict(obj["typoTolerance"]) + if obj.get("typoTolerance") is not None + else None + ) + obj["ignorePlurals"] = ( + IgnorePlurals.from_dict(obj["ignorePlurals"]) + if obj.get("ignorePlurals") is not None + else None + ) + obj["removeStopWords"] = ( + RemoveStopWords.from_dict(obj["removeStopWords"]) + if obj.get("removeStopWords") is not None + else None + ) + obj["queryLanguages"] = obj.get("queryLanguages") + obj["queryType"] = obj.get("queryType") + obj["removeWordsIfNoResults"] = obj.get("removeWordsIfNoResults") + obj["exactOnSingleWordQuery"] = obj.get("exactOnSingleWordQuery") + obj["alternativesAsExact"] = obj.get("alternativesAsExact") + obj["advancedSyntaxFeatures"] = obj.get("advancedSyntaxFeatures") + obj["distinct"] = ( + Distinct.from_dict(obj["distinct"]) + if obj.get("distinct") is not None + else None + ) + obj["renderingContent"] = ( + RenderingContent.from_dict(obj["renderingContent"]) + if obj.get("renderingContent") is not None + else None + ) + obj["reRankingApplyFilter"] = ( + ReRankingApplyFilter.from_dict(obj["reRankingApplyFilter"]) + if obj.get("reRankingApplyFilter") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/recommendations_hit.py b/algoliasearch/recommend/models/recommendations_hit.py index 52b72a80c..cc1e4bb01 100644 --- a/algoliasearch/recommend/models/recommendations_hit.py +++ b/algoliasearch/recommend/models/recommendations_hit.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -27,9 +27,12 @@ class RecommendationsHit(BaseModel): RecommendationsHit """ - oneof_schema_1_validator: Optional[RecommendHit] = None - oneof_schema_2_validator: Optional[TrendingFacetHit] = None + oneof_schema_1_validator: Optional[RecommendHit] = Field(default=None) + + oneof_schema_2_validator: Optional[TrendingFacetHit] = Field(default=None) + actual_instance: Optional[Union[RecommendHit, TrendingFacetHit]] = None + one_of_schemas: Set[str] = {"RecommendHit", "TrendingFacetHit"} def __init__(self, *args, **kwargs) -> None: if args: @@ -53,7 +56,8 @@ def unwrap_actual_instance(self) -> Optional[Union[RecommendHit, TrendingFacetHi return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of RecommendationsHit from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -85,17 +89,23 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[Union[Dict[str, Any], RecommendHit, TrendingFacetHit]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/recommend/models/recommendations_request.py b/algoliasearch/recommend/models/recommendations_request.py index 900110382..2f4599c7d 100644 --- a/algoliasearch/recommend/models/recommendations_request.py +++ b/algoliasearch/recommend/models/recommendations_request.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -33,12 +33,18 @@ class RecommendationsRequest(BaseModel): RecommendationsRequest """ - oneof_schema_1_validator: Optional[BoughtTogetherQuery] = None - oneof_schema_2_validator: Optional[RelatedQuery] = None - oneof_schema_3_validator: Optional[TrendingItemsQuery] = None - oneof_schema_4_validator: Optional[TrendingFacetsQuery] = None - oneof_schema_5_validator: Optional[LookingSimilarQuery] = None - oneof_schema_6_validator: Optional[RecommendedForYouQuery] = None + oneof_schema_1_validator: Optional[BoughtTogetherQuery] = Field(default=None) + + oneof_schema_2_validator: Optional[RelatedQuery] = Field(default=None) + + oneof_schema_3_validator: Optional[TrendingItemsQuery] = Field(default=None) + + oneof_schema_4_validator: Optional[TrendingFacetsQuery] = Field(default=None) + + oneof_schema_5_validator: Optional[LookingSimilarQuery] = Field(default=None) + + oneof_schema_6_validator: Optional[RecommendedForYouQuery] = Field(default=None) + actual_instance: Optional[ Union[ BoughtTogetherQuery, @@ -49,6 +55,14 @@ class RecommendationsRequest(BaseModel): TrendingItemsQuery, ] ] = None + one_of_schemas: Set[str] = { + "BoughtTogetherQuery", + "LookingSimilarQuery", + "RecommendedForYouQuery", + "RelatedQuery", + "TrendingFacetsQuery", + "TrendingItemsQuery", + } def __init__(self, *args, **kwargs) -> None: if args: @@ -83,7 +97,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of RecommendationsRequest from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -139,17 +154,33 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[ + Union[ + Dict[str, Any], + BoughtTogetherQuery, + LookingSimilarQuery, + RecommendedForYouQuery, + RelatedQuery, + TrendingFacetsQuery, + TrendingItemsQuery, + ] + ]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/recommend/models/recommendations_results.py b/algoliasearch/recommend/models/recommendations_results.py index 488037c2b..e6bc6ad1a 100644 --- a/algoliasearch/recommend/models/recommendations_results.py +++ b/algoliasearch/recommend/models/recommendations_results.py @@ -11,20 +11,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import ( - BaseModel, - ConfigDict, - Field, - StrictBool, - StrictInt, - StrictStr, - field_validator, -) +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.recommend.models.exhaustive import Exhaustive @@ -39,125 +31,70 @@ class RecommendationsResults(BaseModel): RecommendationsResults """ - ab_test_id: Optional[StrictInt] = Field( - default=None, - description="A/B test ID. This is only included in the response for indices that are part of an A/B test.", - alias="abTestID", - ) - ab_test_variant_id: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field( - default=None, - description="Variant ID. This is only included in the response for indices that are part of an A/B test.", - alias="abTestVariantID", - ) - around_lat_lng: Optional[Annotated[str, Field(strict=True)]] = Field( - default=None, - description="Computed geographical location.", - alias="aroundLatLng", - ) - automatic_radius: Optional[StrictStr] = Field( - default=None, - description="Distance from a central coordinate provided by `aroundLatLng`.", - alias="automaticRadius", - ) - exhaustive: Optional[Exhaustive] = None - exhaustive_facets_count: Optional[StrictBool] = Field( - default=None, - description="See the `facetsCount` field of the `exhaustive` object in the response.", - alias="exhaustiveFacetsCount", - ) - exhaustive_nb_hits: Optional[StrictBool] = Field( - default=None, - description="See the `nbHits` field of the `exhaustive` object in the response.", - alias="exhaustiveNbHits", - ) - exhaustive_typo: Optional[StrictBool] = Field( - default=None, - description="See the `typo` field of the `exhaustive` object in the response.", - alias="exhaustiveTypo", - ) - facets: Optional[Dict[str, Dict[str, StrictInt]]] = Field( - default=None, description="Facet counts." - ) + ab_test_id: Optional[int] = Field(default=None, alias="abTestID") + """ A/B test ID. This is only included in the response for indices that are part of an A/B test. """ + ab_test_variant_id: Optional[int] = Field(default=None, alias="abTestVariantID") + """ Variant ID. This is only included in the response for indices that are part of an A/B test. """ + around_lat_lng: Optional[str] = Field(default=None, alias="aroundLatLng") + """ Computed geographical location. """ + automatic_radius: Optional[str] = Field(default=None, alias="automaticRadius") + """ Distance from a central coordinate provided by `aroundLatLng`. """ + exhaustive: Optional[Exhaustive] = Field(default=None, alias="exhaustive") + exhaustive_facets_count: Optional[bool] = Field( + default=None, alias="exhaustiveFacetsCount" + ) + """ See the `facetsCount` field of the `exhaustive` object in the response. """ + exhaustive_nb_hits: Optional[bool] = Field(default=None, alias="exhaustiveNbHits") + """ See the `nbHits` field of the `exhaustive` object in the response. """ + exhaustive_typo: Optional[bool] = Field(default=None, alias="exhaustiveTypo") + """ See the `typo` field of the `exhaustive` object in the response. """ + facets: Optional[Dict[str, Dict[str, int]]] = Field(default=None, alias="facets") + """ Facet counts. """ facets_stats: Optional[Dict[str, FacetStats]] = Field( - default=None, description="Statistics for numerical facets." - ) - index: Optional[StrictStr] = Field( - default=None, description="Index name used for the query." - ) - index_used: Optional[StrictStr] = Field( - default=None, - description="Index name used for the query. During A/B testing, the targeted index isn't always the index used by the query.", - alias="indexUsed", - ) - message: Optional[StrictStr] = Field( - default=None, description="Warnings about the query." - ) - nb_sorted_hits: Optional[StrictInt] = Field( - default=None, - description="Number of hits selected and sorted by the relevant sort algorithm.", - alias="nbSortedHits", - ) - parsed_query: Optional[StrictStr] = Field( - default=None, - description="Post-[normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/#what-does-normalization-mean) query string that will be searched.", - alias="parsedQuery", - ) - processing_time_ms: StrictInt = Field( - description="Time the server took to process the request, in milliseconds.", - alias="processingTimeMS", - ) - processing_timings_ms: Optional[Dict[str, Any]] = Field( - default=None, - description="Experimental. List of processing steps and their times, in milliseconds. You can use this list to investigate performance issues.", - alias="processingTimingsMS", - ) - query_after_removal: Optional[StrictStr] = Field( - default=None, - description="Markup text indicating which parts of the original query have been removed to retrieve a non-empty result set.", - alias="queryAfterRemoval", - ) - redirect: Optional[Redirect] = None + default=None, alias="facets_stats" + ) + """ Statistics for numerical facets. """ + index: Optional[str] = Field(default=None, alias="index") + """ Index name used for the query. """ + index_used: Optional[str] = Field(default=None, alias="indexUsed") + """ Index name used for the query. During A/B testing, the targeted index isn't always the index used by the query. """ + message: Optional[str] = Field(default=None, alias="message") + """ Warnings about the query. """ + nb_sorted_hits: Optional[int] = Field(default=None, alias="nbSortedHits") + """ Number of hits selected and sorted by the relevant sort algorithm. """ + parsed_query: Optional[str] = Field(default=None, alias="parsedQuery") + """ Post-[normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/#what-does-normalization-mean) query string that will be searched. """ + processing_time_ms: int = Field(alias="processingTimeMS") + """ Time the server took to process the request, in milliseconds. """ + processing_timings_ms: Optional[object] = Field( + default=None, alias="processingTimingsMS" + ) + """ Experimental. List of processing steps and their times, in milliseconds. You can use this list to investigate performance issues. """ + query_after_removal: Optional[str] = Field(default=None, alias="queryAfterRemoval") + """ Markup text indicating which parts of the original query have been removed to retrieve a non-empty result set. """ + redirect: Optional[Redirect] = Field(default=None, alias="redirect") rendering_content: Optional[RenderingContent] = Field( default=None, alias="renderingContent" ) - server_time_ms: Optional[StrictInt] = Field( - default=None, - description="Time the server took to process the request, in milliseconds.", - alias="serverTimeMS", - ) - server_used: Optional[StrictStr] = Field( - default=None, - description="Host name of the server that processed the request.", - alias="serverUsed", - ) - user_data: Optional[Dict[str, Any]] = Field( - default=None, - description="An object with custom data. You can store up to 32kB as custom data. ", - alias="userData", - ) - query_id: Optional[StrictStr] = Field( - default=None, - description="Unique identifier for the query. This is used for [click analytics](https://www.algolia.com/doc/guides/analytics/click-analytics/).", - alias="queryID", - ) - automatic_insights: Optional[StrictBool] = Field( - default=None, - description="Whether automatic events collection is enabled for the application.", - alias="_automaticInsights", - ) - page: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=0, description="Page of search results to retrieve." - ) - nb_hits: Optional[StrictInt] = Field( - default=None, description="Number of results (hits).", alias="nbHits" - ) - nb_pages: Optional[StrictInt] = Field( - default=None, description="Number of pages of results.", alias="nbPages" - ) - hits_per_page: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = Field( - default=20, description="Number of hits per page.", alias="hitsPerPage" - ) - hits: List[RecommendationsHit] + server_time_ms: Optional[int] = Field(default=None, alias="serverTimeMS") + """ Time the server took to process the request, in milliseconds. """ + server_used: Optional[str] = Field(default=None, alias="serverUsed") + """ Host name of the server that processed the request. """ + user_data: Optional[object] = Field(default=None, alias="userData") + """ An object with custom data. You can store up to 32kB as custom data. """ + query_id: Optional[str] = Field(default=None, alias="queryID") + """ Unique identifier for the query. This is used for [click analytics](https://www.algolia.com/doc/guides/analytics/click-analytics/). """ + automatic_insights: Optional[bool] = Field(default=None, alias="_automaticInsights") + """ Whether automatic events collection is enabled for the application. """ + page: Optional[int] = Field(default=None, alias="page") + """ Page of search results to retrieve. """ + nb_hits: Optional[int] = Field(default=None, alias="nbHits") + """ Number of results (hits). """ + nb_pages: Optional[int] = Field(default=None, alias="nbPages") + """ Number of pages of results. """ + hits_per_page: Optional[int] = Field(default=None, alias="hitsPerPage") + """ Number of hits per page. """ + hits: List[RecommendationsHit] = Field(alias="hits") @field_validator("around_lat_lng") def around_lat_lng_validate_regular_expression(cls, value): @@ -172,55 +109,30 @@ def around_lat_lng_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RecommendationsResults from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.exhaustive: - _dict["exhaustive"] = self.exhaustive.to_dict() - _field_dict = {} - if self.facets_stats: - for _key in self.facets_stats: - if self.facets_stats[_key]: - _field_dict[_key] = self.facets_stats[_key].to_dict() - _dict["facets_stats"] = _field_dict - if self.redirect: - _dict["redirect"] = self.redirect.to_dict() - if self.rendering_content: - _dict["renderingContent"] = self.rendering_content.to_dict() - _items = [] - if self.hits: - for _item in self.hits: - if _item: - _items.append(_item.to_dict()) - _dict["hits"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RecommendationsResults from a dict""" if obj is None: return None @@ -228,61 +140,32 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "abTestID": obj.get("abTestID"), - "abTestVariantID": obj.get("abTestVariantID"), - "aroundLatLng": obj.get("aroundLatLng"), - "automaticRadius": obj.get("automaticRadius"), - "exhaustive": ( - Exhaustive.from_dict(obj.get("exhaustive")) - if obj.get("exhaustive") is not None - else None - ), - "exhaustiveFacetsCount": obj.get("exhaustiveFacetsCount"), - "exhaustiveNbHits": obj.get("exhaustiveNbHits"), - "exhaustiveTypo": obj.get("exhaustiveTypo"), - "facets": obj.get("facets"), - "facets_stats": ( - dict( - (_k, FacetStats.from_dict(_v)) - for _k, _v in obj.get("facets_stats").items() - ) - if obj.get("facets_stats") is not None - else None - ), - "index": obj.get("index"), - "indexUsed": obj.get("indexUsed"), - "message": obj.get("message"), - "nbSortedHits": obj.get("nbSortedHits"), - "parsedQuery": obj.get("parsedQuery"), - "processingTimeMS": obj.get("processingTimeMS"), - "processingTimingsMS": obj.get("processingTimingsMS"), - "queryAfterRemoval": obj.get("queryAfterRemoval"), - "redirect": ( - Redirect.from_dict(obj.get("redirect")) - if obj.get("redirect") is not None - else None - ), - "renderingContent": ( - RenderingContent.from_dict(obj.get("renderingContent")) - if obj.get("renderingContent") is not None - else None - ), - "serverTimeMS": obj.get("serverTimeMS"), - "serverUsed": obj.get("serverUsed"), - "userData": obj.get("userData"), - "queryID": obj.get("queryID"), - "_automaticInsights": obj.get("_automaticInsights"), - "page": obj.get("page"), - "nbHits": obj.get("nbHits"), - "nbPages": obj.get("nbPages"), - "hitsPerPage": obj.get("hitsPerPage"), - "hits": ( - [RecommendationsHit.from_dict(_item) for _item in obj.get("hits")] - if obj.get("hits") is not None - else None - ), - } + obj["exhaustive"] = ( + Exhaustive.from_dict(obj["exhaustive"]) + if obj.get("exhaustive") is not None + else None + ) + obj["facets_stats"] = ( + dict( + (_k, FacetStats.from_dict(_v)) for _k, _v in obj["facets_stats"].items() + ) + if obj.get("facets_stats") is not None + else None ) - return _obj + obj["redirect"] = ( + Redirect.from_dict(obj["redirect"]) + if obj.get("redirect") is not None + else None + ) + obj["renderingContent"] = ( + RenderingContent.from_dict(obj["renderingContent"]) + if obj.get("renderingContent") is not None + else None + ) + obj["hits"] = ( + [RecommendationsHit.from_dict(_item) for _item in obj["hits"]] + if obj.get("hits") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/recommended_for_you_query.py b/algoliasearch/recommend/models/recommended_for_you_query.py index c8984ffdf..a7a94d0cd 100644 --- a/algoliasearch/recommend/models/recommended_for_you_query.py +++ b/algoliasearch/recommend/models/recommended_for_you_query.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.recommend.models.fallback_params import FallbackParams @@ -30,66 +30,45 @@ class RecommendedForYouQuery(BaseModel): RecommendedForYouQuery """ - index_name: StrictStr = Field( - description="Index name (case-sensitive).", alias="indexName" - ) - threshold: Union[ - Annotated[float, Field(le=100, strict=True, ge=0)], - Annotated[int, Field(le=100, strict=True, ge=0)], - ] = Field( - description="Minimum score a recommendation must have to be included in the response." - ) - max_recommendations: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = ( - Field( - default=30, - description="Maximum number of recommendations to retrieve. By default, all recommendations are returned and no fallback request is made. Depending on the available recommendations and the other request parameters, the actual number of recommendations may be lower than this value. ", - alias="maxRecommendations", - ) - ) + index_name: str = Field(alias="indexName") + """ Index name (case-sensitive). """ + threshold: float = Field(alias="threshold") + """ Minimum score a recommendation must have to be included in the response. """ + max_recommendations: Optional[int] = Field(default=None, alias="maxRecommendations") + """ Maximum number of recommendations to retrieve. By default, all recommendations are returned and no fallback request is made. Depending on the available recommendations and the other request parameters, the actual number of recommendations may be lower than this value. """ query_parameters: Optional[RecommendSearchParams] = Field( default=None, alias="queryParameters" ) - model: RecommendedForYouModel + model: RecommendedForYouModel = Field(alias="model") fallback_parameters: Optional[FallbackParams] = Field( default=None, alias="fallbackParameters" ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RecommendedForYouQuery from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.query_parameters: - _dict["queryParameters"] = self.query_parameters.to_dict() - if self.fallback_parameters: - _dict["fallbackParameters"] = self.fallback_parameters.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RecommendedForYouQuery from a dict""" if obj is None: return None @@ -97,22 +76,16 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "indexName": obj.get("indexName"), - "threshold": obj.get("threshold"), - "maxRecommendations": obj.get("maxRecommendations"), - "queryParameters": ( - RecommendSearchParams.from_dict(obj.get("queryParameters")) - if obj.get("queryParameters") is not None - else None - ), - "model": obj.get("model"), - "fallbackParameters": ( - FallbackParams.from_dict(obj.get("fallbackParameters")) - if obj.get("fallbackParameters") is not None - else None - ), - } + obj["queryParameters"] = ( + RecommendSearchParams.from_dict(obj["queryParameters"]) + if obj.get("queryParameters") is not None + else None ) - return _obj + obj["model"] = obj.get("model") + obj["fallbackParameters"] = ( + FallbackParams.from_dict(obj["fallbackParameters"]) + if obj.get("fallbackParameters") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/redirect.py b/algoliasearch/recommend/models/redirect.py index a262033f5..be0d4aa11 100644 --- a/algoliasearch/recommend/models/redirect.py +++ b/algoliasearch/recommend/models/redirect.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,46 +28,35 @@ class Redirect(BaseModel): [Redirect results to a URL](https://www.algolia.com/doc/guides/managing-results/rules/merchandising-and-promoting/how-to/redirects/), this this parameter is for internal use only. """ - index: Optional[List[RedirectRuleIndexMetadata]] = None + index: Optional[List[RedirectRuleIndexMetadata]] = Field( + default=None, alias="index" + ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Redirect from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.index: - for _item in self.index: - if _item: - _items.append(_item.to_dict()) - _dict["index"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Redirect from a dict""" if obj is None: return None @@ -75,16 +64,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "index": ( - [ - RedirectRuleIndexMetadata.from_dict(_item) - for _item in obj.get("index") - ] - if obj.get("index") is not None - else None - ) - } + obj["index"] = ( + [RedirectRuleIndexMetadata.from_dict(_item) for _item in obj["index"]] + if obj.get("index") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/redirect_rule_index_data.py b/algoliasearch/recommend/models/redirect_rule_index_data.py index 799354cc7..bb6826e62 100644 --- a/algoliasearch/recommend/models/redirect_rule_index_data.py +++ b/algoliasearch/recommend/models/redirect_rule_index_data.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,40 +23,33 @@ class RedirectRuleIndexData(BaseModel): Redirect rule data. """ - rule_object_id: StrictStr = Field(alias="ruleObjectID") + rule_object_id: str = Field(alias="ruleObjectID") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RedirectRuleIndexData from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RedirectRuleIndexData from a dict""" if obj is None: return None @@ -64,5 +57,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"ruleObjectID": obj.get("ruleObjectID")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/redirect_rule_index_metadata.py b/algoliasearch/recommend/models/redirect_rule_index_metadata.py index b9cd13da5..9b56e60ba 100644 --- a/algoliasearch/recommend/models/redirect_rule_index_metadata.py +++ b/algoliasearch/recommend/models/redirect_rule_index_metadata.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,46 +28,41 @@ class RedirectRuleIndexMetadata(BaseModel): RedirectRuleIndexMetadata """ - source: StrictStr = Field(description="Source index for the redirect rule.") - dest: StrictStr = Field(description="Destination index for the redirect rule.") - reason: StrictStr = Field(description="Reason for the redirect rule.") - succeed: StrictBool = Field(description="Redirect rule status.") - data: RedirectRuleIndexData + source: str = Field(alias="source") + """ Source index for the redirect rule. """ + dest: str = Field(alias="dest") + """ Destination index for the redirect rule. """ + reason: str = Field(alias="reason") + """ Reason for the redirect rule. """ + succeed: bool = Field(alias="succeed") + """ Redirect rule status. """ + data: RedirectRuleIndexData = Field(alias="data") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RedirectRuleIndexMetadata from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.data: - _dict["data"] = self.data.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RedirectRuleIndexMetadata from a dict""" if obj is None: return None @@ -75,17 +70,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "source": obj.get("source"), - "dest": obj.get("dest"), - "reason": obj.get("reason"), - "succeed": obj.get("succeed"), - "data": ( - RedirectRuleIndexData.from_dict(obj.get("data")) - if obj.get("data") is not None - else None - ), - } + obj["data"] = ( + RedirectRuleIndexData.from_dict(obj["data"]) + if obj.get("data") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/redirect_url.py b/algoliasearch/recommend/models/redirect_url.py index 8adefe638..fce44987e 100644 --- a/algoliasearch/recommend/models/redirect_url.py +++ b/algoliasearch/recommend/models/redirect_url.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,40 +23,33 @@ class RedirectURL(BaseModel): The redirect rule container. """ - url: Optional[StrictStr] = None + url: Optional[str] = Field(default=None, alias="url") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RedirectURL from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RedirectURL from a dict""" if obj is None: return None @@ -64,5 +57,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"url": obj.get("url")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/related_query.py b/algoliasearch/recommend/models/related_query.py index 76b447d91..9e3da6133 100644 --- a/algoliasearch/recommend/models/related_query.py +++ b/algoliasearch/recommend/models/related_query.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.recommend.models.fallback_params import FallbackParams @@ -28,69 +28,47 @@ class RelatedQuery(BaseModel): RelatedQuery """ - index_name: StrictStr = Field( - description="Index name (case-sensitive).", alias="indexName" - ) - threshold: Union[ - Annotated[float, Field(le=100, strict=True, ge=0)], - Annotated[int, Field(le=100, strict=True, ge=0)], - ] = Field( - description="Minimum score a recommendation must have to be included in the response." - ) - max_recommendations: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = ( - Field( - default=30, - description="Maximum number of recommendations to retrieve. By default, all recommendations are returned and no fallback request is made. Depending on the available recommendations and the other request parameters, the actual number of recommendations may be lower than this value. ", - alias="maxRecommendations", - ) - ) + index_name: str = Field(alias="indexName") + """ Index name (case-sensitive). """ + threshold: float = Field(alias="threshold") + """ Minimum score a recommendation must have to be included in the response. """ + max_recommendations: Optional[int] = Field(default=None, alias="maxRecommendations") + """ Maximum number of recommendations to retrieve. By default, all recommendations are returned and no fallback request is made. Depending on the available recommendations and the other request parameters, the actual number of recommendations may be lower than this value. """ query_parameters: Optional[RecommendSearchParams] = Field( default=None, alias="queryParameters" ) - model: RelatedModel - object_id: StrictStr = Field( - description="Unique record identifier.", alias="objectID" - ) + model: RelatedModel = Field(alias="model") + object_id: str = Field(alias="objectID") + """ Unique record identifier. """ fallback_parameters: Optional[FallbackParams] = Field( default=None, alias="fallbackParameters" ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RelatedQuery from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.query_parameters: - _dict["queryParameters"] = self.query_parameters.to_dict() - if self.fallback_parameters: - _dict["fallbackParameters"] = self.fallback_parameters.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RelatedQuery from a dict""" if obj is None: return None @@ -98,23 +76,16 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "indexName": obj.get("indexName"), - "threshold": obj.get("threshold"), - "maxRecommendations": obj.get("maxRecommendations"), - "queryParameters": ( - RecommendSearchParams.from_dict(obj.get("queryParameters")) - if obj.get("queryParameters") is not None - else None - ), - "model": obj.get("model"), - "objectID": obj.get("objectID"), - "fallbackParameters": ( - FallbackParams.from_dict(obj.get("fallbackParameters")) - if obj.get("fallbackParameters") is not None - else None - ), - } + obj["queryParameters"] = ( + RecommendSearchParams.from_dict(obj["queryParameters"]) + if obj.get("queryParameters") is not None + else None ) - return _obj + obj["model"] = obj.get("model") + obj["fallbackParameters"] = ( + FallbackParams.from_dict(obj["fallbackParameters"]) + if obj.get("fallbackParameters") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/remove_stop_words.py b/algoliasearch/recommend/models/remove_stop_words.py index 69791a537..c01d1b6e9 100644 --- a/algoliasearch/recommend/models/remove_stop_words.py +++ b/algoliasearch/recommend/models/remove_stop_words.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, Field, StrictBool, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -26,15 +26,12 @@ class RemoveStopWords(BaseModel): Removes stop words from the search query. Stop words are common words like articles, conjunctions, prepositions, or pronouns that have little or no meaning on their own. In English, \"the\", \"a\", or \"and\" are stop words. You should only use this feature for the languages used in your index. """ - oneof_schema_1_validator: Optional[List[SupportedLanguage]] = Field( - default=None, - description="ISO code for languages for which stop words should be removed. This overrides languages you set in `queryLanguges`.", - ) - oneof_schema_2_validator: Optional[StrictBool] = Field( - default=False, - description="If true, stop words are removed for all languages you included in `queryLanguages`, or for all supported languages, if `queryLanguages` is empty. If false, stop words are not removed. ", - ) + oneof_schema_1_validator: Optional[List[SupportedLanguage]] = Field(default=None) + """ ISO code for languages for which stop words should be removed. This overrides languages you set in `queryLanguges`. """ + oneof_schema_2_validator: Optional[bool] = Field(default=None) + """ If true, stop words are removed for all languages you included in `queryLanguages`, or for all supported languages, if `queryLanguages` is empty. If false, stop words are not removed. """ actual_instance: Optional[Union[List[SupportedLanguage], bool]] = None + one_of_schemas: Set[str] = {"List[SupportedLanguage]", "bool"} def __init__(self, *args, **kwargs) -> None: if args: @@ -58,7 +55,8 @@ def unwrap_actual_instance(self) -> Optional[Union[List[SupportedLanguage], bool return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of RemoveStopWords from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -92,17 +90,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], List[SupportedLanguage], bool]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/recommend/models/remove_words_if_no_results.py b/algoliasearch/recommend/models/remove_words_if_no_results.py index 8961dee90..3466ed947 100644 --- a/algoliasearch/recommend/models/remove_words_if_no_results.py +++ b/algoliasearch/recommend/models/remove_words_if_no_results.py @@ -25,8 +25,11 @@ class RemoveWordsIfNoResults(str, Enum): allowed enum values """ NONE = "none" + LASTWORDS = "lastWords" + FIRSTWORDS = "firstWords" + ALLOPTIONAL = "allOptional" @classmethod diff --git a/algoliasearch/recommend/models/rendering_content.py b/algoliasearch/recommend/models/rendering_content.py index 7d9be7d7c..ad7f91977 100644 --- a/algoliasearch/recommend/models/rendering_content.py +++ b/algoliasearch/recommend/models/rendering_content.py @@ -28,44 +28,33 @@ class RenderingContent(BaseModel): """ facet_ordering: Optional[FacetOrdering] = Field(default=None, alias="facetOrdering") - redirect: Optional[RedirectURL] = None + redirect: Optional[RedirectURL] = Field(default=None, alias="redirect") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RenderingContent from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.facet_ordering: - _dict["facetOrdering"] = self.facet_ordering.to_dict() - if self.redirect: - _dict["redirect"] = self.redirect.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RenderingContent from a dict""" if obj is None: return None @@ -73,18 +62,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "facetOrdering": ( - FacetOrdering.from_dict(obj.get("facetOrdering")) - if obj.get("facetOrdering") is not None - else None - ), - "redirect": ( - RedirectURL.from_dict(obj.get("redirect")) - if obj.get("redirect") is not None - else None - ), - } + obj["facetOrdering"] = ( + FacetOrdering.from_dict(obj["facetOrdering"]) + if obj.get("facetOrdering") is not None + else None ) - return _obj + obj["redirect"] = ( + RedirectURL.from_dict(obj["redirect"]) + if obj.get("redirect") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/rule_metadata.py b/algoliasearch/recommend/models/rule_metadata.py index 4c631a965..7b453c399 100644 --- a/algoliasearch/recommend/models/rule_metadata.py +++ b/algoliasearch/recommend/models/rule_metadata.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,44 +23,34 @@ class RuleMetadata(BaseModel): Rule metadata. """ - last_update: Optional[StrictStr] = Field( - default=None, - description="Date and time when the object was updated, in RFC 3339 format.", - alias="lastUpdate", - ) + last_update: Optional[str] = Field(default=None, alias="lastUpdate") + """ Date and time when the object was updated, in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RuleMetadata from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RuleMetadata from a dict""" if obj is None: return None @@ -68,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"lastUpdate": obj.get("lastUpdate")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/search_recommend_rules_params.py b/algoliasearch/recommend/models/search_recommend_rules_params.py index e0e0754ff..9d2ba22aa 100644 --- a/algoliasearch/recommend/models/search_recommend_rules_params.py +++ b/algoliasearch/recommend/models/search_recommend_rules_params.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class SearchRecommendRulesParams(BaseModel): @@ -23,68 +23,48 @@ class SearchRecommendRulesParams(BaseModel): Recommend rules parameters. """ - query: Optional[StrictStr] = Field(default="", description="Search query.") - context: Optional[StrictStr] = Field( - default=None, description="Only search for rules with matching context." - ) - page: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=None, description="Requested page of the API response." - ) - hits_per_page: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = Field( - default=20, description="Maximum number of hits per page.", alias="hitsPerPage" - ) - enabled: Optional[StrictBool] = Field( - default=None, - description="Whether to only show rules where the value of their `enabled` property matches this parameter. If absent, show all rules, regardless of their `enabled` property. ", - ) - filters: Optional[StrictStr] = Field( - default=None, - description="Filter expression. This only searches for rules matching the filter expression.", - ) - facets: Optional[List[StrictStr]] = Field( - default=None, - description="Include facets and facet values in the response. Use `['*']` to include all facets.", - ) - max_values_per_facet: Optional[ - Annotated[int, Field(le=1000, strict=True, ge=1)] - ] = Field( - default=None, - description="Maximum number of values to return for each facet.", - alias="maxValuesPerFacet", - ) + query: Optional[str] = Field(default=None, alias="query") + """ Search query. """ + context: Optional[str] = Field(default=None, alias="context") + """ Only search for rules with matching context. """ + page: Optional[int] = Field(default=None, alias="page") + """ Requested page of the API response. """ + hits_per_page: Optional[int] = Field(default=None, alias="hitsPerPage") + """ Maximum number of hits per page. """ + enabled: Optional[bool] = Field(default=None, alias="enabled") + """ Whether to only show rules where the value of their `enabled` property matches this parameter. If absent, show all rules, regardless of their `enabled` property. """ + filters: Optional[str] = Field(default=None, alias="filters") + """ Filter expression. This only searches for rules matching the filter expression. """ + facets: Optional[List[str]] = Field(default=None, alias="facets") + """ Include facets and facet values in the response. Use `['*']` to include all facets. """ + max_values_per_facet: Optional[int] = Field(default=None, alias="maxValuesPerFacet") + """ Maximum number of values to return for each facet. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchRecommendRulesParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchRecommendRulesParams from a dict""" if obj is None: return None @@ -92,16 +72,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "query": obj.get("query"), - "context": obj.get("context"), - "page": obj.get("page"), - "hitsPerPage": obj.get("hitsPerPage"), - "enabled": obj.get("enabled"), - "filters": obj.get("filters"), - "facets": obj.get("facets"), - "maxValuesPerFacet": obj.get("maxValuesPerFacet"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/search_recommend_rules_response.py b/algoliasearch/recommend/models/search_recommend_rules_response.py index aa1059403..8d1ff5384 100644 --- a/algoliasearch/recommend/models/search_recommend_rules_response.py +++ b/algoliasearch/recommend/models/search_recommend_rules_response.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.recommend.models.recommend_rule import RecommendRule @@ -26,55 +26,40 @@ class SearchRecommendRulesResponse(BaseModel): SearchRecommendRulesResponse """ - hits: List[RecommendRule] = Field( - description="Recommend rules that match the search criteria." - ) - nb_hits: StrictInt = Field(description="Number of results (hits).", alias="nbHits") - page: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Page of search results to retrieve." - ) - nb_pages: StrictInt = Field( - description="Number of pages of results.", alias="nbPages" - ) + hits: List[RecommendRule] = Field(alias="hits") + """ Recommend rules that match the search criteria. """ + nb_hits: int = Field(alias="nbHits") + """ Number of results (hits). """ + page: int = Field(alias="page") + """ Page of search results to retrieve. """ + nb_pages: int = Field(alias="nbPages") + """ Number of pages of results. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchRecommendRulesResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.hits: - for _item in self.hits: - if _item: - _items.append(_item.to_dict()) - _dict["hits"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchRecommendRulesResponse from a dict""" if obj is None: return None @@ -82,16 +67,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "hits": ( - [RecommendRule.from_dict(_item) for _item in obj.get("hits")] - if obj.get("hits") is not None - else None - ), - "nbHits": obj.get("nbHits"), - "page": obj.get("page"), - "nbPages": obj.get("nbPages"), - } + obj["hits"] = ( + [RecommendRule.from_dict(_item) for _item in obj["hits"]] + if obj.get("hits") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/snippet_result.py b/algoliasearch/recommend/models/snippet_result.py index 3253a422c..8ddadfe51 100644 --- a/algoliasearch/recommend/models/snippet_result.py +++ b/algoliasearch/recommend/models/snippet_result.py @@ -8,7 +8,7 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union from pydantic import BaseModel, Field, ValidationError, model_serializer @@ -26,18 +26,20 @@ class SnippetResult(BaseModel): SnippetResult """ - oneof_schema_1_validator: Optional[SnippetResultOption] = None - oneof_schema_2_validator: Optional[Dict[str, SnippetResult]] = Field( - default=None, - description="Snippets that show the context around a matching search query.", - ) - oneof_schema_3_validator: Optional[List[SnippetResult]] = Field( - default=None, - description="Snippets that show the context around a matching search query.", - ) + oneof_schema_1_validator: Optional[SnippetResultOption] = Field(default=None) + + oneof_schema_2_validator: Optional[Dict[str, SnippetResult]] = Field(default=None) + """ Snippets that show the context around a matching search query. """ + oneof_schema_3_validator: Optional[List[SnippetResult]] = Field(default=None) + """ Snippets that show the context around a matching search query. """ actual_instance: Optional[ Union[Dict[str, SnippetResult], List[SnippetResult], SnippetResultOption] ] = None + one_of_schemas: Set[str] = { + "Dict[str, SnippetResult]", + "List[SnippetResult]", + "SnippetResultOption", + } def __init__(self, *args, **kwargs) -> None: if args: @@ -65,7 +67,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of SnippetResult from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -105,17 +108,30 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[ + Union[ + Dict[str, Any], + Dict[str, SnippetResult], + List[SnippetResult], + SnippetResultOption, + ] + ]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/recommend/models/snippet_result_option.py b/algoliasearch/recommend/models/snippet_result_option.py index 82bcf53ff..a8e79c4d1 100644 --- a/algoliasearch/recommend/models/snippet_result_option.py +++ b/algoliasearch/recommend/models/snippet_result_option.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,43 +26,35 @@ class SnippetResultOption(BaseModel): Snippets that show the context around a matching search query. """ - value: StrictStr = Field( - description="Highlighted attribute value, including HTML tags." - ) + value: str = Field(alias="value") + """ Highlighted attribute value, including HTML tags. """ match_level: MatchLevel = Field(alias="matchLevel") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SnippetResultOption from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SnippetResultOption from a dict""" if obj is None: return None @@ -70,7 +62,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"value": obj.get("value"), "matchLevel": obj.get("matchLevel")} - ) - return _obj + obj["matchLevel"] = obj.get("matchLevel") + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/sort_remaining_by.py b/algoliasearch/recommend/models/sort_remaining_by.py index c156c883e..57cab8ebd 100644 --- a/algoliasearch/recommend/models/sort_remaining_by.py +++ b/algoliasearch/recommend/models/sort_remaining_by.py @@ -25,7 +25,9 @@ class SortRemainingBy(str, Enum): allowed enum values """ COUNT = "count" + ALPHA = "alpha" + HIDDEN = "hidden" @classmethod diff --git a/algoliasearch/recommend/models/supported_language.py b/algoliasearch/recommend/models/supported_language.py index 1c82c4faa..bbac80c88 100644 --- a/algoliasearch/recommend/models/supported_language.py +++ b/algoliasearch/recommend/models/supported_language.py @@ -25,72 +25,139 @@ class SupportedLanguage(str, Enum): allowed enum values """ AF = "af" + AR = "ar" + AZ = "az" + BG = "bg" + BN = "bn" + CA = "ca" + CS = "cs" + CY = "cy" + DA = "da" + DE = "de" + EL = "el" + EN = "en" + EO = "eo" + ES = "es" + ET = "et" + EU = "eu" + FA = "fa" + FI = "fi" + FO = "fo" + FR = "fr" + GA = "ga" + GL = "gl" + HE = "he" + HI = "hi" + HU = "hu" + HY = "hy" + ID = "id" + IS = "is" + IT = "it" + JA = "ja" + KA = "ka" + KK = "kk" + KO = "ko" + KU = "ku" + KY = "ky" + LT = "lt" + LV = "lv" + MI = "mi" + MN = "mn" + MR = "mr" + MS = "ms" + MT = "mt" + NB = "nb" + NL = "nl" + NO = "no" + NS = "ns" + PL = "pl" + PS = "ps" + PT = "pt" + PT_MINUS_BR = "pt-br" + QU = "qu" + RO = "ro" + RU = "ru" + SK = "sk" + SQ = "sq" + SV = "sv" + SW = "sw" + TA = "ta" + TE = "te" + TH = "th" + TL = "tl" + TN = "tn" + TR = "tr" + TT = "tt" + UK = "uk" + UR = "ur" + UZ = "uz" + ZH = "zh" @classmethod diff --git a/algoliasearch/recommend/models/tag_filters.py b/algoliasearch/recommend/models/tag_filters.py index 415d360e9..eb88ff91e 100644 --- a/algoliasearch/recommend/models/tag_filters.py +++ b/algoliasearch/recommend/models/tag_filters.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, StrictStr, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -23,9 +23,12 @@ class TagFilters(BaseModel): Filter the search by values of the special `_tags` attribute. **Prefer using the `filters` parameter, which supports all filter types and combinations with boolean operators.** Different from regular facets, `_tags` can only be used for filtering (including or excluding records). You won't get a facet count. The same combination and escaping rules apply as for `facetFilters`. """ - oneof_schema_1_validator: Optional[List[TagFilters]] = None - oneof_schema_2_validator: Optional[StrictStr] = None + oneof_schema_1_validator: Optional[List[TagFilters]] = Field(default=None) + + oneof_schema_2_validator: Optional[str] = Field(default=None) + actual_instance: Optional[Union[List[TagFilters], str]] = None + one_of_schemas: Set[str] = {"List[TagFilters]", "str"} def __init__(self, *args, **kwargs) -> None: if args: @@ -49,7 +52,8 @@ def unwrap_actual_instance(self) -> Optional[Union[List[TagFilters], str]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of TagFilters from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -83,17 +87,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], List[TagFilters], str]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/recommend/models/task_status.py b/algoliasearch/recommend/models/task_status.py index d8b6799fb..4ee4bdde7 100644 --- a/algoliasearch/recommend/models/task_status.py +++ b/algoliasearch/recommend/models/task_status.py @@ -25,6 +25,7 @@ class TaskStatus(str, Enum): allowed enum values """ PUBLISHED = "published" + NOTPUBLISHED = "notPublished" @classmethod diff --git a/algoliasearch/recommend/models/trending_facet_hit.py b/algoliasearch/recommend/models/trending_facet_hit.py index e96f9bf9a..35bd3a914 100644 --- a/algoliasearch/recommend/models/trending_facet_hit.py +++ b/algoliasearch/recommend/models/trending_facet_hit.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class TrendingFacetHit(BaseModel): @@ -23,51 +23,38 @@ class TrendingFacetHit(BaseModel): Trending facet hit. """ - score: Union[ - Annotated[float, Field(le=100, strict=True, ge=0)], - Annotated[int, Field(le=100, strict=True, ge=0)], - ] = Field(description="Recommendation score.", alias="_score") - facet_name: StrictStr = Field( - description="Facet attribute. To be used in combination with `facetValue`. If specified, only recommendations matching the facet filter will be returned. ", - alias="facetName", - ) - facet_value: StrictStr = Field( - description="Facet value. To be used in combination with `facetName`. If specified, only recommendations matching the facet filter will be returned. ", - alias="facetValue", - ) + score: float = Field(alias="_score") + """ Recommendation score. """ + facet_name: str = Field(alias="facetName") + """ Facet attribute. To be used in combination with `facetValue`. If specified, only recommendations matching the facet filter will be returned. """ + facet_value: str = Field(alias="facetValue") + """ Facet value. To be used in combination with `facetName`. If specified, only recommendations matching the facet filter will be returned. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TrendingFacetHit from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TrendingFacetHit from a dict""" if obj is None: return None @@ -75,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "_score": obj.get("_score"), - "facetName": obj.get("facetName"), - "facetValue": obj.get("facetValue"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/trending_facets_query.py b/algoliasearch/recommend/models/trending_facets_query.py index d5ed90065..ebfe768b4 100644 --- a/algoliasearch/recommend/models/trending_facets_query.py +++ b/algoliasearch/recommend/models/trending_facets_query.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.recommend.models.fallback_params import FallbackParams @@ -28,70 +28,47 @@ class TrendingFacetsQuery(BaseModel): TrendingFacetsQuery """ - index_name: StrictStr = Field( - description="Index name (case-sensitive).", alias="indexName" - ) - threshold: Union[ - Annotated[float, Field(le=100, strict=True, ge=0)], - Annotated[int, Field(le=100, strict=True, ge=0)], - ] = Field( - description="Minimum score a recommendation must have to be included in the response." - ) - max_recommendations: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = ( - Field( - default=30, - description="Maximum number of recommendations to retrieve. By default, all recommendations are returned and no fallback request is made. Depending on the available recommendations and the other request parameters, the actual number of recommendations may be lower than this value. ", - alias="maxRecommendations", - ) - ) + index_name: str = Field(alias="indexName") + """ Index name (case-sensitive). """ + threshold: float = Field(alias="threshold") + """ Minimum score a recommendation must have to be included in the response. """ + max_recommendations: Optional[int] = Field(default=None, alias="maxRecommendations") + """ Maximum number of recommendations to retrieve. By default, all recommendations are returned and no fallback request is made. Depending on the available recommendations and the other request parameters, the actual number of recommendations may be lower than this value. """ query_parameters: Optional[RecommendSearchParams] = Field( default=None, alias="queryParameters" ) - facet_name: Optional[Any] = Field( - description="Facet attribute for which to retrieve trending facet values.", - alias="facetName", - ) - model: TrendingFacetsModel + facet_name: object = Field(alias="facetName") + """ Facet attribute for which to retrieve trending facet values. """ + model: TrendingFacetsModel = Field(alias="model") fallback_parameters: Optional[FallbackParams] = Field( default=None, alias="fallbackParameters" ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TrendingFacetsQuery from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.query_parameters: - _dict["queryParameters"] = self.query_parameters.to_dict() - if self.fallback_parameters: - _dict["fallbackParameters"] = self.fallback_parameters.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TrendingFacetsQuery from a dict""" if obj is None: return None @@ -99,23 +76,16 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "indexName": obj.get("indexName"), - "threshold": obj.get("threshold"), - "maxRecommendations": obj.get("maxRecommendations"), - "queryParameters": ( - RecommendSearchParams.from_dict(obj.get("queryParameters")) - if obj.get("queryParameters") is not None - else None - ), - "facetName": obj.get("facetName"), - "model": obj.get("model"), - "fallbackParameters": ( - FallbackParams.from_dict(obj.get("fallbackParameters")) - if obj.get("fallbackParameters") is not None - else None - ), - } + obj["queryParameters"] = ( + RecommendSearchParams.from_dict(obj["queryParameters"]) + if obj.get("queryParameters") is not None + else None ) - return _obj + obj["model"] = obj.get("model") + obj["fallbackParameters"] = ( + FallbackParams.from_dict(obj["fallbackParameters"]) + if obj.get("fallbackParameters") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/trending_items_query.py b/algoliasearch/recommend/models/trending_items_query.py index 9193a1372..a653b2298 100644 --- a/algoliasearch/recommend/models/trending_items_query.py +++ b/algoliasearch/recommend/models/trending_items_query.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.recommend.models.fallback_params import FallbackParams @@ -28,76 +28,49 @@ class TrendingItemsQuery(BaseModel): TrendingItemsQuery """ - index_name: StrictStr = Field( - description="Index name (case-sensitive).", alias="indexName" - ) - threshold: Union[ - Annotated[float, Field(le=100, strict=True, ge=0)], - Annotated[int, Field(le=100, strict=True, ge=0)], - ] = Field( - description="Minimum score a recommendation must have to be included in the response." - ) - max_recommendations: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = ( - Field( - default=30, - description="Maximum number of recommendations to retrieve. By default, all recommendations are returned and no fallback request is made. Depending on the available recommendations and the other request parameters, the actual number of recommendations may be lower than this value. ", - alias="maxRecommendations", - ) - ) + index_name: str = Field(alias="indexName") + """ Index name (case-sensitive). """ + threshold: float = Field(alias="threshold") + """ Minimum score a recommendation must have to be included in the response. """ + max_recommendations: Optional[int] = Field(default=None, alias="maxRecommendations") + """ Maximum number of recommendations to retrieve. By default, all recommendations are returned and no fallback request is made. Depending on the available recommendations and the other request parameters, the actual number of recommendations may be lower than this value. """ query_parameters: Optional[RecommendSearchParams] = Field( default=None, alias="queryParameters" ) - facet_name: Optional[StrictStr] = Field( - default=None, - description="Facet attribute. To be used in combination with `facetValue`. If specified, only recommendations matching the facet filter will be returned. ", - alias="facetName", - ) - facet_value: Optional[StrictStr] = Field( - default=None, - description="Facet value. To be used in combination with `facetName`. If specified, only recommendations matching the facet filter will be returned. ", - alias="facetValue", - ) - model: TrendingItemsModel + facet_name: Optional[str] = Field(default=None, alias="facetName") + """ Facet attribute. To be used in combination with `facetValue`. If specified, only recommendations matching the facet filter will be returned. """ + facet_value: Optional[str] = Field(default=None, alias="facetValue") + """ Facet value. To be used in combination with `facetName`. If specified, only recommendations matching the facet filter will be returned. """ + model: TrendingItemsModel = Field(alias="model") fallback_parameters: Optional[FallbackParams] = Field( default=None, alias="fallbackParameters" ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TrendingItemsQuery from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.query_parameters: - _dict["queryParameters"] = self.query_parameters.to_dict() - if self.fallback_parameters: - _dict["fallbackParameters"] = self.fallback_parameters.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TrendingItemsQuery from a dict""" if obj is None: return None @@ -105,24 +78,16 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "indexName": obj.get("indexName"), - "threshold": obj.get("threshold"), - "maxRecommendations": obj.get("maxRecommendations"), - "queryParameters": ( - RecommendSearchParams.from_dict(obj.get("queryParameters")) - if obj.get("queryParameters") is not None - else None - ), - "facetName": obj.get("facetName"), - "facetValue": obj.get("facetValue"), - "model": obj.get("model"), - "fallbackParameters": ( - FallbackParams.from_dict(obj.get("fallbackParameters")) - if obj.get("fallbackParameters") is not None - else None - ), - } + obj["queryParameters"] = ( + RecommendSearchParams.from_dict(obj["queryParameters"]) + if obj.get("queryParameters") is not None + else None ) - return _obj + obj["model"] = obj.get("model") + obj["fallbackParameters"] = ( + FallbackParams.from_dict(obj["fallbackParameters"]) + if obj.get("fallbackParameters") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/recommend/models/typo_tolerance.py b/algoliasearch/recommend/models/typo_tolerance.py index 1181de1d4..bae2ec6d4 100644 --- a/algoliasearch/recommend/models/typo_tolerance.py +++ b/algoliasearch/recommend/models/typo_tolerance.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, Field, StrictBool, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -26,12 +26,12 @@ class TypoTolerance(BaseModel): Whether [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/) is enabled and how it is applied. If typo tolerance is true, `min`, or `strict`, [word splitting and concetenation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/splitting-and-concatenation/) is also active. """ - oneof_schema_1_validator: Optional[StrictBool] = Field( - default=True, - description="Whether typo tolerance is active. If true, matches with typos are included in the search results and rank after exact matches.", - ) - oneof_schema_2_validator: Optional[TypoToleranceEnum] = None + oneof_schema_1_validator: Optional[bool] = Field(default=None) + """ Whether typo tolerance is active. If true, matches with typos are included in the search results and rank after exact matches. """ + oneof_schema_2_validator: Optional[TypoToleranceEnum] = Field(default=None) + actual_instance: Optional[Union[TypoToleranceEnum, bool]] = None + one_of_schemas: Set[str] = {"TypoToleranceEnum", "bool"} def __init__(self, *args, **kwargs) -> None: if args: @@ -55,7 +55,8 @@ def unwrap_actual_instance(self) -> Optional[Union[TypoToleranceEnum, bool]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of TypoTolerance from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -88,17 +89,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], TypoToleranceEnum, bool]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/recommend/models/typo_tolerance_enum.py b/algoliasearch/recommend/models/typo_tolerance_enum.py index 932d1aabd..89fb2234b 100644 --- a/algoliasearch/recommend/models/typo_tolerance_enum.py +++ b/algoliasearch/recommend/models/typo_tolerance_enum.py @@ -25,6 +25,7 @@ class TypoToleranceEnum(str, Enum): allowed enum values """ MIN = "min" + STRICT = "strict" @classmethod diff --git a/algoliasearch/recommend/models/value.py b/algoliasearch/recommend/models/value.py index 6a796454a..a78eb08a1 100644 --- a/algoliasearch/recommend/models/value.py +++ b/algoliasearch/recommend/models/value.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,49 +26,39 @@ class Value(BaseModel): Value """ - order: Optional[List[StrictStr]] = Field( - default=None, - description="Explicit order of facets or facet values. This setting lets you always show specific facets or facet values at the top of the list. ", - ) + order: Optional[List[str]] = Field(default=None, alias="order") + """ Explicit order of facets or facet values. This setting lets you always show specific facets or facet values at the top of the list. """ sort_remaining_by: Optional[SortRemainingBy] = Field( default=None, alias="sortRemainingBy" ) - hide: Optional[List[StrictStr]] = Field( - default=None, description="Hide facet values." - ) + hide: Optional[List[str]] = Field(default=None, alias="hide") + """ Hide facet values. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Value from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Value from a dict""" if obj is None: return None @@ -76,11 +66,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "order": obj.get("order"), - "sortRemainingBy": obj.get("sortRemainingBy"), - "hide": obj.get("hide"), - } - ) - return _obj + obj["sortRemainingBy"] = obj.get("sortRemainingBy") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/client.py b/algoliasearch/search/client.py index 69bff4590..bba17d70b 100644 --- a/algoliasearch/search/client.py +++ b/algoliasearch/search/client.py @@ -18,11 +18,12 @@ from urllib.parse import quote from pydantic import Field, StrictBool, StrictInt, StrictStr +from typing_extensions import Annotated if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.http.api_response import ApiResponse from algoliasearch.http.exceptions import RequestException, ValidUntilNotFoundException diff --git a/algoliasearch/search/models/acl.py b/algoliasearch/search/models/acl.py index 4ddf0ee91..8bc638d8b 100644 --- a/algoliasearch/search/models/acl.py +++ b/algoliasearch/search/models/acl.py @@ -25,19 +25,33 @@ class Acl(str, Enum): allowed enum values """ ADDOBJECT = "addObject" + ANALYTICS = "analytics" + BROWSE = "browse" + DELETEOBJECT = "deleteObject" + DELETEINDEX = "deleteIndex" + EDITSETTINGS = "editSettings" + INFERENCE = "inference" + LISTINDEXES = "listIndexes" + LOGS = "logs" + PERSONALIZATION = "personalization" + RECOMMENDATION = "recommendation" + SEARCH = "search" + SEEUNRETRIEVABLEATTRIBUTES = "seeUnretrievableAttributes" + SETTINGS = "settings" + USAGE = "usage" @classmethod diff --git a/algoliasearch/search/models/action.py b/algoliasearch/search/models/action.py index 18092e4c6..dd0a0b7ba 100644 --- a/algoliasearch/search/models/action.py +++ b/algoliasearch/search/models/action.py @@ -25,11 +25,17 @@ class Action(str, Enum): allowed enum values """ ADDOBJECT = "addObject" + UPDATEOBJECT = "updateObject" + PARTIALUPDATEOBJECT = "partialUpdateObject" + PARTIALUPDATEOBJECTNOCREATE = "partialUpdateObjectNoCreate" + DELETEOBJECT = "deleteObject" + DELETE = "delete" + CLEAR = "clear" @classmethod diff --git a/algoliasearch/search/models/add_api_key_response.py b/algoliasearch/search/models/add_api_key_response.py index abe827891..fa2a4b326 100644 --- a/algoliasearch/search/models/add_api_key_response.py +++ b/algoliasearch/search/models/add_api_key_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,44 +23,36 @@ class AddApiKeyResponse(BaseModel): AddApiKeyResponse """ - key: StrictStr = Field(description="API key.") - created_at: StrictStr = Field( - description="Date and time when the object was created, in RFC 3339 format.", - alias="createdAt", - ) + key: str = Field(alias="key") + """ API key. """ + created_at: str = Field(alias="createdAt") + """ Date and time when the object was created, in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AddApiKeyResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AddApiKeyResponse from a dict""" if obj is None: return None @@ -68,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"key": obj.get("key"), "createdAt": obj.get("createdAt")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/advanced_syntax_features.py b/algoliasearch/search/models/advanced_syntax_features.py index a6834c55b..b9ff26102 100644 --- a/algoliasearch/search/models/advanced_syntax_features.py +++ b/algoliasearch/search/models/advanced_syntax_features.py @@ -25,6 +25,7 @@ class AdvancedSyntaxFeatures(str, Enum): allowed enum values """ EXACTPHRASE = "exactPhrase" + EXCLUDEWORDS = "excludeWords" @classmethod diff --git a/algoliasearch/search/models/alternatives_as_exact.py b/algoliasearch/search/models/alternatives_as_exact.py index 8be3c9da6..988dff0ad 100644 --- a/algoliasearch/search/models/alternatives_as_exact.py +++ b/algoliasearch/search/models/alternatives_as_exact.py @@ -25,7 +25,9 @@ class AlternativesAsExact(str, Enum): allowed enum values """ IGNOREPLURALS = "ignorePlurals" + SINGLEWORDSYNONYM = "singleWordSynonym" + MULTIWORDSSYNONYM = "multiWordsSynonym" @classmethod diff --git a/algoliasearch/search/models/anchoring.py b/algoliasearch/search/models/anchoring.py index 0400ffb4a..efb93d563 100644 --- a/algoliasearch/search/models/anchoring.py +++ b/algoliasearch/search/models/anchoring.py @@ -25,8 +25,11 @@ class Anchoring(str, Enum): allowed enum values """ IS = "is" + STARTSWITH = "startsWith" + ENDSWITH = "endsWith" + CONTAINS = "contains" @classmethod diff --git a/algoliasearch/search/models/api_key.py b/algoliasearch/search/models/api_key.py index 4b0d89fbe..d08aeb17d 100644 --- a/algoliasearch/search/models/api_key.py +++ b/algoliasearch/search/models/api_key.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,73 +26,50 @@ class ApiKey(BaseModel): API key object. """ - acl: List[Acl] = Field( - description="Permissions that determine the type of API requests this key can make. The required ACL is listed in each endpoint's reference. For more information, see [access control list](https://www.algolia.com/doc/guides/security/api-keys/#access-control-list-acl). " - ) - description: Optional[StrictStr] = Field( - default="", - description="Description of an API key to help you identify this API key.", - ) - indexes: Optional[List[StrictStr]] = Field( - default=None, - description='Index names or patterns that this API key can access. By default, an API key can access all indices in the same application. You can use leading and trailing wildcard characters (`*`): - `dev_*` matches all indices starting with "dev_". - `*_dev` matches all indices ending with "_dev". - `*_products_*` matches all indices containing "_products_". ', - ) - max_hits_per_query: Optional[StrictInt] = Field( - default=0, - description="Maximum number of results this API key can retrieve in one query. By default, there's no limit. ", - alias="maxHitsPerQuery", - ) - max_queries_per_ip_per_hour: Optional[StrictInt] = Field( - default=0, - description="Maximum number of API requests allowed per IP address or [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/) per hour. If this limit is reached, the API returns an error with status code `429`. By default, there's no limit. ", - alias="maxQueriesPerIPPerHour", - ) - query_parameters: Optional[StrictStr] = Field( - default="", - description="Query parameters to add when making API requests with this API key. To restrict this API key to specific IP addresses, add the `restrictSources` parameter. You can only add a single source, but you can provide a range of IP addresses. Creating an API key fails if the request is made from an IP address that's outside the restricted range. ", - alias="queryParameters", - ) - referers: Optional[List[StrictStr]] = Field( - default=None, - description='Allowed HTTP referrers for this API key. By default, all referrers are allowed. You can use leading and trailing wildcard characters (`*`): - `https://algolia.com/*` allows all referrers starting with "https://algolia.com/" - `*.algolia.com` allows all referrers ending with ".algolia.com" - `*algolia.com*` allows all referrers in the domain "algolia.com". Like all HTTP headers, referrers can be spoofed. Don\'t rely on them to secure your data. For more information, see [HTTP referrer restrictions](https://www.algolia.com/doc/guides/security/security-best-practices/#http-referrers-restrictions). ', - ) - validity: Optional[StrictInt] = Field( - default=0, - description="Duration (in seconds) after which the API key expires. By default, API keys don't expire. ", + acl: List[Acl] = Field(alias="acl") + """ Permissions that determine the type of API requests this key can make. The required ACL is listed in each endpoint's reference. For more information, see [access control list](https://www.algolia.com/doc/guides/security/api-keys/#access-control-list-acl). """ + description: Optional[str] = Field(default=None, alias="description") + """ Description of an API key to help you identify this API key. """ + indexes: Optional[List[str]] = Field(default=None, alias="indexes") + """ Index names or patterns that this API key can access. By default, an API key can access all indices in the same application. You can use leading and trailing wildcard characters (`*`): - `dev_*` matches all indices starting with \"dev_\". - `*_dev` matches all indices ending with \"_dev\". - `*_products_*` matches all indices containing \"_products_\". """ + max_hits_per_query: Optional[int] = Field(default=None, alias="maxHitsPerQuery") + """ Maximum number of results this API key can retrieve in one query. By default, there's no limit. """ + max_queries_per_ip_per_hour: Optional[int] = Field( + default=None, alias="maxQueriesPerIPPerHour" ) + """ Maximum number of API requests allowed per IP address or [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/) per hour. If this limit is reached, the API returns an error with status code `429`. By default, there's no limit. """ + query_parameters: Optional[str] = Field(default=None, alias="queryParameters") + """ Query parameters to add when making API requests with this API key. To restrict this API key to specific IP addresses, add the `restrictSources` parameter. You can only add a single source, but you can provide a range of IP addresses. Creating an API key fails if the request is made from an IP address that's outside the restricted range. """ + referers: Optional[List[str]] = Field(default=None, alias="referers") + """ Allowed HTTP referrers for this API key. By default, all referrers are allowed. You can use leading and trailing wildcard characters (`*`): - `https://algolia.com/*` allows all referrers starting with \"https://algolia.com/\" - `*.algolia.com` allows all referrers ending with \".algolia.com\" - `*algolia.com*` allows all referrers in the domain \"algolia.com\". Like all HTTP headers, referrers can be spoofed. Don't rely on them to secure your data. For more information, see [HTTP referrer restrictions](https://www.algolia.com/doc/guides/security/security-best-practices/#http-referrers-restrictions). """ + validity: Optional[int] = Field(default=None, alias="validity") + """ Duration (in seconds) after which the API key expires. By default, API keys don't expire. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ApiKey from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ApiKey from a dict""" if obj is None: return None @@ -100,16 +77,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "acl": obj.get("acl"), - "description": obj.get("description"), - "indexes": obj.get("indexes"), - "maxHitsPerQuery": obj.get("maxHitsPerQuery"), - "maxQueriesPerIPPerHour": obj.get("maxQueriesPerIPPerHour"), - "queryParameters": obj.get("queryParameters"), - "referers": obj.get("referers"), - "validity": obj.get("validity"), - } - ) - return _obj + obj["acl"] = obj.get("acl") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/api_key_operation.py b/algoliasearch/search/models/api_key_operation.py index bfe871eb5..a76599a74 100644 --- a/algoliasearch/search/models/api_key_operation.py +++ b/algoliasearch/search/models/api_key_operation.py @@ -25,7 +25,9 @@ class ApiKeyOperation(str, Enum): allowed enum values """ ADD = "add" + DELETE = "delete" + UPDATE = "update" @classmethod diff --git a/algoliasearch/search/models/around_precision.py b/algoliasearch/search/models/around_precision.py index 27b589ad6..a1be2c4af 100644 --- a/algoliasearch/search/models/around_precision.py +++ b/algoliasearch/search/models/around_precision.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, Field, StrictInt, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -26,12 +26,12 @@ class AroundPrecision(BaseModel): Precision of a coordinate-based search in meters to group results with similar distances. The Geo ranking criterion considers all matches within the same range of distances to be equal. """ - oneof_schema_1_validator: Optional[StrictInt] = Field( - default=10, - description="Distance in meters to group results by similar distances. For example, if you set `aroundPrecision` to 100, records wihin 100 meters to the central coordinate are considered to have the same distance, as are records between 100 and 199 meters. ", - ) - oneof_schema_2_validator: Optional[List[Range]] = None + oneof_schema_1_validator: Optional[int] = Field(default=None) + """ Distance in meters to group results by similar distances. For example, if you set `aroundPrecision` to 100, records wihin 100 meters to the central coordinate are considered to have the same distance, as are records between 100 and 199 meters. """ + oneof_schema_2_validator: Optional[List[Range]] = Field(default=None) + actual_instance: Optional[Union[List[Range], int]] = None + one_of_schemas: Set[str] = {"List[Range]", "int"} def __init__(self, *args, **kwargs) -> None: if args: @@ -55,7 +55,8 @@ def unwrap_actual_instance(self) -> Optional[Union[List[Range], int]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of AroundPrecision from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -89,17 +90,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], List[Range], int]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/around_radius.py b/algoliasearch/search/models/around_radius.py index 5b2b785fe..73bfa99b8 100644 --- a/algoliasearch/search/models/around_radius.py +++ b/algoliasearch/search/models/around_radius.py @@ -8,14 +8,14 @@ from json import dumps, loads from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.around_radius_all import AroundRadiusAll @@ -26,14 +26,12 @@ class AroundRadius(BaseModel): Maximum radius for a search around a central location. This parameter works in combination with the `aroundLatLng` and `aroundLatLngViaIP` parameters. By default, the search radius is determined automatically from the density of hits around the central location. The search radius is small if there are many hits close to the central coordinates. """ - oneof_schema_1_validator: Optional[Annotated[int, Field(strict=True, ge=1)]] = ( - Field( - default=None, - description="Maximum search radius around a central location in meters.", - ) - ) - oneof_schema_2_validator: Optional[AroundRadiusAll] = None + oneof_schema_1_validator: Optional[int] = Field(default=None) + """ Maximum search radius around a central location in meters. """ + oneof_schema_2_validator: Optional[AroundRadiusAll] = Field(default=None) + actual_instance: Optional[Union[AroundRadiusAll, int]] = None + one_of_schemas: Set[str] = {"AroundRadiusAll", "int"} def __init__(self, *args, **kwargs) -> None: if args: @@ -57,7 +55,8 @@ def unwrap_actual_instance(self) -> Optional[Union[AroundRadiusAll, int]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of AroundRadius from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -90,17 +89,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], AroundRadiusAll, int]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/assign_user_id_params.py b/algoliasearch/search/models/assign_user_id_params.py index 67421acc4..77cd64bec 100644 --- a/algoliasearch/search/models/assign_user_id_params.py +++ b/algoliasearch/search/models/assign_user_id_params.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,40 +23,34 @@ class AssignUserIdParams(BaseModel): Assign userID parameters. """ - cluster: StrictStr = Field(description="Cluster name.") + cluster: str = Field(alias="cluster") + """ Cluster name. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AssignUserIdParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AssignUserIdParams from a dict""" if obj is None: return None @@ -64,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"cluster": obj.get("cluster")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/attribute_to_update.py b/algoliasearch/search/models/attribute_to_update.py index 305d84b49..63608a107 100644 --- a/algoliasearch/search/models/attribute_to_update.py +++ b/algoliasearch/search/models/attribute_to_update.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, StrictStr, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -26,9 +26,12 @@ class AttributeToUpdate(BaseModel): AttributeToUpdate """ - oneof_schema_1_validator: Optional[StrictStr] = None - oneof_schema_2_validator: Optional[BuiltInOperation] = None + oneof_schema_1_validator: Optional[str] = Field(default=None) + + oneof_schema_2_validator: Optional[BuiltInOperation] = Field(default=None) + actual_instance: Optional[Union[BuiltInOperation, str]] = None + one_of_schemas: Set[str] = {"BuiltInOperation", "str"} def __init__(self, *args, **kwargs) -> None: if args: @@ -52,7 +55,8 @@ def unwrap_actual_instance(self) -> Optional[Union[BuiltInOperation, str]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of AttributeToUpdate from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -85,17 +89,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], BuiltInOperation, str]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/automatic_facet_filter.py b/algoliasearch/search/models/automatic_facet_filter.py index c0c1120d5..5a2610015 100644 --- a/algoliasearch/search/models/automatic_facet_filter.py +++ b/algoliasearch/search/models/automatic_facet_filter.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,50 +23,38 @@ class AutomaticFacetFilter(BaseModel): Filter or optional filter to be applied to the search. """ - facet: StrictStr = Field( - description="Facet name to be applied as filter. The name must match placeholders in the `pattern` parameter. For example, with `pattern: {facet:genre}`, `automaticFacetFilters` must be `genre`. " - ) - score: Optional[StrictInt] = Field( - default=1, - description="Filter scores to give different weights to individual filters.", - ) - disjunctive: Optional[StrictBool] = Field( - default=False, - description="Whether the filter is disjunctive or conjunctive. If true the filter has multiple matches, multiple occurences are combined with the logical `OR` operation. If false, multiple occurences are combined with the logical `AND` operation. ", - ) + facet: str = Field(alias="facet") + """ Facet name to be applied as filter. The name must match placeholders in the `pattern` parameter. For example, with `pattern: {facet:genre}`, `automaticFacetFilters` must be `genre`. """ + score: Optional[int] = Field(default=None, alias="score") + """ Filter scores to give different weights to individual filters. """ + disjunctive: Optional[bool] = Field(default=None, alias="disjunctive") + """ Whether the filter is disjunctive or conjunctive. If true the filter has multiple matches, multiple occurences are combined with the logical `OR` operation. If false, multiple occurences are combined with the logical `AND` operation. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of AutomaticFacetFilter from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of AutomaticFacetFilter from a dict""" if obj is None: return None @@ -74,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "facet": obj.get("facet"), - "score": obj.get("score"), - "disjunctive": obj.get("disjunctive"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/automatic_facet_filters.py b/algoliasearch/search/models/automatic_facet_filters.py index c4540923e..9e408c85e 100644 --- a/algoliasearch/search/models/automatic_facet_filters.py +++ b/algoliasearch/search/models/automatic_facet_filters.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, StrictStr, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -26,9 +26,12 @@ class AutomaticFacetFilters(BaseModel): Filter to be applied to the search. You can use this to respond to search queries that match a facet value. For example, if users search for \"comedy\", which matches a facet value of the \"genre\" facet, you can filter the results to show the top-ranked comedy movies. """ - oneof_schema_1_validator: Optional[List[AutomaticFacetFilter]] = None - oneof_schema_2_validator: Optional[List[StrictStr]] = None + oneof_schema_1_validator: Optional[List[AutomaticFacetFilter]] = Field(default=None) + + oneof_schema_2_validator: Optional[List[str]] = Field(default=None) + actual_instance: Optional[Union[List[AutomaticFacetFilter], List[str]]] = None + one_of_schemas: Set[str] = {"List[AutomaticFacetFilter]", "List[str]"} def __init__(self, *args, **kwargs) -> None: if args: @@ -54,7 +57,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of AutomaticFacetFilters from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -88,17 +92,23 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[Union[Dict[str, Any], List[AutomaticFacetFilter], List[str]]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/batch_assign_user_ids_params.py b/algoliasearch/search/models/batch_assign_user_ids_params.py index 4d79fafdd..a89349963 100644 --- a/algoliasearch/search/models/batch_assign_user_ids_params.py +++ b/algoliasearch/search/models/batch_assign_user_ids_params.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,41 +23,36 @@ class BatchAssignUserIdsParams(BaseModel): Assign userID parameters. """ - cluster: StrictStr = Field(description="Cluster name.") - users: List[StrictStr] = Field(description="User IDs to assign.") + cluster: str = Field(alias="cluster") + """ Cluster name. """ + users: List[str] = Field(alias="users") + """ User IDs to assign. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of BatchAssignUserIdsParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of BatchAssignUserIdsParams from a dict""" if obj is None: return None @@ -65,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"cluster": obj.get("cluster"), "users": obj.get("users")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/batch_dictionary_entries_params.py b/algoliasearch/search/models/batch_dictionary_entries_params.py index 32ddcad45..fea54a98a 100644 --- a/algoliasearch/search/models/batch_dictionary_entries_params.py +++ b/algoliasearch/search/models/batch_dictionary_entries_params.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,53 +28,38 @@ class BatchDictionaryEntriesParams(BaseModel): Request body for updating dictionary entries. """ - clear_existing_dictionary_entries: Optional[StrictBool] = Field( - default=False, - description="Whether to replace all custom entries in the dictionary with the ones sent with this request.", - alias="clearExistingDictionaryEntries", - ) - requests: List[BatchDictionaryEntriesRequest] = Field( - description="List of additions and deletions to your dictionaries." + clear_existing_dictionary_entries: Optional[bool] = Field( + default=None, alias="clearExistingDictionaryEntries" ) + """ Whether to replace all custom entries in the dictionary with the ones sent with this request. """ + requests: List[BatchDictionaryEntriesRequest] = Field(alias="requests") + """ List of additions and deletions to your dictionaries. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of BatchDictionaryEntriesParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.requests: - for _item in self.requests: - if _item: - _items.append(_item.to_dict()) - _dict["requests"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of BatchDictionaryEntriesParams from a dict""" if obj is None: return None @@ -82,19 +67,13 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "clearExistingDictionaryEntries": obj.get( - "clearExistingDictionaryEntries" - ), - "requests": ( - [ - BatchDictionaryEntriesRequest.from_dict(_item) - for _item in obj.get("requests") - ] - if obj.get("requests") is not None - else None - ), - } + obj["requests"] = ( + [ + BatchDictionaryEntriesRequest.from_dict(_item) + for _item in obj["requests"] + ] + if obj.get("requests") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/batch_dictionary_entries_request.py b/algoliasearch/search/models/batch_dictionary_entries_request.py index 00679db65..491af947a 100644 --- a/algoliasearch/search/models/batch_dictionary_entries_request.py +++ b/algoliasearch/search/models/batch_dictionary_entries_request.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,43 +27,34 @@ class BatchDictionaryEntriesRequest(BaseModel): BatchDictionaryEntriesRequest """ - action: DictionaryAction - body: DictionaryEntry + action: DictionaryAction = Field(alias="action") + body: DictionaryEntry = Field(alias="body") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of BatchDictionaryEntriesRequest from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.body: - _dict["body"] = self.body.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of BatchDictionaryEntriesRequest from a dict""" if obj is None: return None @@ -71,14 +62,11 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "action": obj.get("action"), - "body": ( - DictionaryEntry.from_dict(obj.get("body")) - if obj.get("body") is not None - else None - ), - } + obj["action"] = obj.get("action") + obj["body"] = ( + DictionaryEntry.from_dict(obj["body"]) + if obj.get("body") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/batch_params.py b/algoliasearch/search/models/batch_params.py index 90cca9fef..63e961f4d 100644 --- a/algoliasearch/search/models/batch_params.py +++ b/algoliasearch/search/models/batch_params.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,46 +26,33 @@ class BatchParams(BaseModel): Batch parameters. """ - requests: List[MultipleBatchRequest] + requests: List[MultipleBatchRequest] = Field(alias="requests") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of BatchParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.requests: - for _item in self.requests: - if _item: - _items.append(_item.to_dict()) - _dict["requests"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of BatchParams from a dict""" if obj is None: return None @@ -73,16 +60,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "requests": ( - [ - MultipleBatchRequest.from_dict(_item) - for _item in obj.get("requests") - ] - if obj.get("requests") is not None - else None - ) - } + obj["requests"] = ( + [MultipleBatchRequest.from_dict(_item) for _item in obj["requests"]] + if obj.get("requests") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/batch_request.py b/algoliasearch/search/models/batch_request.py index 2093e9840..22ff93915 100644 --- a/algoliasearch/search/models/batch_request.py +++ b/algoliasearch/search/models/batch_request.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional from pydantic import BaseModel, ConfigDict, Field @@ -26,43 +26,35 @@ class BatchRequest(BaseModel): BatchRequest """ - action: Action - body: Dict[str, Any] = Field( - description="Operation arguments (varies with specified `action`)." - ) + action: Action = Field(alias="action") + body: object = Field(alias="body") + """ Operation arguments (varies with specified `action`). """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of BatchRequest from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of BatchRequest from a dict""" if obj is None: return None @@ -70,7 +62,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"action": obj.get("action"), "body": obj.get("body")} - ) - return _obj + obj["action"] = obj.get("action") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/batch_response.py b/algoliasearch/search/models/batch_response.py index e6ae58d88..cd2b01324 100644 --- a/algoliasearch/search/models/batch_response.py +++ b/algoliasearch/search/models/batch_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,46 +23,36 @@ class BatchResponse(BaseModel): BatchResponse """ - task_id: StrictInt = Field( - description="Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. ", - alias="taskID", - ) - object_ids: List[StrictStr] = Field( - description="Unique record identifiers.", alias="objectIDs" - ) + task_id: int = Field(alias="taskID") + """ Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. """ + object_ids: List[str] = Field(alias="objectIDs") + """ Unique record identifiers. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of BatchResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of BatchResponse from a dict""" if obj is None: return None @@ -70,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"taskID": obj.get("taskID"), "objectIDs": obj.get("objectIDs")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/batch_write_params.py b/algoliasearch/search/models/batch_write_params.py index b82912b73..7413ab13e 100644 --- a/algoliasearch/search/models/batch_write_params.py +++ b/algoliasearch/search/models/batch_write_params.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,46 +26,33 @@ class BatchWriteParams(BaseModel): Batch parameters. """ - requests: List[BatchRequest] + requests: List[BatchRequest] = Field(alias="requests") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of BatchWriteParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.requests: - for _item in self.requests: - if _item: - _items.append(_item.to_dict()) - _dict["requests"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of BatchWriteParams from a dict""" if obj is None: return None @@ -73,13 +60,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "requests": ( - [BatchRequest.from_dict(_item) for _item in obj.get("requests")] - if obj.get("requests") is not None - else None - ) - } + obj["requests"] = ( + [BatchRequest.from_dict(_item) for _item in obj["requests"]] + if obj.get("requests") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/boolean_string.py b/algoliasearch/search/models/boolean_string.py index 5cf024f8a..cd4f50891 100644 --- a/algoliasearch/search/models/boolean_string.py +++ b/algoliasearch/search/models/boolean_string.py @@ -25,6 +25,7 @@ class BooleanString(str, Enum): allowed enum values """ TRUE = "true" + FALSE = "false" @classmethod diff --git a/algoliasearch/search/models/browse_params.py b/algoliasearch/search/models/browse_params.py index d38ba66e0..e05bfb68a 100644 --- a/algoliasearch/search/models/browse_params.py +++ b/algoliasearch/search/models/browse_params.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -27,9 +27,12 @@ class BrowseParams(BaseModel): BrowseParams """ - oneof_schema_1_validator: Optional[SearchParamsString] = None - oneof_schema_2_validator: Optional[BrowseParamsObject] = None + oneof_schema_1_validator: Optional[SearchParamsString] = Field(default=None) + + oneof_schema_2_validator: Optional[BrowseParamsObject] = Field(default=None) + actual_instance: Optional[Union[BrowseParamsObject, SearchParamsString]] = None + one_of_schemas: Set[str] = {"BrowseParamsObject", "SearchParamsString"} def __init__(self, *args, **kwargs) -> None: if args: @@ -55,7 +58,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of BrowseParams from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -87,17 +91,23 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[Union[Dict[str, Any], BrowseParamsObject, SearchParamsString]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/browse_params_object.py b/algoliasearch/search/models/browse_params_object.py index f46a8687d..5e6e03b9e 100644 --- a/algoliasearch/search/models/browse_params_object.py +++ b/algoliasearch/search/models/browse_params_object.py @@ -8,22 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional -from pydantic import ( - BaseModel, - ConfigDict, - Field, - StrictBool, - StrictFloat, - StrictInt, - StrictStr, -) +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.advanced_syntax_features import AdvancedSyntaxFeatures @@ -57,16 +49,12 @@ class BrowseParamsObject(BaseModel): BrowseParamsObject """ - query: Optional[StrictStr] = Field(default="", description="Search query.") - similar_query: Optional[StrictStr] = Field( - default="", - description="Keywords to be used instead of the search query to conduct a more broader search. Using the `similarQuery` parameter changes other settings: - `queryType` is set to `prefixNone`. - `removeStopWords` is set to true. - `words` is set as the first ranking criterion. - All remaining words are treated as `optionalWords`. Since the `similarQuery` is supposed to do a broad search, they usually return many results. Combine it with `filters` to narrow down the list of results. ", - alias="similarQuery", - ) - filters: Optional[StrictStr] = Field( - default=None, - description="Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). ", - ) + query: Optional[str] = Field(default=None, alias="query") + """ Search query. """ + similar_query: Optional[str] = Field(default=None, alias="similarQuery") + """ Keywords to be used instead of the search query to conduct a more broader search. Using the `similarQuery` parameter changes other settings: - `queryType` is set to `prefixNone`. - `removeStopWords` is set to true. - `words` is set as the first ranking criterion. - All remaining words are treated as `optionalWords`. Since the `similarQuery` is supposed to do a broad search, they usually return many results. Combine it with `filters` to narrow down the list of results. """ + filters: Optional[str] = Field(default=None, alias="filters") + """ Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). """ facet_filters: Optional[FacetFilters] = Field(default=None, alias="facetFilters") optional_filters: Optional[OptionalFilters] = Field( default=None, alias="optionalFilters" @@ -75,377 +63,229 @@ class BrowseParamsObject(BaseModel): default=None, alias="numericFilters" ) tag_filters: Optional[TagFilters] = Field(default=None, alias="tagFilters") - sum_or_filters_scores: Optional[StrictBool] = Field( - default=False, - description="Whether to sum all filter scores. If true, all filter scores are summed. Otherwise, the maximum filter score is kept. For more information, see [filter scores](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/#accumulating-scores-with-sumorfiltersscores). ", - alias="sumOrFiltersScores", - ) - restrict_searchable_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Restricts a search to a subset of your searchable attributes. Attribute names are case-sensitive. ", - alias="restrictSearchableAttributes", - ) - facets: Optional[List[StrictStr]] = Field( - default=None, - description="Facets for which to retrieve facet values that match the search criteria and the number of matching facet values. To retrieve all facets, use the wildcard character `*`. For more information, see [facets](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#contextual-facet-values-and-counts). ", - ) - faceting_after_distinct: Optional[StrictBool] = Field( - default=False, - description="Whether faceting should be applied after deduplication with `distinct`. This leads to accurate facet counts when using faceting in combination with `distinct`. It's usually better to use `afterDistinct` modifiers in the `attributesForFaceting` setting, as `facetingAfterDistinct` only computes correct facet counts if all records have the same facet values for the `attributeForDistinct`. ", - alias="facetingAfterDistinct", - ) - page: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=0, description="Page of search results to retrieve." - ) - offset: Optional[StrictInt] = Field( - default=None, description="Position of the first hit to retrieve." - ) - length: Optional[Annotated[int, Field(le=1000, strict=True, ge=0)]] = Field( - default=None, - description="Number of hits to retrieve (used in combination with `offset`).", - ) - around_lat_lng: Optional[StrictStr] = Field( - default="", - description="Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude. Only records included within circle around this central location are included in the results. The radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings. This parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`. ", - alias="aroundLatLng", - ) - around_lat_lng_via_ip: Optional[StrictBool] = Field( - default=False, - description="Whether to obtain the coordinates from the request's IP address.", - alias="aroundLatLngViaIP", - ) + sum_or_filters_scores: Optional[bool] = Field( + default=None, alias="sumOrFiltersScores" + ) + """ Whether to sum all filter scores. If true, all filter scores are summed. Otherwise, the maximum filter score is kept. For more information, see [filter scores](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/#accumulating-scores-with-sumorfiltersscores). """ + restrict_searchable_attributes: Optional[List[str]] = Field( + default=None, alias="restrictSearchableAttributes" + ) + """ Restricts a search to a subset of your searchable attributes. Attribute names are case-sensitive. """ + facets: Optional[List[str]] = Field(default=None, alias="facets") + """ Facets for which to retrieve facet values that match the search criteria and the number of matching facet values. To retrieve all facets, use the wildcard character `*`. For more information, see [facets](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#contextual-facet-values-and-counts). """ + faceting_after_distinct: Optional[bool] = Field( + default=None, alias="facetingAfterDistinct" + ) + """ Whether faceting should be applied after deduplication with `distinct`. This leads to accurate facet counts when using faceting in combination with `distinct`. It's usually better to use `afterDistinct` modifiers in the `attributesForFaceting` setting, as `facetingAfterDistinct` only computes correct facet counts if all records have the same facet values for the `attributeForDistinct`. """ + page: Optional[int] = Field(default=None, alias="page") + """ Page of search results to retrieve. """ + offset: Optional[int] = Field(default=None, alias="offset") + """ Position of the first hit to retrieve. """ + length: Optional[int] = Field(default=None, alias="length") + """ Number of hits to retrieve (used in combination with `offset`). """ + around_lat_lng: Optional[str] = Field(default=None, alias="aroundLatLng") + """ Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude. Only records included within circle around this central location are included in the results. The radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings. This parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`. """ + around_lat_lng_via_ip: Optional[bool] = Field( + default=None, alias="aroundLatLngViaIP" + ) + """ Whether to obtain the coordinates from the request's IP address. """ around_radius: Optional[AroundRadius] = Field(default=None, alias="aroundRadius") around_precision: Optional[AroundPrecision] = Field( default=None, alias="aroundPrecision" ) - minimum_around_radius: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field( - default=None, - description="Minimum radius (in meters) for a search around a location when `aroundRadius` isn't set.", - alias="minimumAroundRadius", - ) - inside_bounding_box: Optional[ - List[ - Annotated[ - List[Union[StrictFloat, StrictInt]], Field(min_length=4, max_length=4) - ] - ] - ] = Field( - default=None, - description="Coordinates for a rectangular area in which to search. Each bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair: `[p1 lat, p1 long, p2 lat, p2 long]`. Provide multiple bounding boxes as nested arrays. For more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). ", - alias="insideBoundingBox", - ) - inside_polygon: Optional[ - List[ - Annotated[ - List[Union[StrictFloat, StrictInt]], - Field(min_length=6, max_length=20000), - ] - ] - ] = Field( - default=None, - description="Coordinates of a polygon in which to search. Polygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude. Provide multiple polygons as nested arrays. For more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). This parameter is ignored if you also specify `insideBoundingBox`. ", - alias="insidePolygon", + minimum_around_radius: Optional[int] = Field( + default=None, alias="minimumAroundRadius" ) - natural_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="ISO language codes that adjust settings that are useful for processing natural language queries (as opposed to keyword searches): - Sets `removeStopWords` and `ignorePlurals` to the list of provided languages. - Sets `removeWordsIfNoResults` to `allOptional`. - Adds a `natural_language` attribute to `ruleContexts` and `analyticsTags`. ", - alias="naturalLanguages", - ) - rule_contexts: Optional[List[StrictStr]] = Field( - default=None, - description="Assigns a rule context to the search query. [Rule contexts](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/how-to/customize-search-results-by-platform/#whats-a-context) are strings that you can use to trigger matching rules. ", - alias="ruleContexts", - ) - personalization_impact: Optional[ - Annotated[int, Field(le=100, strict=True, ge=0)] - ] = Field( - default=100, - description="Impact that Personalization should have on this search. The higher this value is, the more Personalization determines the ranking compared to other factors. For more information, see [Understanding Personalization impact](https://www.algolia.com/doc/guides/personalization/personalizing-results/in-depth/configuring-personalization/#understanding-personalization-impact). ", - alias="personalizationImpact", - ) - user_token: Optional[StrictStr] = Field( - default=None, - description="Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - get_ranking_info: Optional[StrictBool] = Field( - default=False, - description="Whether the search response should include detailed ranking information.", - alias="getRankingInfo", - ) - synonyms: Optional[StrictBool] = Field( - default=True, - description="Whether to take into account an index's synonyms for this search.", - ) - click_analytics: Optional[StrictBool] = Field( - default=False, - description="Whether to include a `queryID` attribute in the response. The query ID is a unique identifier for a search query and is required for tracking [click and conversion events](https://www.algolia.com/guides/sending-events/getting-started/). ", - alias="clickAnalytics", - ) - analytics: Optional[StrictBool] = Field( - default=True, description="Whether this search will be included in Analytics." - ) - analytics_tags: Optional[List[StrictStr]] = Field( - default=None, - description="Tags to apply to the query for [segmenting analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/).", - alias="analyticsTags", - ) - percentile_computation: Optional[StrictBool] = Field( - default=True, - description="Whether to include this search when calculating processing-time percentiles.", - alias="percentileComputation", - ) - enable_ab_test: Optional[StrictBool] = Field( - default=True, - description="Whether to enable A/B testing for this search.", - alias="enableABTest", - ) - attributes_to_retrieve: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `["*", "-ATTRIBUTE"]`. - The `objectID` attribute is always included. ', - alias="attributesToRetrieve", - ) - ranking: Optional[List[StrictStr]] = Field( - default=None, - description='Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they\'re specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc("ATTRIBUTE")`. Sort the index by the values of an attribute, in ascending order. - `desc("ATTRIBUTE")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). ', - ) - custom_ranking: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes to use as [custom ranking](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/). Attribute names are case-sensitive. The custom ranking attributes decide which items are shown first if the other ranking criteria are equal. Records with missing values for your selected custom ranking attributes are always sorted last. Boolean attributes are sorted based on their alphabetical order. **Modifiers** - `asc("ATTRIBUTE")`. Sort the index by the values of an attribute, in ascending order. - `desc("ATTRIBUTE")`. Sort the index by the values of an attribute, in descending order. If you use two or more custom ranking attributes, [reduce the precision](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/how-to/controlling-custom-ranking-metrics-precision/) of your first attributes, or the other attributes will never be applied. ', - alias="customRanking", - ) - relevancy_strictness: Optional[StrictInt] = Field( - default=100, - description="Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. ", - alias="relevancyStrictness", - ) - attributes_to_highlight: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). ", - alias="attributesToHighlight", - ) - attributes_to_snippet: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. ", - alias="attributesToSnippet", - ) - highlight_pre_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert before the highlighted parts in all highlighted results and snippets.", - alias="highlightPreTag", - ) - highlight_post_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert after the highlighted parts in all highlighted results and snippets.", - alias="highlightPostTag", - ) - snippet_ellipsis_text: Optional[StrictStr] = Field( - default="…", - description="String used as an ellipsis indicator when a snippet is truncated.", - alias="snippetEllipsisText", - ) - restrict_highlight_and_snippet_arrays: Optional[StrictBool] = Field( - default=False, - description="Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. ", - alias="restrictHighlightAndSnippetArrays", - ) - hits_per_page: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = Field( - default=20, description="Number of hits per page.", alias="hitsPerPage" - ) - min_word_sizefor1_typo: Optional[StrictInt] = Field( - default=4, - description="Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor1Typo", - ) - min_word_sizefor2_typos: Optional[StrictInt] = Field( - default=8, - description="Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor2Typos", + """ Minimum radius (in meters) for a search around a location when `aroundRadius` isn't set. """ + inside_bounding_box: Optional[List[List[float]]] = Field( + default=None, alias="insideBoundingBox" ) + """ Coordinates for a rectangular area in which to search. Each bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair: `[p1 lat, p1 long, p2 lat, p2 long]`. Provide multiple bounding boxes as nested arrays. For more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). """ + inside_polygon: Optional[List[List[float]]] = Field( + default=None, alias="insidePolygon" + ) + """ Coordinates of a polygon in which to search. Polygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude. Provide multiple polygons as nested arrays. For more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). This parameter is ignored if you also specify `insideBoundingBox`. """ + natural_languages: Optional[List[SupportedLanguage]] = Field( + default=None, alias="naturalLanguages" + ) + """ ISO language codes that adjust settings that are useful for processing natural language queries (as opposed to keyword searches): - Sets `removeStopWords` and `ignorePlurals` to the list of provided languages. - Sets `removeWordsIfNoResults` to `allOptional`. - Adds a `natural_language` attribute to `ruleContexts` and `analyticsTags`. """ + rule_contexts: Optional[List[str]] = Field(default=None, alias="ruleContexts") + """ Assigns a rule context to the search query. [Rule contexts](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/how-to/customize-search-results-by-platform/#whats-a-context) are strings that you can use to trigger matching rules. """ + personalization_impact: Optional[int] = Field( + default=None, alias="personalizationImpact" + ) + """ Impact that Personalization should have on this search. The higher this value is, the more Personalization determines the ranking compared to other factors. For more information, see [Understanding Personalization impact](https://www.algolia.com/doc/guides/personalization/personalizing-results/in-depth/configuring-personalization/#understanding-personalization-impact). """ + user_token: Optional[str] = Field(default=None, alias="userToken") + """ Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + get_ranking_info: Optional[bool] = Field(default=None, alias="getRankingInfo") + """ Whether the search response should include detailed ranking information. """ + synonyms: Optional[bool] = Field(default=None, alias="synonyms") + """ Whether to take into account an index's synonyms for this search. """ + click_analytics: Optional[bool] = Field(default=None, alias="clickAnalytics") + """ Whether to include a `queryID` attribute in the response. The query ID is a unique identifier for a search query and is required for tracking [click and conversion events](https://www.algolia.com/guides/sending-events/getting-started/). """ + analytics: Optional[bool] = Field(default=None, alias="analytics") + """ Whether this search will be included in Analytics. """ + analytics_tags: Optional[List[str]] = Field(default=None, alias="analyticsTags") + """ Tags to apply to the query for [segmenting analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). """ + percentile_computation: Optional[bool] = Field( + default=None, alias="percentileComputation" + ) + """ Whether to include this search when calculating processing-time percentiles. """ + enable_ab_test: Optional[bool] = Field(default=None, alias="enableABTest") + """ Whether to enable A/B testing for this search. """ + attributes_to_retrieve: Optional[List[str]] = Field( + default=None, alias="attributesToRetrieve" + ) + """ Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `[\"*\", \"-ATTRIBUTE\"]`. - The `objectID` attribute is always included. """ + ranking: Optional[List[str]] = Field(default=None, alias="ranking") + """ Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they're specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in ascending order. - `desc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). """ + custom_ranking: Optional[List[str]] = Field(default=None, alias="customRanking") + """ Attributes to use as [custom ranking](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/). Attribute names are case-sensitive. The custom ranking attributes decide which items are shown first if the other ranking criteria are equal. Records with missing values for your selected custom ranking attributes are always sorted last. Boolean attributes are sorted based on their alphabetical order. **Modifiers** - `asc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in ascending order. - `desc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in descending order. If you use two or more custom ranking attributes, [reduce the precision](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/how-to/controlling-custom-ranking-metrics-precision/) of your first attributes, or the other attributes will never be applied. """ + relevancy_strictness: Optional[int] = Field( + default=None, alias="relevancyStrictness" + ) + """ Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. """ + attributes_to_highlight: Optional[List[str]] = Field( + default=None, alias="attributesToHighlight" + ) + """ Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). """ + attributes_to_snippet: Optional[List[str]] = Field( + default=None, alias="attributesToSnippet" + ) + """ Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. """ + highlight_pre_tag: Optional[str] = Field(default=None, alias="highlightPreTag") + """ HTML tag to insert before the highlighted parts in all highlighted results and snippets. """ + highlight_post_tag: Optional[str] = Field(default=None, alias="highlightPostTag") + """ HTML tag to insert after the highlighted parts in all highlighted results and snippets. """ + snippet_ellipsis_text: Optional[str] = Field( + default=None, alias="snippetEllipsisText" + ) + """ String used as an ellipsis indicator when a snippet is truncated. """ + restrict_highlight_and_snippet_arrays: Optional[bool] = Field( + default=None, alias="restrictHighlightAndSnippetArrays" + ) + """ Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. """ + hits_per_page: Optional[int] = Field(default=None, alias="hitsPerPage") + """ Number of hits per page. """ + min_word_sizefor1_typo: Optional[int] = Field( + default=None, alias="minWordSizefor1Typo" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ + min_word_sizefor2_typos: Optional[int] = Field( + default=None, alias="minWordSizefor2Typos" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ typo_tolerance: Optional[TypoTolerance] = Field(default=None, alias="typoTolerance") - allow_typos_on_numeric_tokens: Optional[StrictBool] = Field( - default=True, - description="Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. ", - alias="allowTyposOnNumericTokens", + allow_typos_on_numeric_tokens: Optional[bool] = Field( + default=None, alias="allowTyposOnNumericTokens" ) - disable_typo_tolerance_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. ", - alias="disableTypoToleranceOnAttributes", + """ Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. """ + disable_typo_tolerance_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableTypoToleranceOnAttributes" ) + """ Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. """ ignore_plurals: Optional[IgnorePlurals] = Field(default=None, alias="ignorePlurals") remove_stop_words: Optional[RemoveStopWords] = Field( default=None, alias="removeStopWords" ) - keep_diacritics_on_characters: Optional[StrictStr] = Field( - default="", - description="Characters for which diacritics should be preserved. By default, Algolia removes diacritics from letters. For example, `é` becomes `e`. If this causes issues in your search, you can specify characters that should keep their diacritics. ", - alias="keepDiacriticsOnCharacters", + keep_diacritics_on_characters: Optional[str] = Field( + default=None, alias="keepDiacriticsOnCharacters" ) + """ Characters for which diacritics should be preserved. By default, Algolia removes diacritics from letters. For example, `é` becomes `e`. If this causes issues in your search, you can specify characters that should keep their diacritics. """ query_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). ", - alias="queryLanguages", + default=None, alias="queryLanguages" ) - decompound_query: Optional[StrictBool] = Field( - default=True, - description="Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). ", - alias="decompoundQuery", - ) - enable_rules: Optional[StrictBool] = Field( - default=True, description="Whether to enable rules.", alias="enableRules" - ) - enable_personalization: Optional[StrictBool] = Field( - default=False, - description="Whether to enable Personalization.", - alias="enablePersonalization", + """ Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). """ + decompound_query: Optional[bool] = Field(default=None, alias="decompoundQuery") + """ Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). """ + enable_rules: Optional[bool] = Field(default=None, alias="enableRules") + """ Whether to enable rules. """ + enable_personalization: Optional[bool] = Field( + default=None, alias="enablePersonalization" ) + """ Whether to enable Personalization. """ query_type: Optional[QueryType] = Field(default=None, alias="queryType") remove_words_if_no_results: Optional[RemoveWordsIfNoResults] = Field( default=None, alias="removeWordsIfNoResults" ) - mode: Optional[Mode] = None + mode: Optional[Mode] = Field(default=None, alias="mode") semantic_search: Optional[SemanticSearch] = Field( default=None, alias="semanticSearch" ) - advanced_syntax: Optional[StrictBool] = Field( - default=False, - description="Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. ", - alias="advancedSyntax", - ) - optional_words: Optional[List[StrictStr]] = Field( - default=None, - description='Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn\'t include the optional words. For example, if the search query is "action video" and "video" is an optional word, the search engine runs two queries. One for "action video" and one for "action". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). ', - alias="optionalWords", - ) - disable_exact_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. ", - alias="disableExactOnAttributes", + advanced_syntax: Optional[bool] = Field(default=None, alias="advancedSyntax") + """ Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. """ + optional_words: Optional[List[str]] = Field(default=None, alias="optionalWords") + """ Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn't include the optional words. For example, if the search query is \"action video\" and \"video\" is an optional word, the search engine runs two queries. One for \"action video\" and one for \"action\". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). """ + disable_exact_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableExactOnAttributes" ) + """ Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. """ exact_on_single_word_query: Optional[ExactOnSingleWordQuery] = Field( default=None, alias="exactOnSingleWordQuery" ) alternatives_as_exact: Optional[List[AlternativesAsExact]] = Field( - default=None, - description='Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as "NY/NYC" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as "NY/New York" are considered exact matches. ', - alias="alternativesAsExact", + default=None, alias="alternativesAsExact" ) + """ Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as \"NY/NYC\" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as \"NY/New York\" are considered exact matches. """ advanced_syntax_features: Optional[List[AdvancedSyntaxFeatures]] = Field( - default=None, - description='Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue "iPhone case"` only returns records with the exact string "iPhone case". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain "search" but not "engine". This setting only has an effect if `advancedSyntax` is true. ', - alias="advancedSyntaxFeatures", - ) - distinct: Optional[Distinct] = None - replace_synonyms_in_highlight: Optional[StrictBool] = Field( - default=False, - description='Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either "home" or "house" are included in the search results, and either "home" or "house" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of "house" are replaced by "home" in the highlighted response. ', - alias="replaceSynonymsInHighlight", - ) - min_proximity: Optional[Annotated[int, Field(le=7, strict=True, ge=1)]] = Field( - default=1, - description="Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. ", - alias="minProximity", - ) - response_fields: Optional[List[StrictStr]] = Field( - default=None, - description="Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. ", - alias="responseFields", - ) - max_facet_hits: Optional[Annotated[int, Field(le=100, strict=True)]] = Field( - default=10, - description="Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values).", - alias="maxFacetHits", - ) - max_values_per_facet: Optional[Annotated[int, Field(le=1000, strict=True)]] = Field( - default=100, - description="Maximum number of facet values to return for each facet.", - alias="maxValuesPerFacet", - ) - sort_facet_values_by: Optional[StrictStr] = Field( - default="count", - description="Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). ", - alias="sortFacetValuesBy", - ) - attribute_criteria_computed_by_min_proximity: Optional[StrictBool] = Field( - default=False, - description="Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. ", - alias="attributeCriteriaComputedByMinProximity", - ) + default=None, alias="advancedSyntaxFeatures" + ) + """ Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue \"iPhone case\"` only returns records with the exact string \"iPhone case\". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain \"search\" but not \"engine\". This setting only has an effect if `advancedSyntax` is true. """ + distinct: Optional[Distinct] = Field(default=None, alias="distinct") + replace_synonyms_in_highlight: Optional[bool] = Field( + default=None, alias="replaceSynonymsInHighlight" + ) + """ Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either \"home\" or \"house\" are included in the search results, and either \"home\" or \"house\" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of \"house\" are replaced by \"home\" in the highlighted response. """ + min_proximity: Optional[int] = Field(default=None, alias="minProximity") + """ Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. """ + response_fields: Optional[List[str]] = Field(default=None, alias="responseFields") + """ Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. """ + max_facet_hits: Optional[int] = Field(default=None, alias="maxFacetHits") + """ Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values). """ + max_values_per_facet: Optional[int] = Field(default=None, alias="maxValuesPerFacet") + """ Maximum number of facet values to return for each facet. """ + sort_facet_values_by: Optional[str] = Field(default=None, alias="sortFacetValuesBy") + """ Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). """ + attribute_criteria_computed_by_min_proximity: Optional[bool] = Field( + default=None, alias="attributeCriteriaComputedByMinProximity" + ) + """ Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. """ rendering_content: Optional[RenderingContent] = Field( default=None, alias="renderingContent" ) - enable_re_ranking: Optional[StrictBool] = Field( - default=True, - description="Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. ", - alias="enableReRanking", - ) + enable_re_ranking: Optional[bool] = Field(default=None, alias="enableReRanking") + """ Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. """ re_ranking_apply_filter: Optional[ReRankingApplyFilter] = Field( default=None, alias="reRankingApplyFilter" ) - cursor: Optional[StrictStr] = Field( - default=None, - description="Cursor to get the next page of the response. The parameter must match the value returned in the response of a previous request. The last page of the response does not return a `cursor` attribute. ", - ) + cursor: Optional[str] = Field(default=None, alias="cursor") + """ Cursor to get the next page of the response. The parameter must match the value returned in the response of a previous request. The last page of the response does not return a `cursor` attribute. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of BrowseParamsObject from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.facet_filters: - _dict["facetFilters"] = self.facet_filters.to_dict() - if self.optional_filters: - _dict["optionalFilters"] = self.optional_filters.to_dict() - if self.numeric_filters: - _dict["numericFilters"] = self.numeric_filters.to_dict() - if self.tag_filters: - _dict["tagFilters"] = self.tag_filters.to_dict() - if self.around_radius: - _dict["aroundRadius"] = self.around_radius.to_dict() - if self.around_precision: - _dict["aroundPrecision"] = self.around_precision.to_dict() - if self.typo_tolerance: - _dict["typoTolerance"] = self.typo_tolerance.to_dict() - if self.ignore_plurals: - _dict["ignorePlurals"] = self.ignore_plurals.to_dict() - if self.remove_stop_words: - _dict["removeStopWords"] = self.remove_stop_words.to_dict() - if self.semantic_search: - _dict["semanticSearch"] = self.semantic_search.to_dict() - if self.distinct: - _dict["distinct"] = self.distinct.to_dict() - if self.rendering_content: - _dict["renderingContent"] = self.rendering_content.to_dict() - if self.re_ranking_apply_filter: - _dict["reRankingApplyFilter"] = self.re_ranking_apply_filter.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of BrowseParamsObject from a dict""" if obj is None: return None @@ -453,143 +293,78 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "query": obj.get("query"), - "similarQuery": obj.get("similarQuery"), - "filters": obj.get("filters"), - "facetFilters": ( - FacetFilters.from_dict(obj.get("facetFilters")) - if obj.get("facetFilters") is not None - else None - ), - "optionalFilters": ( - OptionalFilters.from_dict(obj.get("optionalFilters")) - if obj.get("optionalFilters") is not None - else None - ), - "numericFilters": ( - NumericFilters.from_dict(obj.get("numericFilters")) - if obj.get("numericFilters") is not None - else None - ), - "tagFilters": ( - TagFilters.from_dict(obj.get("tagFilters")) - if obj.get("tagFilters") is not None - else None - ), - "sumOrFiltersScores": obj.get("sumOrFiltersScores"), - "restrictSearchableAttributes": obj.get("restrictSearchableAttributes"), - "facets": obj.get("facets"), - "facetingAfterDistinct": obj.get("facetingAfterDistinct"), - "page": obj.get("page"), - "offset": obj.get("offset"), - "length": obj.get("length"), - "aroundLatLng": obj.get("aroundLatLng"), - "aroundLatLngViaIP": obj.get("aroundLatLngViaIP"), - "aroundRadius": ( - AroundRadius.from_dict(obj.get("aroundRadius")) - if obj.get("aroundRadius") is not None - else None - ), - "aroundPrecision": ( - AroundPrecision.from_dict(obj.get("aroundPrecision")) - if obj.get("aroundPrecision") is not None - else None - ), - "minimumAroundRadius": obj.get("minimumAroundRadius"), - "insideBoundingBox": obj.get("insideBoundingBox"), - "insidePolygon": obj.get("insidePolygon"), - "naturalLanguages": obj.get("naturalLanguages"), - "ruleContexts": obj.get("ruleContexts"), - "personalizationImpact": obj.get("personalizationImpact"), - "userToken": obj.get("userToken"), - "getRankingInfo": obj.get("getRankingInfo"), - "synonyms": obj.get("synonyms"), - "clickAnalytics": obj.get("clickAnalytics"), - "analytics": obj.get("analytics"), - "analyticsTags": obj.get("analyticsTags"), - "percentileComputation": obj.get("percentileComputation"), - "enableABTest": obj.get("enableABTest"), - "attributesToRetrieve": obj.get("attributesToRetrieve"), - "ranking": obj.get("ranking"), - "customRanking": obj.get("customRanking"), - "relevancyStrictness": obj.get("relevancyStrictness"), - "attributesToHighlight": obj.get("attributesToHighlight"), - "attributesToSnippet": obj.get("attributesToSnippet"), - "highlightPreTag": obj.get("highlightPreTag"), - "highlightPostTag": obj.get("highlightPostTag"), - "snippetEllipsisText": obj.get("snippetEllipsisText"), - "restrictHighlightAndSnippetArrays": obj.get( - "restrictHighlightAndSnippetArrays" - ), - "hitsPerPage": obj.get("hitsPerPage"), - "minWordSizefor1Typo": obj.get("minWordSizefor1Typo"), - "minWordSizefor2Typos": obj.get("minWordSizefor2Typos"), - "typoTolerance": ( - TypoTolerance.from_dict(obj.get("typoTolerance")) - if obj.get("typoTolerance") is not None - else None - ), - "allowTyposOnNumericTokens": obj.get("allowTyposOnNumericTokens"), - "disableTypoToleranceOnAttributes": obj.get( - "disableTypoToleranceOnAttributes" - ), - "ignorePlurals": ( - IgnorePlurals.from_dict(obj.get("ignorePlurals")) - if obj.get("ignorePlurals") is not None - else None - ), - "removeStopWords": ( - RemoveStopWords.from_dict(obj.get("removeStopWords")) - if obj.get("removeStopWords") is not None - else None - ), - "keepDiacriticsOnCharacters": obj.get("keepDiacriticsOnCharacters"), - "queryLanguages": obj.get("queryLanguages"), - "decompoundQuery": obj.get("decompoundQuery"), - "enableRules": obj.get("enableRules"), - "enablePersonalization": obj.get("enablePersonalization"), - "queryType": obj.get("queryType"), - "removeWordsIfNoResults": obj.get("removeWordsIfNoResults"), - "mode": obj.get("mode"), - "semanticSearch": ( - SemanticSearch.from_dict(obj.get("semanticSearch")) - if obj.get("semanticSearch") is not None - else None - ), - "advancedSyntax": obj.get("advancedSyntax"), - "optionalWords": obj.get("optionalWords"), - "disableExactOnAttributes": obj.get("disableExactOnAttributes"), - "exactOnSingleWordQuery": obj.get("exactOnSingleWordQuery"), - "alternativesAsExact": obj.get("alternativesAsExact"), - "advancedSyntaxFeatures": obj.get("advancedSyntaxFeatures"), - "distinct": ( - Distinct.from_dict(obj.get("distinct")) - if obj.get("distinct") is not None - else None - ), - "replaceSynonymsInHighlight": obj.get("replaceSynonymsInHighlight"), - "minProximity": obj.get("minProximity"), - "responseFields": obj.get("responseFields"), - "maxFacetHits": obj.get("maxFacetHits"), - "maxValuesPerFacet": obj.get("maxValuesPerFacet"), - "sortFacetValuesBy": obj.get("sortFacetValuesBy"), - "attributeCriteriaComputedByMinProximity": obj.get( - "attributeCriteriaComputedByMinProximity" - ), - "renderingContent": ( - RenderingContent.from_dict(obj.get("renderingContent")) - if obj.get("renderingContent") is not None - else None - ), - "enableReRanking": obj.get("enableReRanking"), - "reRankingApplyFilter": ( - ReRankingApplyFilter.from_dict(obj.get("reRankingApplyFilter")) - if obj.get("reRankingApplyFilter") is not None - else None - ), - "cursor": obj.get("cursor"), - } + obj["facetFilters"] = ( + FacetFilters.from_dict(obj["facetFilters"]) + if obj.get("facetFilters") is not None + else None + ) + obj["optionalFilters"] = ( + OptionalFilters.from_dict(obj["optionalFilters"]) + if obj.get("optionalFilters") is not None + else None + ) + obj["numericFilters"] = ( + NumericFilters.from_dict(obj["numericFilters"]) + if obj.get("numericFilters") is not None + else None + ) + obj["tagFilters"] = ( + TagFilters.from_dict(obj["tagFilters"]) + if obj.get("tagFilters") is not None + else None + ) + obj["aroundRadius"] = ( + AroundRadius.from_dict(obj["aroundRadius"]) + if obj.get("aroundRadius") is not None + else None ) - return _obj + obj["aroundPrecision"] = ( + AroundPrecision.from_dict(obj["aroundPrecision"]) + if obj.get("aroundPrecision") is not None + else None + ) + obj["naturalLanguages"] = obj.get("naturalLanguages") + obj["typoTolerance"] = ( + TypoTolerance.from_dict(obj["typoTolerance"]) + if obj.get("typoTolerance") is not None + else None + ) + obj["ignorePlurals"] = ( + IgnorePlurals.from_dict(obj["ignorePlurals"]) + if obj.get("ignorePlurals") is not None + else None + ) + obj["removeStopWords"] = ( + RemoveStopWords.from_dict(obj["removeStopWords"]) + if obj.get("removeStopWords") is not None + else None + ) + obj["queryLanguages"] = obj.get("queryLanguages") + obj["queryType"] = obj.get("queryType") + obj["removeWordsIfNoResults"] = obj.get("removeWordsIfNoResults") + obj["mode"] = obj.get("mode") + obj["semanticSearch"] = ( + SemanticSearch.from_dict(obj["semanticSearch"]) + if obj.get("semanticSearch") is not None + else None + ) + obj["exactOnSingleWordQuery"] = obj.get("exactOnSingleWordQuery") + obj["alternativesAsExact"] = obj.get("alternativesAsExact") + obj["advancedSyntaxFeatures"] = obj.get("advancedSyntaxFeatures") + obj["distinct"] = ( + Distinct.from_dict(obj["distinct"]) + if obj.get("distinct") is not None + else None + ) + obj["renderingContent"] = ( + RenderingContent.from_dict(obj["renderingContent"]) + if obj.get("renderingContent") is not None + else None + ) + obj["reRankingApplyFilter"] = ( + ReRankingApplyFilter.from_dict(obj["reRankingApplyFilter"]) + if obj.get("reRankingApplyFilter") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/browse_response.py b/algoliasearch/search/models/browse_response.py index 3d7f40ad3..5cc1e9bc4 100644 --- a/algoliasearch/search/models/browse_response.py +++ b/algoliasearch/search/models/browse_response.py @@ -11,20 +11,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import ( - BaseModel, - ConfigDict, - Field, - StrictBool, - StrictInt, - StrictStr, - field_validator, -) +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.exhaustive import Exhaustive @@ -39,135 +31,77 @@ class BrowseResponse(BaseModel): BrowseResponse """ - ab_test_id: Optional[StrictInt] = Field( - default=None, - description="A/B test ID. This is only included in the response for indices that are part of an A/B test.", - alias="abTestID", - ) - ab_test_variant_id: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field( - default=None, - description="Variant ID. This is only included in the response for indices that are part of an A/B test.", - alias="abTestVariantID", - ) - around_lat_lng: Optional[Annotated[str, Field(strict=True)]] = Field( - default=None, - description="Computed geographical location.", - alias="aroundLatLng", - ) - automatic_radius: Optional[StrictStr] = Field( - default=None, - description="Distance from a central coordinate provided by `aroundLatLng`.", - alias="automaticRadius", - ) - exhaustive: Optional[Exhaustive] = None - exhaustive_facets_count: Optional[StrictBool] = Field( - default=None, - description="See the `facetsCount` field of the `exhaustive` object in the response.", - alias="exhaustiveFacetsCount", - ) - exhaustive_nb_hits: Optional[StrictBool] = Field( - default=None, - description="See the `nbHits` field of the `exhaustive` object in the response.", - alias="exhaustiveNbHits", - ) - exhaustive_typo: Optional[StrictBool] = Field( - default=None, - description="See the `typo` field of the `exhaustive` object in the response.", - alias="exhaustiveTypo", - ) - facets: Optional[Dict[str, Dict[str, StrictInt]]] = Field( - default=None, description="Facet counts." - ) + ab_test_id: Optional[int] = Field(default=None, alias="abTestID") + """ A/B test ID. This is only included in the response for indices that are part of an A/B test. """ + ab_test_variant_id: Optional[int] = Field(default=None, alias="abTestVariantID") + """ Variant ID. This is only included in the response for indices that are part of an A/B test. """ + around_lat_lng: Optional[str] = Field(default=None, alias="aroundLatLng") + """ Computed geographical location. """ + automatic_radius: Optional[str] = Field(default=None, alias="automaticRadius") + """ Distance from a central coordinate provided by `aroundLatLng`. """ + exhaustive: Optional[Exhaustive] = Field(default=None, alias="exhaustive") + exhaustive_facets_count: Optional[bool] = Field( + default=None, alias="exhaustiveFacetsCount" + ) + """ See the `facetsCount` field of the `exhaustive` object in the response. """ + exhaustive_nb_hits: Optional[bool] = Field(default=None, alias="exhaustiveNbHits") + """ See the `nbHits` field of the `exhaustive` object in the response. """ + exhaustive_typo: Optional[bool] = Field(default=None, alias="exhaustiveTypo") + """ See the `typo` field of the `exhaustive` object in the response. """ + facets: Optional[Dict[str, Dict[str, int]]] = Field(default=None, alias="facets") + """ Facet counts. """ facets_stats: Optional[Dict[str, FacetStats]] = Field( - default=None, description="Statistics for numerical facets." - ) - index: Optional[StrictStr] = Field( - default=None, description="Index name used for the query." - ) - index_used: Optional[StrictStr] = Field( - default=None, - description="Index name used for the query. During A/B testing, the targeted index isn't always the index used by the query.", - alias="indexUsed", - ) - message: Optional[StrictStr] = Field( - default=None, description="Warnings about the query." - ) - nb_sorted_hits: Optional[StrictInt] = Field( - default=None, - description="Number of hits selected and sorted by the relevant sort algorithm.", - alias="nbSortedHits", - ) - parsed_query: Optional[StrictStr] = Field( - default=None, - description="Post-[normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/#what-does-normalization-mean) query string that will be searched.", - alias="parsedQuery", - ) - processing_time_ms: StrictInt = Field( - description="Time the server took to process the request, in milliseconds.", - alias="processingTimeMS", - ) - processing_timings_ms: Optional[Dict[str, Any]] = Field( - default=None, - description="Experimental. List of processing steps and their times, in milliseconds. You can use this list to investigate performance issues.", - alias="processingTimingsMS", - ) - query_after_removal: Optional[StrictStr] = Field( - default=None, - description="Markup text indicating which parts of the original query have been removed to retrieve a non-empty result set.", - alias="queryAfterRemoval", - ) - redirect: Optional[Redirect] = None + default=None, alias="facets_stats" + ) + """ Statistics for numerical facets. """ + index: Optional[str] = Field(default=None, alias="index") + """ Index name used for the query. """ + index_used: Optional[str] = Field(default=None, alias="indexUsed") + """ Index name used for the query. During A/B testing, the targeted index isn't always the index used by the query. """ + message: Optional[str] = Field(default=None, alias="message") + """ Warnings about the query. """ + nb_sorted_hits: Optional[int] = Field(default=None, alias="nbSortedHits") + """ Number of hits selected and sorted by the relevant sort algorithm. """ + parsed_query: Optional[str] = Field(default=None, alias="parsedQuery") + """ Post-[normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/#what-does-normalization-mean) query string that will be searched. """ + processing_time_ms: int = Field(alias="processingTimeMS") + """ Time the server took to process the request, in milliseconds. """ + processing_timings_ms: Optional[object] = Field( + default=None, alias="processingTimingsMS" + ) + """ Experimental. List of processing steps and their times, in milliseconds. You can use this list to investigate performance issues. """ + query_after_removal: Optional[str] = Field(default=None, alias="queryAfterRemoval") + """ Markup text indicating which parts of the original query have been removed to retrieve a non-empty result set. """ + redirect: Optional[Redirect] = Field(default=None, alias="redirect") rendering_content: Optional[RenderingContent] = Field( default=None, alias="renderingContent" ) - server_time_ms: Optional[StrictInt] = Field( - default=None, - description="Time the server took to process the request, in milliseconds.", - alias="serverTimeMS", - ) - server_used: Optional[StrictStr] = Field( - default=None, - description="Host name of the server that processed the request.", - alias="serverUsed", - ) - user_data: Optional[Dict[str, Any]] = Field( - default=None, - description="An object with custom data. You can store up to 32kB as custom data. ", - alias="userData", - ) - query_id: Optional[StrictStr] = Field( - default=None, - description="Unique identifier for the query. This is used for [click analytics](https://www.algolia.com/doc/guides/analytics/click-analytics/).", - alias="queryID", - ) - automatic_insights: Optional[StrictBool] = Field( - default=None, - description="Whether automatic events collection is enabled for the application.", - alias="_automaticInsights", - ) - page: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=0, description="Page of search results to retrieve." - ) - nb_hits: Optional[StrictInt] = Field( - default=None, description="Number of results (hits).", alias="nbHits" - ) - nb_pages: Optional[StrictInt] = Field( - default=None, description="Number of pages of results.", alias="nbPages" - ) - hits_per_page: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = Field( - default=20, description="Number of hits per page.", alias="hitsPerPage" - ) - hits: List[Hit] = Field( - description="Search results (hits). Hits are records from your index that match the search criteria, augmented with additional attributes, such as, for highlighting. " - ) - query: StrictStr = Field(description="Search query.") - params: StrictStr = Field( - description="URL-encoded string of all search parameters." - ) - cursor: Optional[StrictStr] = Field( - default=None, - description="Cursor to get the next page of the response. The parameter must match the value returned in the response of a previous request. The last page of the response does not return a `cursor` attribute. ", - ) + server_time_ms: Optional[int] = Field(default=None, alias="serverTimeMS") + """ Time the server took to process the request, in milliseconds. """ + server_used: Optional[str] = Field(default=None, alias="serverUsed") + """ Host name of the server that processed the request. """ + user_data: Optional[object] = Field(default=None, alias="userData") + """ An object with custom data. You can store up to 32kB as custom data. """ + query_id: Optional[str] = Field(default=None, alias="queryID") + """ Unique identifier for the query. This is used for [click analytics](https://www.algolia.com/doc/guides/analytics/click-analytics/). """ + automatic_insights: Optional[bool] = Field(default=None, alias="_automaticInsights") + """ Whether automatic events collection is enabled for the application. """ + page: Optional[int] = Field(default=None, alias="page") + """ Page of search results to retrieve. """ + nb_hits: Optional[int] = Field(default=None, alias="nbHits") + """ Number of results (hits). """ + nb_pages: Optional[int] = Field(default=None, alias="nbPages") + """ Number of pages of results. """ + hits_per_page: Optional[int] = Field(default=None, alias="hitsPerPage") + """ Number of hits per page. """ + hits: List[Hit] = Field(alias="hits") + """ Search results (hits). Hits are records from your index that match the search criteria, augmented with additional attributes, such as, for highlighting. """ + query: str = Field(alias="query") + """ Search query. """ + params: str = Field(alias="params") + """ URL-encoded string of all search parameters. """ + cursor: Optional[str] = Field(default=None, alias="cursor") + """ Cursor to get the next page of the response. The parameter must match the value returned in the response of a previous request. The last page of the response does not return a `cursor` attribute. """ @field_validator("around_lat_lng") def around_lat_lng_validate_regular_expression(cls, value): @@ -182,55 +116,30 @@ def around_lat_lng_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of BrowseResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.exhaustive: - _dict["exhaustive"] = self.exhaustive.to_dict() - _field_dict = {} - if self.facets_stats: - for _key in self.facets_stats: - if self.facets_stats[_key]: - _field_dict[_key] = self.facets_stats[_key].to_dict() - _dict["facets_stats"] = _field_dict - if self.redirect: - _dict["redirect"] = self.redirect.to_dict() - if self.rendering_content: - _dict["renderingContent"] = self.rendering_content.to_dict() - _items = [] - if self.hits: - for _item in self.hits: - if _item: - _items.append(_item.to_dict()) - _dict["hits"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of BrowseResponse from a dict""" if obj is None: return None @@ -238,64 +147,32 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "abTestID": obj.get("abTestID"), - "abTestVariantID": obj.get("abTestVariantID"), - "aroundLatLng": obj.get("aroundLatLng"), - "automaticRadius": obj.get("automaticRadius"), - "exhaustive": ( - Exhaustive.from_dict(obj.get("exhaustive")) - if obj.get("exhaustive") is not None - else None - ), - "exhaustiveFacetsCount": obj.get("exhaustiveFacetsCount"), - "exhaustiveNbHits": obj.get("exhaustiveNbHits"), - "exhaustiveTypo": obj.get("exhaustiveTypo"), - "facets": obj.get("facets"), - "facets_stats": ( - dict( - (_k, FacetStats.from_dict(_v)) - for _k, _v in obj.get("facets_stats").items() - ) - if obj.get("facets_stats") is not None - else None - ), - "index": obj.get("index"), - "indexUsed": obj.get("indexUsed"), - "message": obj.get("message"), - "nbSortedHits": obj.get("nbSortedHits"), - "parsedQuery": obj.get("parsedQuery"), - "processingTimeMS": obj.get("processingTimeMS"), - "processingTimingsMS": obj.get("processingTimingsMS"), - "queryAfterRemoval": obj.get("queryAfterRemoval"), - "redirect": ( - Redirect.from_dict(obj.get("redirect")) - if obj.get("redirect") is not None - else None - ), - "renderingContent": ( - RenderingContent.from_dict(obj.get("renderingContent")) - if obj.get("renderingContent") is not None - else None - ), - "serverTimeMS": obj.get("serverTimeMS"), - "serverUsed": obj.get("serverUsed"), - "userData": obj.get("userData"), - "queryID": obj.get("queryID"), - "_automaticInsights": obj.get("_automaticInsights"), - "page": obj.get("page"), - "nbHits": obj.get("nbHits"), - "nbPages": obj.get("nbPages"), - "hitsPerPage": obj.get("hitsPerPage"), - "hits": ( - [Hit.from_dict(_item) for _item in obj.get("hits")] - if obj.get("hits") is not None - else None - ), - "query": obj.get("query"), - "params": obj.get("params"), - "cursor": obj.get("cursor"), - } + obj["exhaustive"] = ( + Exhaustive.from_dict(obj["exhaustive"]) + if obj.get("exhaustive") is not None + else None + ) + obj["facets_stats"] = ( + dict( + (_k, FacetStats.from_dict(_v)) for _k, _v in obj["facets_stats"].items() + ) + if obj.get("facets_stats") is not None + else None ) - return _obj + obj["redirect"] = ( + Redirect.from_dict(obj["redirect"]) + if obj.get("redirect") is not None + else None + ) + obj["renderingContent"] = ( + RenderingContent.from_dict(obj["renderingContent"]) + if obj.get("renderingContent") is not None + else None + ) + obj["hits"] = ( + [Hit.from_dict(_item) for _item in obj["hits"]] + if obj.get("hits") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/built_in_operation.py b/algoliasearch/search/models/built_in_operation.py index 60fbf6d43..ec44b22cb 100644 --- a/algoliasearch/search/models/built_in_operation.py +++ b/algoliasearch/search/models/built_in_operation.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional from pydantic import BaseModel, ConfigDict, Field @@ -28,42 +28,33 @@ class BuiltInOperation(BaseModel): """ operation: BuiltInOperationType = Field(alias="_operation") - value: BuiltInOperationValue + value: BuiltInOperationValue = Field(alias="value") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of BuiltInOperation from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.value: - _dict["value"] = self.value.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of BuiltInOperation from a dict""" if obj is None: return None @@ -71,14 +62,11 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "_operation": obj.get("_operation"), - "value": ( - BuiltInOperationValue.from_dict(obj.get("value")) - if obj.get("value") is not None - else None - ), - } + obj["_operation"] = obj.get("_operation") + obj["value"] = ( + BuiltInOperationValue.from_dict(obj["value"]) + if obj.get("value") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/built_in_operation_type.py b/algoliasearch/search/models/built_in_operation_type.py index 6102ceb49..8f57774c0 100644 --- a/algoliasearch/search/models/built_in_operation_type.py +++ b/algoliasearch/search/models/built_in_operation_type.py @@ -25,11 +25,17 @@ class BuiltInOperationType(str, Enum): allowed enum values """ INCREMENT = "Increment" + DECREMENT = "Decrement" + ADD = "Add" + REMOVE = "Remove" + ADDUNIQUE = "AddUnique" + INCREMENTFROM = "IncrementFrom" + INCREMENTSET = "IncrementSet" @classmethod diff --git a/algoliasearch/search/models/built_in_operation_value.py b/algoliasearch/search/models/built_in_operation_value.py index 31fd89e61..78a1fa671 100644 --- a/algoliasearch/search/models/built_in_operation_value.py +++ b/algoliasearch/search/models/built_in_operation_value.py @@ -8,16 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import ( - BaseModel, - Field, - StrictInt, - StrictStr, - ValidationError, - model_serializer, -) +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -30,15 +23,12 @@ class BuiltInOperationValue(BaseModel): BuiltInOperationValue """ - oneof_schema_1_validator: Optional[StrictStr] = Field( - default=None, - description="A string to append or remove for the `Add`, `Remove`, and `AddUnique` operations.", - ) - oneof_schema_2_validator: Optional[StrictInt] = Field( - default=None, - description="A number to add, remove, or append, depending on the operation.", - ) + oneof_schema_1_validator: Optional[str] = Field(default=None) + """ A string to append or remove for the `Add`, `Remove`, and `AddUnique` operations. """ + oneof_schema_2_validator: Optional[int] = Field(default=None) + """ A number to add, remove, or append, depending on the operation. """ actual_instance: Optional[Union[int, str]] = None + one_of_schemas: Set[str] = {"int", "str"} def __init__(self, *args, **kwargs) -> None: if args: @@ -62,7 +52,8 @@ def unwrap_actual_instance(self) -> Optional[Union[int, str]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of BuiltInOperationValue from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -96,17 +87,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], int, str]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/condition.py b/algoliasearch/search/models/condition.py index aae410955..d816975bd 100644 --- a/algoliasearch/search/models/condition.py +++ b/algoliasearch/search/models/condition.py @@ -11,19 +11,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import ( - BaseModel, - ConfigDict, - Field, - StrictBool, - StrictStr, - field_validator, -) +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.anchoring import Anchoring @@ -34,23 +27,15 @@ class Condition(BaseModel): Condition """ - pattern: Optional[StrictStr] = Field( - default=None, - description='Query pattern that triggers the rule. You can use either a literal string, or a special pattern `{facet:ATTRIBUTE}`, where `ATTRIBUTE` is a facet name. The rule is triggered if the query matches the literal string or a value of the specified facet. For example, with `pattern: {facet:genre}`, the rule is triggered when users search for a genre, such as "comedy". ', - ) - anchoring: Optional[Anchoring] = None - alternatives: Optional[StrictBool] = Field( - default=False, - description="Whether the pattern should match plurals, synonyms, and typos.", - ) - context: Optional[Annotated[str, Field(strict=True)]] = Field( - default=None, - description="An additional restriction that only triggers the rule, when the search has the same value as `ruleContexts` parameter. For example, if `context: mobile`, the rule is only triggered when the search request has a matching `ruleContexts: mobile`. A rule context must only contain alphanumeric characters. ", - ) - filters: Optional[StrictStr] = Field( - default=None, - description="Filters that trigger the rule. You can add add filters using the syntax `facet:value` so that the rule is triggered, when the specific filter is selected. You can use `filters` on its own or combine it with the `pattern` parameter. ", - ) + pattern: Optional[str] = Field(default=None, alias="pattern") + """ Query pattern that triggers the rule. You can use either a literal string, or a special pattern `{facet:ATTRIBUTE}`, where `ATTRIBUTE` is a facet name. The rule is triggered if the query matches the literal string or a value of the specified facet. For example, with `pattern: {facet:genre}`, the rule is triggered when users search for a genre, such as \"comedy\". """ + anchoring: Optional[Anchoring] = Field(default=None, alias="anchoring") + alternatives: Optional[bool] = Field(default=None, alias="alternatives") + """ Whether the pattern should match plurals, synonyms, and typos. """ + context: Optional[str] = Field(default=None, alias="context") + """ An additional restriction that only triggers the rule, when the search has the same value as `ruleContexts` parameter. For example, if `context: mobile`, the rule is only triggered when the search request has a matching `ruleContexts: mobile`. A rule context must only contain alphanumeric characters. """ + filters: Optional[str] = Field(default=None, alias="filters") + """ Filters that trigger the rule. You can add add filters using the syntax `facet:value` so that the rule is triggered, when the specific filter is selected. You can use `filters` on its own or combine it with the `pattern` parameter. """ @field_validator("context") def context_validate_regular_expression(cls, value): @@ -63,37 +48,30 @@ def context_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Condition from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Condition from a dict""" if obj is None: return None @@ -101,13 +79,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "pattern": obj.get("pattern"), - "anchoring": obj.get("anchoring"), - "alternatives": obj.get("alternatives"), - "context": obj.get("context"), - "filters": obj.get("filters"), - } - ) - return _obj + obj["anchoring"] = obj.get("anchoring") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/consequence.py b/algoliasearch/search/models/consequence.py index 660b7c6e3..5001b1ef0 100644 --- a/algoliasearch/search/models/consequence.py +++ b/algoliasearch/search/models/consequence.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.consequence_hide import ConsequenceHide @@ -28,71 +28,41 @@ class Consequence(BaseModel): Effect of the rule. For more information, see [Consequences](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/#consequences). """ - params: Optional[ConsequenceParams] = None - promote: Optional[Annotated[List[Promote], Field(max_length=300)]] = Field( - default=None, - description="Records you want to pin to a specific position in the search results. You can promote up to 300 records, either individually, or as groups of up to 100 records each. ", - ) - filter_promotes: Optional[StrictBool] = Field( - default=False, - description='Whether promoted records must match an active filter for the consequence to be applied. This ensures that user actions (filtering the search) are given a higher precendence. For example, if you promote a record with the `color: red` attribute, and the user filters the search for `color: blue`, the "red" record won\'t be shown. ', - alias="filterPromotes", - ) - hide: Optional[Annotated[List[ConsequenceHide], Field(max_length=50)]] = Field( - default=None, description="Records you want to hide from the search results." - ) - user_data: Optional[Any] = Field( - default=None, - description="A JSON object with custom data that will be appended to the `userData` array in the response. This object isn't interpreted by the API and is limited to 1 kB of minified JSON. ", - alias="userData", - ) + params: Optional[ConsequenceParams] = Field(default=None, alias="params") + promote: Optional[List[Promote]] = Field(default=None, alias="promote") + """ Records you want to pin to a specific position in the search results. You can promote up to 300 records, either individually, or as groups of up to 100 records each. """ + filter_promotes: Optional[bool] = Field(default=None, alias="filterPromotes") + """ Whether promoted records must match an active filter for the consequence to be applied. This ensures that user actions (filtering the search) are given a higher precendence. For example, if you promote a record with the `color: red` attribute, and the user filters the search for `color: blue`, the \"red\" record won't be shown. """ + hide: Optional[List[ConsequenceHide]] = Field(default=None, alias="hide") + """ Records you want to hide from the search results. """ + user_data: Optional[object] = Field(default=None, alias="userData") + """ A JSON object with custom data that will be appended to the `userData` array in the response. This object isn't interpreted by the API and is limited to 1 kB of minified JSON. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Consequence from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.params: - _dict["params"] = self.params.to_dict() - _items = [] - if self.promote: - for _item in self.promote: - if _item: - _items.append(_item.to_dict()) - _dict["promote"] = _items - _items = [] - if self.hide: - for _item in self.hide: - if _item: - _items.append(_item.to_dict()) - _dict["hide"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Consequence from a dict""" if obj is None: return None @@ -100,25 +70,20 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "params": ( - ConsequenceParams.from_dict(obj.get("params")) - if obj.get("params") is not None - else None - ), - "promote": ( - [Promote.from_dict(_item) for _item in obj.get("promote")] - if obj.get("promote") is not None - else None - ), - "filterPromotes": obj.get("filterPromotes"), - "hide": ( - [ConsequenceHide.from_dict(_item) for _item in obj.get("hide")] - if obj.get("hide") is not None - else None - ), - "userData": obj.get("userData"), - } + obj["params"] = ( + ConsequenceParams.from_dict(obj["params"]) + if obj.get("params") is not None + else None + ) + obj["promote"] = ( + [Promote.from_dict(_item) for _item in obj["promote"]] + if obj.get("promote") is not None + else None ) - return _obj + obj["hide"] = ( + [ConsequenceHide.from_dict(_item) for _item in obj["hide"]] + if obj.get("hide") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/consequence_hide.py b/algoliasearch/search/models/consequence_hide.py index 0f81da9f4..47d0fb64a 100644 --- a/algoliasearch/search/models/consequence_hide.py +++ b/algoliasearch/search/models/consequence_hide.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,42 +23,34 @@ class ConsequenceHide(BaseModel): Object ID of the record to hide. """ - object_id: StrictStr = Field( - description="Unique record identifier.", alias="objectID" - ) + object_id: str = Field(alias="objectID") + """ Unique record identifier. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ConsequenceHide from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ConsequenceHide from a dict""" if obj is None: return None @@ -66,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"objectID": obj.get("objectID")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/consequence_params.py b/algoliasearch/search/models/consequence_params.py index d04ae8ce3..6770b9b07 100644 --- a/algoliasearch/search/models/consequence_params.py +++ b/algoliasearch/search/models/consequence_params.py @@ -8,22 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional -from pydantic import ( - BaseModel, - ConfigDict, - Field, - StrictBool, - StrictFloat, - StrictInt, - StrictStr, -) +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.advanced_syntax_features import AdvancedSyntaxFeatures @@ -59,15 +51,10 @@ class ConsequenceParams(BaseModel): ConsequenceParams """ - similar_query: Optional[StrictStr] = Field( - default="", - description="Keywords to be used instead of the search query to conduct a more broader search. Using the `similarQuery` parameter changes other settings: - `queryType` is set to `prefixNone`. - `removeStopWords` is set to true. - `words` is set as the first ranking criterion. - All remaining words are treated as `optionalWords`. Since the `similarQuery` is supposed to do a broad search, they usually return many results. Combine it with `filters` to narrow down the list of results. ", - alias="similarQuery", - ) - filters: Optional[StrictStr] = Field( - default=None, - description="Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). ", - ) + similar_query: Optional[str] = Field(default=None, alias="similarQuery") + """ Keywords to be used instead of the search query to conduct a more broader search. Using the `similarQuery` parameter changes other settings: - `queryType` is set to `prefixNone`. - `removeStopWords` is set to true. - `words` is set as the first ranking criterion. - All remaining words are treated as `optionalWords`. Since the `similarQuery` is supposed to do a broad search, they usually return many results. Combine it with `filters` to narrow down the list of results. """ + filters: Optional[str] = Field(default=None, alias="filters") + """ Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). """ facet_filters: Optional[FacetFilters] = Field(default=None, alias="facetFilters") optional_filters: Optional[OptionalFilters] = Field( default=None, alias="optionalFilters" @@ -76,315 +63,202 @@ class ConsequenceParams(BaseModel): default=None, alias="numericFilters" ) tag_filters: Optional[TagFilters] = Field(default=None, alias="tagFilters") - sum_or_filters_scores: Optional[StrictBool] = Field( - default=False, - description="Whether to sum all filter scores. If true, all filter scores are summed. Otherwise, the maximum filter score is kept. For more information, see [filter scores](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/#accumulating-scores-with-sumorfiltersscores). ", - alias="sumOrFiltersScores", - ) - restrict_searchable_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Restricts a search to a subset of your searchable attributes. Attribute names are case-sensitive. ", - alias="restrictSearchableAttributes", - ) - facets: Optional[List[StrictStr]] = Field( - default=None, - description="Facets for which to retrieve facet values that match the search criteria and the number of matching facet values. To retrieve all facets, use the wildcard character `*`. For more information, see [facets](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#contextual-facet-values-and-counts). ", - ) - faceting_after_distinct: Optional[StrictBool] = Field( - default=False, - description="Whether faceting should be applied after deduplication with `distinct`. This leads to accurate facet counts when using faceting in combination with `distinct`. It's usually better to use `afterDistinct` modifiers in the `attributesForFaceting` setting, as `facetingAfterDistinct` only computes correct facet counts if all records have the same facet values for the `attributeForDistinct`. ", - alias="facetingAfterDistinct", - ) - page: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=0, description="Page of search results to retrieve." - ) - offset: Optional[StrictInt] = Field( - default=None, description="Position of the first hit to retrieve." - ) - length: Optional[Annotated[int, Field(le=1000, strict=True, ge=0)]] = Field( - default=None, - description="Number of hits to retrieve (used in combination with `offset`).", - ) - around_lat_lng: Optional[StrictStr] = Field( - default="", - description="Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude. Only records included within circle around this central location are included in the results. The radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings. This parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`. ", - alias="aroundLatLng", - ) - around_lat_lng_via_ip: Optional[StrictBool] = Field( - default=False, - description="Whether to obtain the coordinates from the request's IP address.", - alias="aroundLatLngViaIP", - ) + sum_or_filters_scores: Optional[bool] = Field( + default=None, alias="sumOrFiltersScores" + ) + """ Whether to sum all filter scores. If true, all filter scores are summed. Otherwise, the maximum filter score is kept. For more information, see [filter scores](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/#accumulating-scores-with-sumorfiltersscores). """ + restrict_searchable_attributes: Optional[List[str]] = Field( + default=None, alias="restrictSearchableAttributes" + ) + """ Restricts a search to a subset of your searchable attributes. Attribute names are case-sensitive. """ + facets: Optional[List[str]] = Field(default=None, alias="facets") + """ Facets for which to retrieve facet values that match the search criteria and the number of matching facet values. To retrieve all facets, use the wildcard character `*`. For more information, see [facets](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#contextual-facet-values-and-counts). """ + faceting_after_distinct: Optional[bool] = Field( + default=None, alias="facetingAfterDistinct" + ) + """ Whether faceting should be applied after deduplication with `distinct`. This leads to accurate facet counts when using faceting in combination with `distinct`. It's usually better to use `afterDistinct` modifiers in the `attributesForFaceting` setting, as `facetingAfterDistinct` only computes correct facet counts if all records have the same facet values for the `attributeForDistinct`. """ + page: Optional[int] = Field(default=None, alias="page") + """ Page of search results to retrieve. """ + offset: Optional[int] = Field(default=None, alias="offset") + """ Position of the first hit to retrieve. """ + length: Optional[int] = Field(default=None, alias="length") + """ Number of hits to retrieve (used in combination with `offset`). """ + around_lat_lng: Optional[str] = Field(default=None, alias="aroundLatLng") + """ Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude. Only records included within circle around this central location are included in the results. The radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings. This parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`. """ + around_lat_lng_via_ip: Optional[bool] = Field( + default=None, alias="aroundLatLngViaIP" + ) + """ Whether to obtain the coordinates from the request's IP address. """ around_radius: Optional[AroundRadius] = Field(default=None, alias="aroundRadius") around_precision: Optional[AroundPrecision] = Field( default=None, alias="aroundPrecision" ) - minimum_around_radius: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field( - default=None, - description="Minimum radius (in meters) for a search around a location when `aroundRadius` isn't set.", - alias="minimumAroundRadius", - ) - inside_bounding_box: Optional[ - List[ - Annotated[ - List[Union[StrictFloat, StrictInt]], Field(min_length=4, max_length=4) - ] - ] - ] = Field( - default=None, - description="Coordinates for a rectangular area in which to search. Each bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair: `[p1 lat, p1 long, p2 lat, p2 long]`. Provide multiple bounding boxes as nested arrays. For more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). ", - alias="insideBoundingBox", - ) - inside_polygon: Optional[ - List[ - Annotated[ - List[Union[StrictFloat, StrictInt]], - Field(min_length=6, max_length=20000), - ] - ] - ] = Field( - default=None, - description="Coordinates of a polygon in which to search. Polygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude. Provide multiple polygons as nested arrays. For more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). This parameter is ignored if you also specify `insideBoundingBox`. ", - alias="insidePolygon", + minimum_around_radius: Optional[int] = Field( + default=None, alias="minimumAroundRadius" ) - natural_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="ISO language codes that adjust settings that are useful for processing natural language queries (as opposed to keyword searches): - Sets `removeStopWords` and `ignorePlurals` to the list of provided languages. - Sets `removeWordsIfNoResults` to `allOptional`. - Adds a `natural_language` attribute to `ruleContexts` and `analyticsTags`. ", - alias="naturalLanguages", - ) - rule_contexts: Optional[List[StrictStr]] = Field( - default=None, - description="Assigns a rule context to the search query. [Rule contexts](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/how-to/customize-search-results-by-platform/#whats-a-context) are strings that you can use to trigger matching rules. ", - alias="ruleContexts", - ) - personalization_impact: Optional[ - Annotated[int, Field(le=100, strict=True, ge=0)] - ] = Field( - default=100, - description="Impact that Personalization should have on this search. The higher this value is, the more Personalization determines the ranking compared to other factors. For more information, see [Understanding Personalization impact](https://www.algolia.com/doc/guides/personalization/personalizing-results/in-depth/configuring-personalization/#understanding-personalization-impact). ", - alias="personalizationImpact", - ) - user_token: Optional[StrictStr] = Field( - default=None, - description="Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - get_ranking_info: Optional[StrictBool] = Field( - default=False, - description="Whether the search response should include detailed ranking information.", - alias="getRankingInfo", - ) - synonyms: Optional[StrictBool] = Field( - default=True, - description="Whether to take into account an index's synonyms for this search.", - ) - click_analytics: Optional[StrictBool] = Field( - default=False, - description="Whether to include a `queryID` attribute in the response. The query ID is a unique identifier for a search query and is required for tracking [click and conversion events](https://www.algolia.com/guides/sending-events/getting-started/). ", - alias="clickAnalytics", - ) - analytics: Optional[StrictBool] = Field( - default=True, description="Whether this search will be included in Analytics." - ) - analytics_tags: Optional[List[StrictStr]] = Field( - default=None, - description="Tags to apply to the query for [segmenting analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/).", - alias="analyticsTags", - ) - percentile_computation: Optional[StrictBool] = Field( - default=True, - description="Whether to include this search when calculating processing-time percentiles.", - alias="percentileComputation", - ) - enable_ab_test: Optional[StrictBool] = Field( - default=True, - description="Whether to enable A/B testing for this search.", - alias="enableABTest", - ) - attributes_to_retrieve: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `["*", "-ATTRIBUTE"]`. - The `objectID` attribute is always included. ', - alias="attributesToRetrieve", - ) - ranking: Optional[List[StrictStr]] = Field( - default=None, - description='Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they\'re specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc("ATTRIBUTE")`. Sort the index by the values of an attribute, in ascending order. - `desc("ATTRIBUTE")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). ', - ) - custom_ranking: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes to use as [custom ranking](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/). Attribute names are case-sensitive. The custom ranking attributes decide which items are shown first if the other ranking criteria are equal. Records with missing values for your selected custom ranking attributes are always sorted last. Boolean attributes are sorted based on their alphabetical order. **Modifiers** - `asc("ATTRIBUTE")`. Sort the index by the values of an attribute, in ascending order. - `desc("ATTRIBUTE")`. Sort the index by the values of an attribute, in descending order. If you use two or more custom ranking attributes, [reduce the precision](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/how-to/controlling-custom-ranking-metrics-precision/) of your first attributes, or the other attributes will never be applied. ', - alias="customRanking", - ) - relevancy_strictness: Optional[StrictInt] = Field( - default=100, - description="Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. ", - alias="relevancyStrictness", - ) - attributes_to_highlight: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). ", - alias="attributesToHighlight", - ) - attributes_to_snippet: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. ", - alias="attributesToSnippet", - ) - highlight_pre_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert before the highlighted parts in all highlighted results and snippets.", - alias="highlightPreTag", - ) - highlight_post_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert after the highlighted parts in all highlighted results and snippets.", - alias="highlightPostTag", - ) - snippet_ellipsis_text: Optional[StrictStr] = Field( - default="…", - description="String used as an ellipsis indicator when a snippet is truncated.", - alias="snippetEllipsisText", - ) - restrict_highlight_and_snippet_arrays: Optional[StrictBool] = Field( - default=False, - description="Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. ", - alias="restrictHighlightAndSnippetArrays", - ) - hits_per_page: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = Field( - default=20, description="Number of hits per page.", alias="hitsPerPage" - ) - min_word_sizefor1_typo: Optional[StrictInt] = Field( - default=4, - description="Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor1Typo", - ) - min_word_sizefor2_typos: Optional[StrictInt] = Field( - default=8, - description="Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor2Typos", + """ Minimum radius (in meters) for a search around a location when `aroundRadius` isn't set. """ + inside_bounding_box: Optional[List[List[float]]] = Field( + default=None, alias="insideBoundingBox" ) + """ Coordinates for a rectangular area in which to search. Each bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair: `[p1 lat, p1 long, p2 lat, p2 long]`. Provide multiple bounding boxes as nested arrays. For more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). """ + inside_polygon: Optional[List[List[float]]] = Field( + default=None, alias="insidePolygon" + ) + """ Coordinates of a polygon in which to search. Polygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude. Provide multiple polygons as nested arrays. For more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). This parameter is ignored if you also specify `insideBoundingBox`. """ + natural_languages: Optional[List[SupportedLanguage]] = Field( + default=None, alias="naturalLanguages" + ) + """ ISO language codes that adjust settings that are useful for processing natural language queries (as opposed to keyword searches): - Sets `removeStopWords` and `ignorePlurals` to the list of provided languages. - Sets `removeWordsIfNoResults` to `allOptional`. - Adds a `natural_language` attribute to `ruleContexts` and `analyticsTags`. """ + rule_contexts: Optional[List[str]] = Field(default=None, alias="ruleContexts") + """ Assigns a rule context to the search query. [Rule contexts](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/how-to/customize-search-results-by-platform/#whats-a-context) are strings that you can use to trigger matching rules. """ + personalization_impact: Optional[int] = Field( + default=None, alias="personalizationImpact" + ) + """ Impact that Personalization should have on this search. The higher this value is, the more Personalization determines the ranking compared to other factors. For more information, see [Understanding Personalization impact](https://www.algolia.com/doc/guides/personalization/personalizing-results/in-depth/configuring-personalization/#understanding-personalization-impact). """ + user_token: Optional[str] = Field(default=None, alias="userToken") + """ Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + get_ranking_info: Optional[bool] = Field(default=None, alias="getRankingInfo") + """ Whether the search response should include detailed ranking information. """ + synonyms: Optional[bool] = Field(default=None, alias="synonyms") + """ Whether to take into account an index's synonyms for this search. """ + click_analytics: Optional[bool] = Field(default=None, alias="clickAnalytics") + """ Whether to include a `queryID` attribute in the response. The query ID is a unique identifier for a search query and is required for tracking [click and conversion events](https://www.algolia.com/guides/sending-events/getting-started/). """ + analytics: Optional[bool] = Field(default=None, alias="analytics") + """ Whether this search will be included in Analytics. """ + analytics_tags: Optional[List[str]] = Field(default=None, alias="analyticsTags") + """ Tags to apply to the query for [segmenting analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). """ + percentile_computation: Optional[bool] = Field( + default=None, alias="percentileComputation" + ) + """ Whether to include this search when calculating processing-time percentiles. """ + enable_ab_test: Optional[bool] = Field(default=None, alias="enableABTest") + """ Whether to enable A/B testing for this search. """ + attributes_to_retrieve: Optional[List[str]] = Field( + default=None, alias="attributesToRetrieve" + ) + """ Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `[\"*\", \"-ATTRIBUTE\"]`. - The `objectID` attribute is always included. """ + ranking: Optional[List[str]] = Field(default=None, alias="ranking") + """ Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they're specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in ascending order. - `desc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). """ + custom_ranking: Optional[List[str]] = Field(default=None, alias="customRanking") + """ Attributes to use as [custom ranking](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/). Attribute names are case-sensitive. The custom ranking attributes decide which items are shown first if the other ranking criteria are equal. Records with missing values for your selected custom ranking attributes are always sorted last. Boolean attributes are sorted based on their alphabetical order. **Modifiers** - `asc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in ascending order. - `desc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in descending order. If you use two or more custom ranking attributes, [reduce the precision](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/how-to/controlling-custom-ranking-metrics-precision/) of your first attributes, or the other attributes will never be applied. """ + relevancy_strictness: Optional[int] = Field( + default=None, alias="relevancyStrictness" + ) + """ Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. """ + attributes_to_highlight: Optional[List[str]] = Field( + default=None, alias="attributesToHighlight" + ) + """ Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). """ + attributes_to_snippet: Optional[List[str]] = Field( + default=None, alias="attributesToSnippet" + ) + """ Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. """ + highlight_pre_tag: Optional[str] = Field(default=None, alias="highlightPreTag") + """ HTML tag to insert before the highlighted parts in all highlighted results and snippets. """ + highlight_post_tag: Optional[str] = Field(default=None, alias="highlightPostTag") + """ HTML tag to insert after the highlighted parts in all highlighted results and snippets. """ + snippet_ellipsis_text: Optional[str] = Field( + default=None, alias="snippetEllipsisText" + ) + """ String used as an ellipsis indicator when a snippet is truncated. """ + restrict_highlight_and_snippet_arrays: Optional[bool] = Field( + default=None, alias="restrictHighlightAndSnippetArrays" + ) + """ Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. """ + hits_per_page: Optional[int] = Field(default=None, alias="hitsPerPage") + """ Number of hits per page. """ + min_word_sizefor1_typo: Optional[int] = Field( + default=None, alias="minWordSizefor1Typo" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ + min_word_sizefor2_typos: Optional[int] = Field( + default=None, alias="minWordSizefor2Typos" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ typo_tolerance: Optional[TypoTolerance] = Field(default=None, alias="typoTolerance") - allow_typos_on_numeric_tokens: Optional[StrictBool] = Field( - default=True, - description="Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. ", - alias="allowTyposOnNumericTokens", + allow_typos_on_numeric_tokens: Optional[bool] = Field( + default=None, alias="allowTyposOnNumericTokens" ) - disable_typo_tolerance_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. ", - alias="disableTypoToleranceOnAttributes", + """ Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. """ + disable_typo_tolerance_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableTypoToleranceOnAttributes" ) + """ Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. """ ignore_plurals: Optional[IgnorePlurals] = Field(default=None, alias="ignorePlurals") remove_stop_words: Optional[RemoveStopWords] = Field( default=None, alias="removeStopWords" ) - keep_diacritics_on_characters: Optional[StrictStr] = Field( - default="", - description="Characters for which diacritics should be preserved. By default, Algolia removes diacritics from letters. For example, `é` becomes `e`. If this causes issues in your search, you can specify characters that should keep their diacritics. ", - alias="keepDiacriticsOnCharacters", + keep_diacritics_on_characters: Optional[str] = Field( + default=None, alias="keepDiacriticsOnCharacters" ) + """ Characters for which diacritics should be preserved. By default, Algolia removes diacritics from letters. For example, `é` becomes `e`. If this causes issues in your search, you can specify characters that should keep their diacritics. """ query_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). ", - alias="queryLanguages", + default=None, alias="queryLanguages" ) - decompound_query: Optional[StrictBool] = Field( - default=True, - description="Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). ", - alias="decompoundQuery", - ) - enable_rules: Optional[StrictBool] = Field( - default=True, description="Whether to enable rules.", alias="enableRules" - ) - enable_personalization: Optional[StrictBool] = Field( - default=False, - description="Whether to enable Personalization.", - alias="enablePersonalization", + """ Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). """ + decompound_query: Optional[bool] = Field(default=None, alias="decompoundQuery") + """ Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). """ + enable_rules: Optional[bool] = Field(default=None, alias="enableRules") + """ Whether to enable rules. """ + enable_personalization: Optional[bool] = Field( + default=None, alias="enablePersonalization" ) + """ Whether to enable Personalization. """ query_type: Optional[QueryType] = Field(default=None, alias="queryType") remove_words_if_no_results: Optional[RemoveWordsIfNoResults] = Field( default=None, alias="removeWordsIfNoResults" ) - mode: Optional[Mode] = None + mode: Optional[Mode] = Field(default=None, alias="mode") semantic_search: Optional[SemanticSearch] = Field( default=None, alias="semanticSearch" ) - advanced_syntax: Optional[StrictBool] = Field( - default=False, - description="Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. ", - alias="advancedSyntax", - ) - optional_words: Optional[List[StrictStr]] = Field( - default=None, - description='Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn\'t include the optional words. For example, if the search query is "action video" and "video" is an optional word, the search engine runs two queries. One for "action video" and one for "action". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). ', - alias="optionalWords", - ) - disable_exact_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. ", - alias="disableExactOnAttributes", + advanced_syntax: Optional[bool] = Field(default=None, alias="advancedSyntax") + """ Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. """ + optional_words: Optional[List[str]] = Field(default=None, alias="optionalWords") + """ Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn't include the optional words. For example, if the search query is \"action video\" and \"video\" is an optional word, the search engine runs two queries. One for \"action video\" and one for \"action\". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). """ + disable_exact_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableExactOnAttributes" ) + """ Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. """ exact_on_single_word_query: Optional[ExactOnSingleWordQuery] = Field( default=None, alias="exactOnSingleWordQuery" ) alternatives_as_exact: Optional[List[AlternativesAsExact]] = Field( - default=None, - description='Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as "NY/NYC" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as "NY/New York" are considered exact matches. ', - alias="alternativesAsExact", + default=None, alias="alternativesAsExact" ) + """ Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as \"NY/NYC\" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as \"NY/New York\" are considered exact matches. """ advanced_syntax_features: Optional[List[AdvancedSyntaxFeatures]] = Field( - default=None, - description='Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue "iPhone case"` only returns records with the exact string "iPhone case". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain "search" but not "engine". This setting only has an effect if `advancedSyntax` is true. ', - alias="advancedSyntaxFeatures", - ) - distinct: Optional[Distinct] = None - replace_synonyms_in_highlight: Optional[StrictBool] = Field( - default=False, - description='Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either "home" or "house" are included in the search results, and either "home" or "house" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of "house" are replaced by "home" in the highlighted response. ', - alias="replaceSynonymsInHighlight", - ) - min_proximity: Optional[Annotated[int, Field(le=7, strict=True, ge=1)]] = Field( - default=1, - description="Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. ", - alias="minProximity", - ) - response_fields: Optional[List[StrictStr]] = Field( - default=None, - description="Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. ", - alias="responseFields", - ) - max_facet_hits: Optional[Annotated[int, Field(le=100, strict=True)]] = Field( - default=10, - description="Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values).", - alias="maxFacetHits", - ) - max_values_per_facet: Optional[Annotated[int, Field(le=1000, strict=True)]] = Field( - default=100, - description="Maximum number of facet values to return for each facet.", - alias="maxValuesPerFacet", - ) - sort_facet_values_by: Optional[StrictStr] = Field( - default="count", - description="Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). ", - alias="sortFacetValuesBy", - ) - attribute_criteria_computed_by_min_proximity: Optional[StrictBool] = Field( - default=False, - description="Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. ", - alias="attributeCriteriaComputedByMinProximity", - ) + default=None, alias="advancedSyntaxFeatures" + ) + """ Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue \"iPhone case\"` only returns records with the exact string \"iPhone case\". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain \"search\" but not \"engine\". This setting only has an effect if `advancedSyntax` is true. """ + distinct: Optional[Distinct] = Field(default=None, alias="distinct") + replace_synonyms_in_highlight: Optional[bool] = Field( + default=None, alias="replaceSynonymsInHighlight" + ) + """ Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either \"home\" or \"house\" are included in the search results, and either \"home\" or \"house\" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of \"house\" are replaced by \"home\" in the highlighted response. """ + min_proximity: Optional[int] = Field(default=None, alias="minProximity") + """ Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. """ + response_fields: Optional[List[str]] = Field(default=None, alias="responseFields") + """ Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. """ + max_facet_hits: Optional[int] = Field(default=None, alias="maxFacetHits") + """ Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values). """ + max_values_per_facet: Optional[int] = Field(default=None, alias="maxValuesPerFacet") + """ Maximum number of facet values to return for each facet. """ + sort_facet_values_by: Optional[str] = Field(default=None, alias="sortFacetValuesBy") + """ Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). """ + attribute_criteria_computed_by_min_proximity: Optional[bool] = Field( + default=None, alias="attributeCriteriaComputedByMinProximity" + ) + """ Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. """ rendering_content: Optional[RenderingContent] = Field( default=None, alias="renderingContent" ) - enable_re_ranking: Optional[StrictBool] = Field( - default=True, - description="Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. ", - alias="enableReRanking", - ) + enable_re_ranking: Optional[bool] = Field(default=None, alias="enableReRanking") + """ Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. """ re_ranking_apply_filter: Optional[ReRankingApplyFilter] = Field( default=None, alias="reRankingApplyFilter" ) - query: Optional[ConsequenceQuery] = None + query: Optional[ConsequenceQuery] = Field(default=None, alias="query") automatic_facet_filters: Optional[AutomaticFacetFilters] = Field( default=None, alias="automaticFacetFilters" ) @@ -393,71 +267,30 @@ class ConsequenceParams(BaseModel): ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ConsequenceParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.facet_filters: - _dict["facetFilters"] = self.facet_filters.to_dict() - if self.optional_filters: - _dict["optionalFilters"] = self.optional_filters.to_dict() - if self.numeric_filters: - _dict["numericFilters"] = self.numeric_filters.to_dict() - if self.tag_filters: - _dict["tagFilters"] = self.tag_filters.to_dict() - if self.around_radius: - _dict["aroundRadius"] = self.around_radius.to_dict() - if self.around_precision: - _dict["aroundPrecision"] = self.around_precision.to_dict() - if self.typo_tolerance: - _dict["typoTolerance"] = self.typo_tolerance.to_dict() - if self.ignore_plurals: - _dict["ignorePlurals"] = self.ignore_plurals.to_dict() - if self.remove_stop_words: - _dict["removeStopWords"] = self.remove_stop_words.to_dict() - if self.semantic_search: - _dict["semanticSearch"] = self.semantic_search.to_dict() - if self.distinct: - _dict["distinct"] = self.distinct.to_dict() - if self.rendering_content: - _dict["renderingContent"] = self.rendering_content.to_dict() - if self.re_ranking_apply_filter: - _dict["reRankingApplyFilter"] = self.re_ranking_apply_filter.to_dict() - if self.query: - _dict["query"] = self.query.to_dict() - if self.automatic_facet_filters: - _dict["automaticFacetFilters"] = self.automatic_facet_filters.to_dict() - if self.automatic_optional_facet_filters: - _dict["automaticOptionalFacetFilters"] = ( - self.automatic_optional_facet_filters.to_dict() - ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ConsequenceParams from a dict""" if obj is None: return None @@ -465,158 +298,93 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "similarQuery": obj.get("similarQuery"), - "filters": obj.get("filters"), - "facetFilters": ( - FacetFilters.from_dict(obj.get("facetFilters")) - if obj.get("facetFilters") is not None - else None - ), - "optionalFilters": ( - OptionalFilters.from_dict(obj.get("optionalFilters")) - if obj.get("optionalFilters") is not None - else None - ), - "numericFilters": ( - NumericFilters.from_dict(obj.get("numericFilters")) - if obj.get("numericFilters") is not None - else None - ), - "tagFilters": ( - TagFilters.from_dict(obj.get("tagFilters")) - if obj.get("tagFilters") is not None - else None - ), - "sumOrFiltersScores": obj.get("sumOrFiltersScores"), - "restrictSearchableAttributes": obj.get("restrictSearchableAttributes"), - "facets": obj.get("facets"), - "facetingAfterDistinct": obj.get("facetingAfterDistinct"), - "page": obj.get("page"), - "offset": obj.get("offset"), - "length": obj.get("length"), - "aroundLatLng": obj.get("aroundLatLng"), - "aroundLatLngViaIP": obj.get("aroundLatLngViaIP"), - "aroundRadius": ( - AroundRadius.from_dict(obj.get("aroundRadius")) - if obj.get("aroundRadius") is not None - else None - ), - "aroundPrecision": ( - AroundPrecision.from_dict(obj.get("aroundPrecision")) - if obj.get("aroundPrecision") is not None - else None - ), - "minimumAroundRadius": obj.get("minimumAroundRadius"), - "insideBoundingBox": obj.get("insideBoundingBox"), - "insidePolygon": obj.get("insidePolygon"), - "naturalLanguages": obj.get("naturalLanguages"), - "ruleContexts": obj.get("ruleContexts"), - "personalizationImpact": obj.get("personalizationImpact"), - "userToken": obj.get("userToken"), - "getRankingInfo": obj.get("getRankingInfo"), - "synonyms": obj.get("synonyms"), - "clickAnalytics": obj.get("clickAnalytics"), - "analytics": obj.get("analytics"), - "analyticsTags": obj.get("analyticsTags"), - "percentileComputation": obj.get("percentileComputation"), - "enableABTest": obj.get("enableABTest"), - "attributesToRetrieve": obj.get("attributesToRetrieve"), - "ranking": obj.get("ranking"), - "customRanking": obj.get("customRanking"), - "relevancyStrictness": obj.get("relevancyStrictness"), - "attributesToHighlight": obj.get("attributesToHighlight"), - "attributesToSnippet": obj.get("attributesToSnippet"), - "highlightPreTag": obj.get("highlightPreTag"), - "highlightPostTag": obj.get("highlightPostTag"), - "snippetEllipsisText": obj.get("snippetEllipsisText"), - "restrictHighlightAndSnippetArrays": obj.get( - "restrictHighlightAndSnippetArrays" - ), - "hitsPerPage": obj.get("hitsPerPage"), - "minWordSizefor1Typo": obj.get("minWordSizefor1Typo"), - "minWordSizefor2Typos": obj.get("minWordSizefor2Typos"), - "typoTolerance": ( - TypoTolerance.from_dict(obj.get("typoTolerance")) - if obj.get("typoTolerance") is not None - else None - ), - "allowTyposOnNumericTokens": obj.get("allowTyposOnNumericTokens"), - "disableTypoToleranceOnAttributes": obj.get( - "disableTypoToleranceOnAttributes" - ), - "ignorePlurals": ( - IgnorePlurals.from_dict(obj.get("ignorePlurals")) - if obj.get("ignorePlurals") is not None - else None - ), - "removeStopWords": ( - RemoveStopWords.from_dict(obj.get("removeStopWords")) - if obj.get("removeStopWords") is not None - else None - ), - "keepDiacriticsOnCharacters": obj.get("keepDiacriticsOnCharacters"), - "queryLanguages": obj.get("queryLanguages"), - "decompoundQuery": obj.get("decompoundQuery"), - "enableRules": obj.get("enableRules"), - "enablePersonalization": obj.get("enablePersonalization"), - "queryType": obj.get("queryType"), - "removeWordsIfNoResults": obj.get("removeWordsIfNoResults"), - "mode": obj.get("mode"), - "semanticSearch": ( - SemanticSearch.from_dict(obj.get("semanticSearch")) - if obj.get("semanticSearch") is not None - else None - ), - "advancedSyntax": obj.get("advancedSyntax"), - "optionalWords": obj.get("optionalWords"), - "disableExactOnAttributes": obj.get("disableExactOnAttributes"), - "exactOnSingleWordQuery": obj.get("exactOnSingleWordQuery"), - "alternativesAsExact": obj.get("alternativesAsExact"), - "advancedSyntaxFeatures": obj.get("advancedSyntaxFeatures"), - "distinct": ( - Distinct.from_dict(obj.get("distinct")) - if obj.get("distinct") is not None - else None - ), - "replaceSynonymsInHighlight": obj.get("replaceSynonymsInHighlight"), - "minProximity": obj.get("minProximity"), - "responseFields": obj.get("responseFields"), - "maxFacetHits": obj.get("maxFacetHits"), - "maxValuesPerFacet": obj.get("maxValuesPerFacet"), - "sortFacetValuesBy": obj.get("sortFacetValuesBy"), - "attributeCriteriaComputedByMinProximity": obj.get( - "attributeCriteriaComputedByMinProximity" - ), - "renderingContent": ( - RenderingContent.from_dict(obj.get("renderingContent")) - if obj.get("renderingContent") is not None - else None - ), - "enableReRanking": obj.get("enableReRanking"), - "reRankingApplyFilter": ( - ReRankingApplyFilter.from_dict(obj.get("reRankingApplyFilter")) - if obj.get("reRankingApplyFilter") is not None - else None - ), - "query": ( - ConsequenceQuery.from_dict(obj.get("query")) - if obj.get("query") is not None - else None - ), - "automaticFacetFilters": ( - AutomaticFacetFilters.from_dict(obj.get("automaticFacetFilters")) - if obj.get("automaticFacetFilters") is not None - else None - ), - "automaticOptionalFacetFilters": ( - AutomaticFacetFilters.from_dict( - obj.get("automaticOptionalFacetFilters") - ) - if obj.get("automaticOptionalFacetFilters") is not None - else None - ), - } + obj["facetFilters"] = ( + FacetFilters.from_dict(obj["facetFilters"]) + if obj.get("facetFilters") is not None + else None + ) + obj["optionalFilters"] = ( + OptionalFilters.from_dict(obj["optionalFilters"]) + if obj.get("optionalFilters") is not None + else None + ) + obj["numericFilters"] = ( + NumericFilters.from_dict(obj["numericFilters"]) + if obj.get("numericFilters") is not None + else None + ) + obj["tagFilters"] = ( + TagFilters.from_dict(obj["tagFilters"]) + if obj.get("tagFilters") is not None + else None + ) + obj["aroundRadius"] = ( + AroundRadius.from_dict(obj["aroundRadius"]) + if obj.get("aroundRadius") is not None + else None + ) + obj["aroundPrecision"] = ( + AroundPrecision.from_dict(obj["aroundPrecision"]) + if obj.get("aroundPrecision") is not None + else None + ) + obj["naturalLanguages"] = obj.get("naturalLanguages") + obj["typoTolerance"] = ( + TypoTolerance.from_dict(obj["typoTolerance"]) + if obj.get("typoTolerance") is not None + else None + ) + obj["ignorePlurals"] = ( + IgnorePlurals.from_dict(obj["ignorePlurals"]) + if obj.get("ignorePlurals") is not None + else None ) - return _obj + obj["removeStopWords"] = ( + RemoveStopWords.from_dict(obj["removeStopWords"]) + if obj.get("removeStopWords") is not None + else None + ) + obj["queryLanguages"] = obj.get("queryLanguages") + obj["queryType"] = obj.get("queryType") + obj["removeWordsIfNoResults"] = obj.get("removeWordsIfNoResults") + obj["mode"] = obj.get("mode") + obj["semanticSearch"] = ( + SemanticSearch.from_dict(obj["semanticSearch"]) + if obj.get("semanticSearch") is not None + else None + ) + obj["exactOnSingleWordQuery"] = obj.get("exactOnSingleWordQuery") + obj["alternativesAsExact"] = obj.get("alternativesAsExact") + obj["advancedSyntaxFeatures"] = obj.get("advancedSyntaxFeatures") + obj["distinct"] = ( + Distinct.from_dict(obj["distinct"]) + if obj.get("distinct") is not None + else None + ) + obj["renderingContent"] = ( + RenderingContent.from_dict(obj["renderingContent"]) + if obj.get("renderingContent") is not None + else None + ) + obj["reRankingApplyFilter"] = ( + ReRankingApplyFilter.from_dict(obj["reRankingApplyFilter"]) + if obj.get("reRankingApplyFilter") is not None + else None + ) + obj["query"] = ( + ConsequenceQuery.from_dict(obj["query"]) + if obj.get("query") is not None + else None + ) + obj["automaticFacetFilters"] = ( + AutomaticFacetFilters.from_dict(obj["automaticFacetFilters"]) + if obj.get("automaticFacetFilters") is not None + else None + ) + obj["automaticOptionalFacetFilters"] = ( + AutomaticFacetFilters.from_dict(obj["automaticOptionalFacetFilters"]) + if obj.get("automaticOptionalFacetFilters") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/consequence_query.py b/algoliasearch/search/models/consequence_query.py index 4e58712d0..9c7537290 100644 --- a/algoliasearch/search/models/consequence_query.py +++ b/algoliasearch/search/models/consequence_query.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, StrictStr, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -26,9 +26,12 @@ class ConsequenceQuery(BaseModel): Replace or edit the search query. If `consequenceQuery` is a string, the entire search query is replaced with that string. If `consequenceQuery` is an object, it describes incremental edits made to the query. """ - oneof_schema_1_validator: Optional[ConsequenceQueryObject] = None - oneof_schema_2_validator: Optional[StrictStr] = None + oneof_schema_1_validator: Optional[ConsequenceQueryObject] = Field(default=None) + + oneof_schema_2_validator: Optional[str] = Field(default=None) + actual_instance: Optional[Union[ConsequenceQueryObject, str]] = None + one_of_schemas: Set[str] = {"ConsequenceQueryObject", "str"} def __init__(self, *args, **kwargs) -> None: if args: @@ -52,7 +55,8 @@ def unwrap_actual_instance(self) -> Optional[Union[ConsequenceQueryObject, str]] return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of ConsequenceQuery from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -85,17 +89,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], ConsequenceQueryObject, str]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/consequence_query_object.py b/algoliasearch/search/models/consequence_query_object.py index 2d3d3dfcf..044076949 100644 --- a/algoliasearch/search/models/consequence_query_object.py +++ b/algoliasearch/search/models/consequence_query_object.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,51 +26,36 @@ class ConsequenceQueryObject(BaseModel): ConsequenceQueryObject """ - remove: Optional[List[StrictStr]] = Field( - default=None, description="Words to remove from the search query." - ) - edits: Optional[List[Edit]] = Field( - default=None, description="Changes to make to the search query." - ) + remove: Optional[List[str]] = Field(default=None, alias="remove") + """ Words to remove from the search query. """ + edits: Optional[List[Edit]] = Field(default=None, alias="edits") + """ Changes to make to the search query. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ConsequenceQueryObject from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.edits: - for _item in self.edits: - if _item: - _items.append(_item.to_dict()) - _dict["edits"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ConsequenceQueryObject from a dict""" if obj is None: return None @@ -78,14 +63,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "remove": obj.get("remove"), - "edits": ( - [Edit.from_dict(_item) for _item in obj.get("edits")] - if obj.get("edits") is not None - else None - ), - } + obj["edits"] = ( + [Edit.from_dict(_item) for _item in obj["edits"]] + if obj.get("edits") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/created_at_response.py b/algoliasearch/search/models/created_at_response.py index 5eb22e51d..f7e63ab05 100644 --- a/algoliasearch/search/models/created_at_response.py +++ b/algoliasearch/search/models/created_at_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,34 @@ class CreatedAtResponse(BaseModel): Response and creation timestamp. """ - created_at: StrictStr = Field( - description="Date and time when the object was created, in RFC 3339 format.", - alias="createdAt", - ) + created_at: str = Field(alias="createdAt") + """ Date and time when the object was created, in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of CreatedAtResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of CreatedAtResponse from a dict""" if obj is None: return None @@ -67,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"createdAt": obj.get("createdAt")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/delete_api_key_response.py b/algoliasearch/search/models/delete_api_key_response.py index 73eafbf67..ad6459f83 100644 --- a/algoliasearch/search/models/delete_api_key_response.py +++ b/algoliasearch/search/models/delete_api_key_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,34 @@ class DeleteApiKeyResponse(BaseModel): DeleteApiKeyResponse """ - deleted_at: StrictStr = Field( - description="Date and time when the object was deleted, in RFC 3339 format.", - alias="deletedAt", - ) + deleted_at: str = Field(alias="deletedAt") + """ Date and time when the object was deleted, in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DeleteApiKeyResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DeleteApiKeyResponse from a dict""" if obj is None: return None @@ -67,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"deletedAt": obj.get("deletedAt")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/delete_by_params.py b/algoliasearch/search/models/delete_by_params.py index b720074eb..d4589d219 100644 --- a/algoliasearch/search/models/delete_by_params.py +++ b/algoliasearch/search/models/delete_by_params.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.around_radius import AroundRadius @@ -30,84 +30,49 @@ class DeleteByParams(BaseModel): """ facet_filters: Optional[FacetFilters] = Field(default=None, alias="facetFilters") - filters: Optional[StrictStr] = Field( - default=None, - description="Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). ", - ) + filters: Optional[str] = Field(default=None, alias="filters") + """ Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). """ numeric_filters: Optional[NumericFilters] = Field( default=None, alias="numericFilters" ) tag_filters: Optional[TagFilters] = Field(default=None, alias="tagFilters") - around_lat_lng: Optional[StrictStr] = Field( - default="", - description="Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude. Only records included within circle around this central location are included in the results. The radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings. This parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`. ", - alias="aroundLatLng", - ) + around_lat_lng: Optional[str] = Field(default=None, alias="aroundLatLng") + """ Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude. Only records included within circle around this central location are included in the results. The radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings. This parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`. """ around_radius: Optional[AroundRadius] = Field(default=None, alias="aroundRadius") - inside_bounding_box: Optional[ - List[ - Annotated[ - List[Union[StrictFloat, StrictInt]], Field(min_length=4, max_length=4) - ] - ] - ] = Field( - default=None, - description="Coordinates for a rectangular area in which to search. Each bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair: `[p1 lat, p1 long, p2 lat, p2 long]`. Provide multiple bounding boxes as nested arrays. For more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). ", - alias="insideBoundingBox", + inside_bounding_box: Optional[List[List[float]]] = Field( + default=None, alias="insideBoundingBox" ) - inside_polygon: Optional[ - List[ - Annotated[ - List[Union[StrictFloat, StrictInt]], - Field(min_length=6, max_length=20000), - ] - ] - ] = Field( - default=None, - description="Coordinates of a polygon in which to search. Polygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude. Provide multiple polygons as nested arrays. For more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). This parameter is ignored if you also specify `insideBoundingBox`. ", - alias="insidePolygon", + """ Coordinates for a rectangular area in which to search. Each bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair: `[p1 lat, p1 long, p2 lat, p2 long]`. Provide multiple bounding boxes as nested arrays. For more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). """ + inside_polygon: Optional[List[List[float]]] = Field( + default=None, alias="insidePolygon" ) + """ Coordinates of a polygon in which to search. Polygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude. Provide multiple polygons as nested arrays. For more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). This parameter is ignored if you also specify `insideBoundingBox`. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DeleteByParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.facet_filters: - _dict["facetFilters"] = self.facet_filters.to_dict() - if self.numeric_filters: - _dict["numericFilters"] = self.numeric_filters.to_dict() - if self.tag_filters: - _dict["tagFilters"] = self.tag_filters.to_dict() - if self.around_radius: - _dict["aroundRadius"] = self.around_radius.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DeleteByParams from a dict""" if obj is None: return None @@ -115,32 +80,25 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "facetFilters": ( - FacetFilters.from_dict(obj.get("facetFilters")) - if obj.get("facetFilters") is not None - else None - ), - "filters": obj.get("filters"), - "numericFilters": ( - NumericFilters.from_dict(obj.get("numericFilters")) - if obj.get("numericFilters") is not None - else None - ), - "tagFilters": ( - TagFilters.from_dict(obj.get("tagFilters")) - if obj.get("tagFilters") is not None - else None - ), - "aroundLatLng": obj.get("aroundLatLng"), - "aroundRadius": ( - AroundRadius.from_dict(obj.get("aroundRadius")) - if obj.get("aroundRadius") is not None - else None - ), - "insideBoundingBox": obj.get("insideBoundingBox"), - "insidePolygon": obj.get("insidePolygon"), - } + obj["facetFilters"] = ( + FacetFilters.from_dict(obj["facetFilters"]) + if obj.get("facetFilters") is not None + else None ) - return _obj + obj["numericFilters"] = ( + NumericFilters.from_dict(obj["numericFilters"]) + if obj.get("numericFilters") is not None + else None + ) + obj["tagFilters"] = ( + TagFilters.from_dict(obj["tagFilters"]) + if obj.get("tagFilters") is not None + else None + ) + obj["aroundRadius"] = ( + AroundRadius.from_dict(obj["aroundRadius"]) + if obj.get("aroundRadius") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/delete_source_response.py b/algoliasearch/search/models/delete_source_response.py index f3444ce8a..9cade06a0 100644 --- a/algoliasearch/search/models/delete_source_response.py +++ b/algoliasearch/search/models/delete_source_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,34 @@ class DeleteSourceResponse(BaseModel): DeleteSourceResponse """ - deleted_at: StrictStr = Field( - description="Date and time when the object was deleted, in RFC 3339 format.", - alias="deletedAt", - ) + deleted_at: str = Field(alias="deletedAt") + """ Date and time when the object was deleted, in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DeleteSourceResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DeleteSourceResponse from a dict""" if obj is None: return None @@ -67,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"deletedAt": obj.get("deletedAt")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/deleted_at_response.py b/algoliasearch/search/models/deleted_at_response.py index 90f192f86..5de986f76 100644 --- a/algoliasearch/search/models/deleted_at_response.py +++ b/algoliasearch/search/models/deleted_at_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,47 +23,36 @@ class DeletedAtResponse(BaseModel): Response, taskID, and deletion timestamp. """ - task_id: StrictInt = Field( - description="Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. ", - alias="taskID", - ) - deleted_at: StrictStr = Field( - description="Date and time when the object was deleted, in RFC 3339 format.", - alias="deletedAt", - ) + task_id: int = Field(alias="taskID") + """ Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. """ + deleted_at: str = Field(alias="deletedAt") + """ Date and time when the object was deleted, in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DeletedAtResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DeletedAtResponse from a dict""" if obj is None: return None @@ -71,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"taskID": obj.get("taskID"), "deletedAt": obj.get("deletedAt")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/dictionary_action.py b/algoliasearch/search/models/dictionary_action.py index 1f64a9d2e..19412733f 100644 --- a/algoliasearch/search/models/dictionary_action.py +++ b/algoliasearch/search/models/dictionary_action.py @@ -25,6 +25,7 @@ class DictionaryAction(str, Enum): allowed enum values """ ADDENTRY = "addEntry" + DELETEENTRY = "deleteEntry" @classmethod diff --git a/algoliasearch/search/models/dictionary_entry.py b/algoliasearch/search/models/dictionary_entry.py index d234fe55a..dffa8b31b 100644 --- a/algoliasearch/search/models/dictionary_entry.py +++ b/algoliasearch/search/models/dictionary_entry.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, ClassVar, Dict, List, Optional +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,75 +28,44 @@ class DictionaryEntry(BaseModel): Dictionary entry. """ - object_id: StrictStr = Field( - description="Unique identifier for the dictionary entry.", alias="objectID" - ) - language: Optional[SupportedLanguage] = None - word: Optional[StrictStr] = Field( - default=None, - description="Matching dictionary word for `stopwords` and `compounds` dictionaries.", - ) - words: Optional[List[StrictStr]] = Field( - default=None, - description="Matching words in the `plurals` dictionary including declensions.", - ) - decomposition: Optional[List[StrictStr]] = Field( - default=None, - description="Invividual components of a compound word in the `compounds` dictionary.", - ) - state: Optional[DictionaryEntryState] = None - type: Optional[DictionaryEntryType] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = [ - "objectID", - "language", - "word", - "words", - "decomposition", - "state", - "type", - ] + object_id: str = Field(alias="objectID") + """ Unique identifier for the dictionary entry. """ + language: Optional[SupportedLanguage] = Field(default=None, alias="language") + word: Optional[str] = Field(default=None, alias="word") + """ Matching dictionary word for `stopwords` and `compounds` dictionaries. """ + words: Optional[List[str]] = Field(default=None, alias="words") + """ Matching words in the `plurals` dictionary including declensions. """ + decomposition: Optional[List[str]] = Field(default=None, alias="decomposition") + """ Invividual components of a compound word in the `compounds` dictionary. """ + state: Optional[DictionaryEntryState] = Field(default=None, alias="state") + type: Optional[DictionaryEntryType] = Field(default=None, alias="type") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + extra="allow", ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DictionaryEntry from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={ - "additional_properties", - }, exclude_none=True, exclude_unset=True, ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DictionaryEntry from a dict""" if obj is None: return None @@ -104,20 +73,8 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "objectID": obj.get("objectID"), - "language": obj.get("language"), - "word": obj.get("word"), - "words": obj.get("words"), - "decomposition": obj.get("decomposition"), - "state": obj.get("state"), - "type": obj.get("type"), - } - ) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + obj["language"] = obj.get("language") + obj["state"] = obj.get("state") + obj["type"] = obj.get("type") - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/dictionary_entry_state.py b/algoliasearch/search/models/dictionary_entry_state.py index a7b960a26..5ee2d4493 100644 --- a/algoliasearch/search/models/dictionary_entry_state.py +++ b/algoliasearch/search/models/dictionary_entry_state.py @@ -25,6 +25,7 @@ class DictionaryEntryState(str, Enum): allowed enum values """ ENABLED = "enabled" + DISABLED = "disabled" @classmethod diff --git a/algoliasearch/search/models/dictionary_entry_type.py b/algoliasearch/search/models/dictionary_entry_type.py index 10442d7b9..b4fbd8d0a 100644 --- a/algoliasearch/search/models/dictionary_entry_type.py +++ b/algoliasearch/search/models/dictionary_entry_type.py @@ -25,6 +25,7 @@ class DictionaryEntryType(str, Enum): allowed enum values """ CUSTOM = "custom" + STANDARD = "standard" @classmethod diff --git a/algoliasearch/search/models/dictionary_language.py b/algoliasearch/search/models/dictionary_language.py index 007d456e1..5d8781715 100644 --- a/algoliasearch/search/models/dictionary_language.py +++ b/algoliasearch/search/models/dictionary_language.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,44 +23,34 @@ class DictionaryLanguage(BaseModel): Dictionary type. If `null`, this dictionary type isn't supported for the language. """ - nb_custom_entries: Optional[StrictInt] = Field( - default=None, - description="Number of custom dictionary entries.", - alias="nbCustomEntries", - ) + nb_custom_entries: Optional[int] = Field(default=None, alias="nbCustomEntries") + """ Number of custom dictionary entries. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DictionaryLanguage from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DictionaryLanguage from a dict""" if obj is None: return None @@ -68,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"nbCustomEntries": obj.get("nbCustomEntries")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/dictionary_settings_params.py b/algoliasearch/search/models/dictionary_settings_params.py index 451b80f49..4e32be5e7 100644 --- a/algoliasearch/search/models/dictionary_settings_params.py +++ b/algoliasearch/search/models/dictionary_settings_params.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional from pydantic import BaseModel, ConfigDict, Field @@ -29,39 +29,30 @@ class DictionarySettingsParams(BaseModel): disable_standard_entries: StandardEntries = Field(alias="disableStandardEntries") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of DictionarySettingsParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.disable_standard_entries: - _dict["disableStandardEntries"] = self.disable_standard_entries.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of DictionarySettingsParams from a dict""" if obj is None: return None @@ -69,13 +60,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "disableStandardEntries": ( - StandardEntries.from_dict(obj.get("disableStandardEntries")) - if obj.get("disableStandardEntries") is not None - else None - ) - } + obj["disableStandardEntries"] = ( + StandardEntries.from_dict(obj["disableStandardEntries"]) + if obj.get("disableStandardEntries") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/dictionary_type.py b/algoliasearch/search/models/dictionary_type.py index f2c1624e0..6e31f61da 100644 --- a/algoliasearch/search/models/dictionary_type.py +++ b/algoliasearch/search/models/dictionary_type.py @@ -25,7 +25,9 @@ class DictionaryType(str, Enum): allowed enum values """ PLURALS = "plurals" + STOPWORDS = "stopwords" + COMPOUNDS = "compounds" @classmethod diff --git a/algoliasearch/search/models/distinct.py b/algoliasearch/search/models/distinct.py index 474461db7..fcc03353d 100644 --- a/algoliasearch/search/models/distinct.py +++ b/algoliasearch/search/models/distinct.py @@ -8,14 +8,14 @@ from json import dumps, loads from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, Field, StrictBool, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class Distinct(BaseModel): @@ -23,17 +23,12 @@ class Distinct(BaseModel): Determines how many records of a group are included in the search results. Records with the same value for the `attributeForDistinct` attribute are considered a group. The `distinct` setting controls how many members of the group are returned. This is useful for [deduplication and grouping](https://www.algolia.com/doc/guides/managing-results/refine-results/grouping/#introducing-algolias-distinct-feature). The `distinct` setting is ignored if `attributeForDistinct` is not set. """ - oneof_schema_1_validator: Optional[StrictBool] = Field( - default=None, - description="Whether deduplication is turned on. If true, only one member of a group is shown in the search results.", - ) - oneof_schema_2_validator: Optional[ - Annotated[int, Field(le=4, strict=True, ge=0)] - ] = Field( - default=0, - description="Number of members of a group of records to include in the search results. - Don't use `distinct > 1` for records that might be [promoted by rules](https://www.algolia.com/doc/guides/managing-results/rules/merchandising-and-promoting/how-to/promote-hits/). The number of hits won't be correct and faceting won't work as expected. - With `distinct > 1`, the `hitsPerPage` parameter controls the number of returned groups. For example, with `hitsPerPage: 10` and `distinct: 2`, up to 20 records are returned. Likewise, the `nbHits` response attribute contains the number of returned groups. ", - ) + oneof_schema_1_validator: Optional[bool] = Field(default=None) + """ Whether deduplication is turned on. If true, only one member of a group is shown in the search results. """ + oneof_schema_2_validator: Optional[int] = Field(default=None) + """ Number of members of a group of records to include in the search results. - Don't use `distinct > 1` for records that might be [promoted by rules](https://www.algolia.com/doc/guides/managing-results/rules/merchandising-and-promoting/how-to/promote-hits/). The number of hits won't be correct and faceting won't work as expected. - With `distinct > 1`, the `hitsPerPage` parameter controls the number of returned groups. For example, with `hitsPerPage: 10` and `distinct: 2`, up to 20 records are returned. Likewise, the `nbHits` response attribute contains the number of returned groups. """ actual_instance: Optional[Union[bool, int]] = None + one_of_schemas: Set[str] = {"bool", "int"} def __init__(self, *args, **kwargs) -> None: if args: @@ -57,7 +52,8 @@ def unwrap_actual_instance(self) -> Optional[Union[bool, int]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of Distinct from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -91,17 +87,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], bool, int]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/edit.py b/algoliasearch/search/models/edit.py index 18f70e1fb..7f0ee1a38 100644 --- a/algoliasearch/search/models/edit.py +++ b/algoliasearch/search/models/edit.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,47 +26,37 @@ class Edit(BaseModel): Edit """ - type: Optional[EditType] = None - delete: Optional[StrictStr] = Field( - default=None, description="Text or patterns to remove from the query string." - ) - insert: Optional[StrictStr] = Field( - default=None, - description="Text to be added in place of the deleted text inside the query string.", - ) + type: Optional[EditType] = Field(default=None, alias="type") + delete: Optional[str] = Field(default=None, alias="delete") + """ Text or patterns to remove from the query string. """ + insert: Optional[str] = Field(default=None, alias="insert") + """ Text to be added in place of the deleted text inside the query string. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Edit from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Edit from a dict""" if obj is None: return None @@ -74,11 +64,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "type": obj.get("type"), - "delete": obj.get("delete"), - "insert": obj.get("insert"), - } - ) - return _obj + obj["type"] = obj.get("type") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/edit_type.py b/algoliasearch/search/models/edit_type.py index 42ed72948..bee35d13e 100644 --- a/algoliasearch/search/models/edit_type.py +++ b/algoliasearch/search/models/edit_type.py @@ -25,6 +25,7 @@ class EditType(str, Enum): allowed enum values """ REMOVE = "remove" + REPLACE = "replace" @classmethod diff --git a/algoliasearch/search/models/error_base.py b/algoliasearch/search/models/error_base.py index 4317b330d..075d8a3ac 100644 --- a/algoliasearch/search/models/error_base.py +++ b/algoliasearch/search/models/error_base.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, ClassVar, Dict, List, Optional +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,50 +23,34 @@ class ErrorBase(BaseModel): Error. """ - message: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["message"] + message: Optional[str] = Field(default=None, alias="message") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + extra="allow", ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ErrorBase from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={ - "additional_properties", - }, exclude_none=True, exclude_unset=True, ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ErrorBase from a dict""" if obj is None: return None @@ -74,10 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"message": obj.get("message")}) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/exact_on_single_word_query.py b/algoliasearch/search/models/exact_on_single_word_query.py index 31b3fdfae..8eb32ce95 100644 --- a/algoliasearch/search/models/exact_on_single_word_query.py +++ b/algoliasearch/search/models/exact_on_single_word_query.py @@ -25,7 +25,9 @@ class ExactOnSingleWordQuery(str, Enum): allowed enum values """ ATTRIBUTE = "attribute" + NONE = "none" + WORD = "word" @classmethod diff --git a/algoliasearch/search/models/exhaustive.py b/algoliasearch/search/models/exhaustive.py index 008f6f857..1b7e3b403 100644 --- a/algoliasearch/search/models/exhaustive.py +++ b/algoliasearch/search/models/exhaustive.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,63 +23,42 @@ class Exhaustive(BaseModel): Whether certain properties of the search response are calculated exhaustive (exact) or approximated. """ - facets_count: Optional[StrictBool] = Field( - default=None, - description="Whether the facet count is exhaustive (`true`) or approximate (`false`). See the [related discussion](https://support.algolia.com/hc/en-us/articles/4406975248145-Why-are-my-facet-and-hit-counts-not-accurate-).", - alias="facetsCount", - ) - facet_values: Optional[StrictBool] = Field( - default=None, - description="The value is `false` if not all facet values are retrieved.", - alias="facetValues", - ) - nb_hits: Optional[StrictBool] = Field( - default=None, - description="Whether the `nbHits` is exhaustive (`true`) or approximate (`false`). When the query takes more than 50ms to be processed, the engine makes an approximation. This can happen when using complex filters on millions of records, when typo-tolerance was not exhaustive, or when enough hits have been retrieved (for example, after the engine finds 10,000 exact matches). `nbHits` is reported as non-exhaustive whenever an approximation is made, even if the approximation didn’t, in the end, impact the exhaustivity of the query.", - alias="nbHits", - ) - rules_match: Optional[StrictBool] = Field( - default=None, - description="Rules matching exhaustivity. The value is `false` if rules were enable for this query, and could not be fully processed due a timeout. This is generally caused by the number of alternatives (such as typos) which is too large.", - alias="rulesMatch", - ) - typo: Optional[StrictBool] = Field( - default=None, - description="Whether the typo search was exhaustive (`true`) or approximate (`false`). An approximation is done when the typo search query part takes more than 10% of the query budget (ie. 5ms by default) to be processed (this can happen when a lot of typo alternatives exist for the query). This field will not be included when typo-tolerance is entirely disabled.", - ) + facets_count: Optional[bool] = Field(default=None, alias="facetsCount") + """ Whether the facet count is exhaustive (`true`) or approximate (`false`). See the [related discussion](https://support.algolia.com/hc/en-us/articles/4406975248145-Why-are-my-facet-and-hit-counts-not-accurate-). """ + facet_values: Optional[bool] = Field(default=None, alias="facetValues") + """ The value is `false` if not all facet values are retrieved. """ + nb_hits: Optional[bool] = Field(default=None, alias="nbHits") + """ Whether the `nbHits` is exhaustive (`true`) or approximate (`false`). When the query takes more than 50ms to be processed, the engine makes an approximation. This can happen when using complex filters on millions of records, when typo-tolerance was not exhaustive, or when enough hits have been retrieved (for example, after the engine finds 10,000 exact matches). `nbHits` is reported as non-exhaustive whenever an approximation is made, even if the approximation didn’t, in the end, impact the exhaustivity of the query. """ + rules_match: Optional[bool] = Field(default=None, alias="rulesMatch") + """ Rules matching exhaustivity. The value is `false` if rules were enable for this query, and could not be fully processed due a timeout. This is generally caused by the number of alternatives (such as typos) which is too large. """ + typo: Optional[bool] = Field(default=None, alias="typo") + """ Whether the typo search was exhaustive (`true`) or approximate (`false`). An approximation is done when the typo search query part takes more than 10% of the query budget (ie. 5ms by default) to be processed (this can happen when a lot of typo alternatives exist for the query). This field will not be included when typo-tolerance is entirely disabled. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Exhaustive from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Exhaustive from a dict""" if obj is None: return None @@ -87,13 +66,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "facetsCount": obj.get("facetsCount"), - "facetValues": obj.get("facetValues"), - "nbHits": obj.get("nbHits"), - "rulesMatch": obj.get("rulesMatch"), - "typo": obj.get("typo"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/facet_filters.py b/algoliasearch/search/models/facet_filters.py index cd6492ec5..9669c5fb0 100644 --- a/algoliasearch/search/models/facet_filters.py +++ b/algoliasearch/search/models/facet_filters.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, StrictStr, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -23,9 +23,12 @@ class FacetFilters(BaseModel): Filter the search by facet values, so that only records with the same facet values are retrieved. **Prefer using the `filters` parameter, which supports all filter types and combinations with boolean operators.** - `[filter1, filter2]` is interpreted as `filter1 AND filter2`. - `[[filter1, filter2], filter3]` is interpreted as `filter1 OR filter2 AND filter3`. - `facet:-value` is interpreted as `NOT facet:value`. While it's best to avoid attributes that start with a `-`, you can still filter them by escaping with a backslash: `facet:\\-value`. """ - oneof_schema_1_validator: Optional[List[FacetFilters]] = None - oneof_schema_2_validator: Optional[StrictStr] = None + oneof_schema_1_validator: Optional[List[FacetFilters]] = Field(default=None) + + oneof_schema_2_validator: Optional[str] = Field(default=None) + actual_instance: Optional[Union[List[FacetFilters], str]] = None + one_of_schemas: Set[str] = {"List[FacetFilters]", "str"} def __init__(self, *args, **kwargs) -> None: if args: @@ -49,7 +52,8 @@ def unwrap_actual_instance(self) -> Optional[Union[List[FacetFilters], str]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of FacetFilters from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -83,17 +87,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], List[FacetFilters], str]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/facet_hits.py b/algoliasearch/search/models/facet_hits.py index b5dcdb0bd..3b3376e4e 100644 --- a/algoliasearch/search/models/facet_hits.py +++ b/algoliasearch/search/models/facet_hits.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,46 +23,38 @@ class FacetHits(BaseModel): FacetHits """ - value: StrictStr = Field(description="Facet value.") - highlighted: StrictStr = Field( - description="Highlighted attribute value, including HTML tags." - ) - count: StrictInt = Field( - description="Number of records with this facet value. [The count may be approximated](https://support.algolia.com/hc/en-us/articles/4406975248145-Why-are-my-facet-and-hit-counts-not-accurate-)." - ) + value: str = Field(alias="value") + """ Facet value. """ + highlighted: str = Field(alias="highlighted") + """ Highlighted attribute value, including HTML tags. """ + count: int = Field(alias="count") + """ Number of records with this facet value. [The count may be approximated](https://support.algolia.com/hc/en-us/articles/4406975248145-Why-are-my-facet-and-hit-counts-not-accurate-). """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of FacetHits from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of FacetHits from a dict""" if obj is None: return None @@ -70,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "value": obj.get("value"), - "highlighted": obj.get("highlighted"), - "count": obj.get("count"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/facet_ordering.py b/algoliasearch/search/models/facet_ordering.py index 939fb7a1b..d91597f01 100644 --- a/algoliasearch/search/models/facet_ordering.py +++ b/algoliasearch/search/models/facet_ordering.py @@ -27,51 +27,35 @@ class FacetOrdering(BaseModel): Order of facet names and facet values in your UI. """ - facets: Optional[Facets] = None - values: Optional[Dict[str, Value]] = Field( - default=None, description="Order of facet values. One object for each facet." - ) + facets: Optional[Facets] = Field(default=None, alias="facets") + values: Optional[Dict[str, Value]] = Field(default=None, alias="values") + """ Order of facet values. One object for each facet. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of FacetOrdering from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.facets: - _dict["facets"] = self.facets.to_dict() - _field_dict = {} - if self.values: - for _key in self.values: - if self.values[_key]: - _field_dict[_key] = self.values[_key].to_dict() - _dict["values"] = _field_dict - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of FacetOrdering from a dict""" if obj is None: return None @@ -79,21 +63,13 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "facets": ( - Facets.from_dict(obj.get("facets")) - if obj.get("facets") is not None - else None - ), - "values": ( - dict( - (_k, Value.from_dict(_v)) - for _k, _v in obj.get("values").items() - ) - if obj.get("values") is not None - else None - ), - } + obj["facets"] = ( + Facets.from_dict(obj["facets"]) if obj.get("facets") is not None else None ) - return _obj + obj["values"] = ( + dict((_k, Value.from_dict(_v)) for _k, _v in obj["values"].items()) + if obj.get("values") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/facet_stats.py b/algoliasearch/search/models/facet_stats.py index 2747ff786..ada778720 100644 --- a/algoliasearch/search/models/facet_stats.py +++ b/algoliasearch/search/models/facet_stats.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,51 +23,40 @@ class FacetStats(BaseModel): FacetStats """ - min: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, description="Minimum value in the results." - ) - max: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, description="Maximum value in the results." - ) - avg: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, description="Average facet value in the results." - ) - sum: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, description="Sum of all values in the results." - ) + min: Optional[float] = Field(default=None, alias="min") + """ Minimum value in the results. """ + max: Optional[float] = Field(default=None, alias="max") + """ Maximum value in the results. """ + avg: Optional[float] = Field(default=None, alias="avg") + """ Average facet value in the results. """ + sum: Optional[float] = Field(default=None, alias="sum") + """ Sum of all values in the results. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of FacetStats from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of FacetStats from a dict""" if obj is None: return None @@ -75,12 +64,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "min": obj.get("min"), - "max": obj.get("max"), - "avg": obj.get("avg"), - "sum": obj.get("sum"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/facets.py b/algoliasearch/search/models/facets.py index a284da9b6..d840e71a4 100644 --- a/algoliasearch/search/models/facets.py +++ b/algoliasearch/search/models/facets.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,34 @@ class Facets(BaseModel): Order of facet names. """ - order: Optional[List[StrictStr]] = Field( - default=None, - description="Explicit order of facets or facet values. This setting lets you always show specific facets or facet values at the top of the list. ", - ) + order: Optional[List[str]] = Field(default=None, alias="order") + """ Explicit order of facets or facet values. This setting lets you always show specific facets or facet values at the top of the list. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Facets from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Facets from a dict""" if obj is None: return None @@ -67,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"order": obj.get("order")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/fetched_index.py b/algoliasearch/search/models/fetched_index.py index a92822bdc..6437feeae 100644 --- a/algoliasearch/search/models/fetched_index.py +++ b/algoliasearch/search/models/fetched_index.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,78 +23,56 @@ class FetchedIndex(BaseModel): FetchedIndex """ - name: StrictStr = Field(description="Index name.") - created_at: StrictStr = Field( - description="Index creation date. An empty string means that the index has no records.", - alias="createdAt", - ) - updated_at: StrictStr = Field( - description="Date and time when the object was updated, in RFC 3339 format.", - alias="updatedAt", - ) - entries: StrictInt = Field(description="Number of records contained in the index.") - data_size: StrictInt = Field( - description="Number of bytes of the index in minified format.", alias="dataSize" - ) - file_size: StrictInt = Field( - description="Number of bytes of the index binary file.", alias="fileSize" - ) - last_build_time_s: StrictInt = Field( - description="Last build time.", alias="lastBuildTimeS" - ) - number_of_pending_tasks: StrictInt = Field( - description="Number of pending indexing operations. This value is deprecated and should not be used.", - alias="numberOfPendingTasks", - ) - pending_task: StrictBool = Field( - description="A boolean which says whether the index has pending tasks. This value is deprecated and should not be used.", - alias="pendingTask", - ) - primary: Optional[StrictStr] = Field( - default=None, - description="Only present if the index is a replica. Contains the name of the related primary index.", - ) - replicas: Optional[List[StrictStr]] = Field( - default=None, - description="Only present if the index is a primary index with replicas. Contains the names of all linked replicas.", - ) - virtual: Optional[StrictBool] = Field( - default=None, - description="Only present if the index is a [virtual replica](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-an-index-alphabetically/#virtual-replicas).", - ) + name: str = Field(alias="name") + """ Index name. """ + created_at: str = Field(alias="createdAt") + """ Index creation date. An empty string means that the index has no records. """ + updated_at: str = Field(alias="updatedAt") + """ Date and time when the object was updated, in RFC 3339 format. """ + entries: int = Field(alias="entries") + """ Number of records contained in the index. """ + data_size: int = Field(alias="dataSize") + """ Number of bytes of the index in minified format. """ + file_size: int = Field(alias="fileSize") + """ Number of bytes of the index binary file. """ + last_build_time_s: int = Field(alias="lastBuildTimeS") + """ Last build time. """ + number_of_pending_tasks: int = Field(alias="numberOfPendingTasks") + """ Number of pending indexing operations. This value is deprecated and should not be used. """ + pending_task: bool = Field(alias="pendingTask") + """ A boolean which says whether the index has pending tasks. This value is deprecated and should not be used. """ + primary: Optional[str] = Field(default=None, alias="primary") + """ Only present if the index is a replica. Contains the name of the related primary index. """ + replicas: Optional[List[str]] = Field(default=None, alias="replicas") + """ Only present if the index is a primary index with replicas. Contains the names of all linked replicas. """ + virtual: Optional[bool] = Field(default=None, alias="virtual") + """ Only present if the index is a [virtual replica](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-an-index-alphabetically/#virtual-replicas). """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of FetchedIndex from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of FetchedIndex from a dict""" if obj is None: return None @@ -102,20 +80,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "name": obj.get("name"), - "createdAt": obj.get("createdAt"), - "updatedAt": obj.get("updatedAt"), - "entries": obj.get("entries"), - "dataSize": obj.get("dataSize"), - "fileSize": obj.get("fileSize"), - "lastBuildTimeS": obj.get("lastBuildTimeS"), - "numberOfPendingTasks": obj.get("numberOfPendingTasks"), - "pendingTask": obj.get("pendingTask"), - "primary": obj.get("primary"), - "replicas": obj.get("replicas"), - "virtual": obj.get("virtual"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/get_api_key_response.py b/algoliasearch/search/models/get_api_key_response.py index 6112c53df..718e28e16 100644 --- a/algoliasearch/search/models/get_api_key_response.py +++ b/algoliasearch/search/models/get_api_key_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,78 +26,54 @@ class GetApiKeyResponse(BaseModel): GetApiKeyResponse """ - value: Optional[StrictStr] = Field(default=None, description="API key.") - created_at: StrictInt = Field( - description="Timestamp when the object was created, in milliseconds since the Unix epoch.", - alias="createdAt", - ) - acl: List[Acl] = Field( - description="Permissions that determine the type of API requests this key can make. The required ACL is listed in each endpoint's reference. For more information, see [access control list](https://www.algolia.com/doc/guides/security/api-keys/#access-control-list-acl). " - ) - description: Optional[StrictStr] = Field( - default="", - description="Description of an API key to help you identify this API key.", - ) - indexes: Optional[List[StrictStr]] = Field( - default=None, - description='Index names or patterns that this API key can access. By default, an API key can access all indices in the same application. You can use leading and trailing wildcard characters (`*`): - `dev_*` matches all indices starting with "dev_". - `*_dev` matches all indices ending with "_dev". - `*_products_*` matches all indices containing "_products_". ', - ) - max_hits_per_query: Optional[StrictInt] = Field( - default=0, - description="Maximum number of results this API key can retrieve in one query. By default, there's no limit. ", - alias="maxHitsPerQuery", - ) - max_queries_per_ip_per_hour: Optional[StrictInt] = Field( - default=0, - description="Maximum number of API requests allowed per IP address or [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/) per hour. If this limit is reached, the API returns an error with status code `429`. By default, there's no limit. ", - alias="maxQueriesPerIPPerHour", - ) - query_parameters: Optional[StrictStr] = Field( - default="", - description="Query parameters to add when making API requests with this API key. To restrict this API key to specific IP addresses, add the `restrictSources` parameter. You can only add a single source, but you can provide a range of IP addresses. Creating an API key fails if the request is made from an IP address that's outside the restricted range. ", - alias="queryParameters", - ) - referers: Optional[List[StrictStr]] = Field( - default=None, - description='Allowed HTTP referrers for this API key. By default, all referrers are allowed. You can use leading and trailing wildcard characters (`*`): - `https://algolia.com/*` allows all referrers starting with "https://algolia.com/" - `*.algolia.com` allows all referrers ending with ".algolia.com" - `*algolia.com*` allows all referrers in the domain "algolia.com". Like all HTTP headers, referrers can be spoofed. Don\'t rely on them to secure your data. For more information, see [HTTP referrer restrictions](https://www.algolia.com/doc/guides/security/security-best-practices/#http-referrers-restrictions). ', - ) - validity: Optional[StrictInt] = Field( - default=0, - description="Duration (in seconds) after which the API key expires. By default, API keys don't expire. ", + value: Optional[str] = Field(default=None, alias="value") + """ API key. """ + created_at: int = Field(alias="createdAt") + """ Timestamp when the object was created, in milliseconds since the Unix epoch. """ + acl: List[Acl] = Field(alias="acl") + """ Permissions that determine the type of API requests this key can make. The required ACL is listed in each endpoint's reference. For more information, see [access control list](https://www.algolia.com/doc/guides/security/api-keys/#access-control-list-acl). """ + description: Optional[str] = Field(default=None, alias="description") + """ Description of an API key to help you identify this API key. """ + indexes: Optional[List[str]] = Field(default=None, alias="indexes") + """ Index names or patterns that this API key can access. By default, an API key can access all indices in the same application. You can use leading and trailing wildcard characters (`*`): - `dev_*` matches all indices starting with \"dev_\". - `*_dev` matches all indices ending with \"_dev\". - `*_products_*` matches all indices containing \"_products_\". """ + max_hits_per_query: Optional[int] = Field(default=None, alias="maxHitsPerQuery") + """ Maximum number of results this API key can retrieve in one query. By default, there's no limit. """ + max_queries_per_ip_per_hour: Optional[int] = Field( + default=None, alias="maxQueriesPerIPPerHour" ) + """ Maximum number of API requests allowed per IP address or [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/) per hour. If this limit is reached, the API returns an error with status code `429`. By default, there's no limit. """ + query_parameters: Optional[str] = Field(default=None, alias="queryParameters") + """ Query parameters to add when making API requests with this API key. To restrict this API key to specific IP addresses, add the `restrictSources` parameter. You can only add a single source, but you can provide a range of IP addresses. Creating an API key fails if the request is made from an IP address that's outside the restricted range. """ + referers: Optional[List[str]] = Field(default=None, alias="referers") + """ Allowed HTTP referrers for this API key. By default, all referrers are allowed. You can use leading and trailing wildcard characters (`*`): - `https://algolia.com/*` allows all referrers starting with \"https://algolia.com/\" - `*.algolia.com` allows all referrers ending with \".algolia.com\" - `*algolia.com*` allows all referrers in the domain \"algolia.com\". Like all HTTP headers, referrers can be spoofed. Don't rely on them to secure your data. For more information, see [HTTP referrer restrictions](https://www.algolia.com/doc/guides/security/security-best-practices/#http-referrers-restrictions). """ + validity: Optional[int] = Field(default=None, alias="validity") + """ Duration (in seconds) after which the API key expires. By default, API keys don't expire. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetApiKeyResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetApiKeyResponse from a dict""" if obj is None: return None @@ -105,18 +81,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "value": obj.get("value"), - "createdAt": obj.get("createdAt"), - "acl": obj.get("acl"), - "description": obj.get("description"), - "indexes": obj.get("indexes"), - "maxHitsPerQuery": obj.get("maxHitsPerQuery"), - "maxQueriesPerIPPerHour": obj.get("maxQueriesPerIPPerHour"), - "queryParameters": obj.get("queryParameters"), - "referers": obj.get("referers"), - "validity": obj.get("validity"), - } - ) - return _obj + obj["acl"] = obj.get("acl") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/get_dictionary_settings_response.py b/algoliasearch/search/models/get_dictionary_settings_response.py index 68bbd9ef7..be6e9eda6 100644 --- a/algoliasearch/search/models/get_dictionary_settings_response.py +++ b/algoliasearch/search/models/get_dictionary_settings_response.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional from pydantic import BaseModel, ConfigDict, Field @@ -29,39 +29,30 @@ class GetDictionarySettingsResponse(BaseModel): disable_standard_entries: StandardEntries = Field(alias="disableStandardEntries") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetDictionarySettingsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.disable_standard_entries: - _dict["disableStandardEntries"] = self.disable_standard_entries.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetDictionarySettingsResponse from a dict""" if obj is None: return None @@ -69,13 +60,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "disableStandardEntries": ( - StandardEntries.from_dict(obj.get("disableStandardEntries")) - if obj.get("disableStandardEntries") is not None - else None - ) - } + obj["disableStandardEntries"] = ( + StandardEntries.from_dict(obj["disableStandardEntries"]) + if obj.get("disableStandardEntries") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/get_logs_response.py b/algoliasearch/search/models/get_logs_response.py index 1adab9845..5be352272 100644 --- a/algoliasearch/search/models/get_logs_response.py +++ b/algoliasearch/search/models/get_logs_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,46 +26,33 @@ class GetLogsResponse(BaseModel): GetLogsResponse """ - logs: List[Log] + logs: List[Log] = Field(alias="logs") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetLogsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.logs: - for _item in self.logs: - if _item: - _items.append(_item.to_dict()) - _dict["logs"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetLogsResponse from a dict""" if obj is None: return None @@ -73,13 +60,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "logs": ( - [Log.from_dict(_item) for _item in obj.get("logs")] - if obj.get("logs") is not None - else None - ) - } + obj["logs"] = ( + [Log.from_dict(_item) for _item in obj["logs"]] + if obj.get("logs") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/get_objects_params.py b/algoliasearch/search/models/get_objects_params.py index 0527b3945..ad5fffd29 100644 --- a/algoliasearch/search/models/get_objects_params.py +++ b/algoliasearch/search/models/get_objects_params.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,46 +26,33 @@ class GetObjectsParams(BaseModel): Request parameters. """ - requests: List[GetObjectsRequest] + requests: List[GetObjectsRequest] = Field(alias="requests") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetObjectsParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.requests: - for _item in self.requests: - if _item: - _items.append(_item.to_dict()) - _dict["requests"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetObjectsParams from a dict""" if obj is None: return None @@ -73,16 +60,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "requests": ( - [ - GetObjectsRequest.from_dict(_item) - for _item in obj.get("requests") - ] - if obj.get("requests") is not None - else None - ) - } + obj["requests"] = ( + [GetObjectsRequest.from_dict(_item) for _item in obj["requests"]] + if obj.get("requests") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/get_objects_request.py b/algoliasearch/search/models/get_objects_request.py index 5d010038b..a29204355 100644 --- a/algoliasearch/search/models/get_objects_request.py +++ b/algoliasearch/search/models/get_objects_request.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,50 +23,40 @@ class GetObjectsRequest(BaseModel): Request body for retrieving records. """ - attributes_to_retrieve: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes to retrieve. If not specified, all retrievable attributes are returned. ", - alias="attributesToRetrieve", - ) - object_id: StrictStr = Field( - description="Object ID for the record to retrieve.", alias="objectID" - ) - index_name: StrictStr = Field( - description="Index from which to retrieve the records.", alias="indexName" + attributes_to_retrieve: Optional[List[str]] = Field( + default=None, alias="attributesToRetrieve" ) + """ Attributes to retrieve. If not specified, all retrievable attributes are returned. """ + object_id: str = Field(alias="objectID") + """ Object ID for the record to retrieve. """ + index_name: str = Field(alias="indexName") + """ Index from which to retrieve the records. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetObjectsRequest from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetObjectsRequest from a dict""" if obj is None: return None @@ -74,11 +64,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "attributesToRetrieve": obj.get("attributesToRetrieve"), - "objectID": obj.get("objectID"), - "indexName": obj.get("indexName"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/get_objects_response.py b/algoliasearch/search/models/get_objects_response.py index 6e55f54f9..8b1af4379 100644 --- a/algoliasearch/search/models/get_objects_response.py +++ b/algoliasearch/search/models/get_objects_response.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -23,40 +23,34 @@ class GetObjectsResponse(BaseModel): GetObjectsResponse """ - results: List[Dict[str, Any]] = Field(description="Retrieved records.") + results: List[object] = Field(alias="results") + """ Retrieved records. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetObjectsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetObjectsResponse from a dict""" if obj is None: return None @@ -64,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"results": obj.get("results")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/get_task_response.py b/algoliasearch/search/models/get_task_response.py index 900cb2007..74dee9eec 100644 --- a/algoliasearch/search/models/get_task_response.py +++ b/algoliasearch/search/models/get_task_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,40 +26,33 @@ class GetTaskResponse(BaseModel): GetTaskResponse """ - status: TaskStatus + status: TaskStatus = Field(alias="status") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetTaskResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetTaskResponse from a dict""" if obj is None: return None @@ -67,5 +60,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"status": obj.get("status")}) - return _obj + obj["status"] = obj.get("status") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/get_top_user_ids_response.py b/algoliasearch/search/models/get_top_user_ids_response.py index 5f6822952..99938960d 100644 --- a/algoliasearch/search/models/get_top_user_ids_response.py +++ b/algoliasearch/search/models/get_top_user_ids_response.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -26,43 +26,34 @@ class GetTopUserIdsResponse(BaseModel): User IDs and clusters. """ - top_users: List[Dict[str, List[UserId]]] = Field( - description="Key-value pairs with cluster names as keys and lists of users with the highest number of records per cluster as values.", - alias="topUsers", - ) + top_users: List[Dict[str, List[UserId]]] = Field(alias="topUsers") + """ Key-value pairs with cluster names as keys and lists of users with the highest number of records per cluster as values. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of GetTopUserIdsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of GetTopUserIdsResponse from a dict""" if obj is None: return None @@ -70,5 +61,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"topUsers": obj.get("topUsers")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/has_pending_mappings_response.py b/algoliasearch/search/models/has_pending_mappings_response.py index 0507e12d1..6720e0577 100644 --- a/algoliasearch/search/models/has_pending_mappings_response.py +++ b/algoliasearch/search/models/has_pending_mappings_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,46 +23,36 @@ class HasPendingMappingsResponse(BaseModel): HasPendingMappingsResponse """ - pending: StrictBool = Field( - description="Whether there are clusters undergoing migration, creation, or deletion." - ) - clusters: Optional[Dict[str, List[StrictStr]]] = Field( - default=None, - description="Cluster pending mapping state: migrating, creating, deleting. ", - ) + pending: bool = Field(alias="pending") + """ Whether there are clusters undergoing migration, creation, or deletion. """ + clusters: Optional[Dict[str, List[str]]] = Field(default=None, alias="clusters") + """ Cluster pending mapping state: migrating, creating, deleting. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of HasPendingMappingsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of HasPendingMappingsResponse from a dict""" if obj is None: return None @@ -70,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"pending": obj.get("pending"), "clusters": obj.get("clusters")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/highlight_result.py b/algoliasearch/search/models/highlight_result.py index d12d561c9..a41cb3e20 100644 --- a/algoliasearch/search/models/highlight_result.py +++ b/algoliasearch/search/models/highlight_result.py @@ -8,7 +8,7 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union from pydantic import BaseModel, Field, ValidationError, model_serializer @@ -26,18 +26,20 @@ class HighlightResult(BaseModel): HighlightResult """ - oneof_schema_1_validator: Optional[HighlightResultOption] = None - oneof_schema_2_validator: Optional[Dict[str, HighlightResult]] = Field( - default=None, - description="Surround words that match the query with HTML tags for highlighting.", - ) - oneof_schema_3_validator: Optional[List[HighlightResult]] = Field( - default=None, - description="Surround words that match the query with HTML tags for highlighting.", - ) + oneof_schema_1_validator: Optional[HighlightResultOption] = Field(default=None) + + oneof_schema_2_validator: Optional[Dict[str, HighlightResult]] = Field(default=None) + """ Surround words that match the query with HTML tags for highlighting. """ + oneof_schema_3_validator: Optional[List[HighlightResult]] = Field(default=None) + """ Surround words that match the query with HTML tags for highlighting. """ actual_instance: Optional[ Union[Dict[str, HighlightResult], HighlightResultOption, List[HighlightResult]] ] = None + one_of_schemas: Set[str] = { + "Dict[str, HighlightResult]", + "HighlightResultOption", + "List[HighlightResult]", + } def __init__(self, *args, **kwargs) -> None: if args: @@ -65,7 +67,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of HighlightResult from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -105,17 +108,30 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[ + Union[ + Dict[str, Any], + Dict[str, HighlightResult], + HighlightResultOption, + List[HighlightResult], + ] + ]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/highlight_result_option.py b/algoliasearch/search/models/highlight_result_option.py index 32e833ede..d36432b4f 100644 --- a/algoliasearch/search/models/highlight_result_option.py +++ b/algoliasearch/search/models/highlight_result_option.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,51 +26,39 @@ class HighlightResultOption(BaseModel): Surround words that match the query with HTML tags for highlighting. """ - value: StrictStr = Field( - description="Highlighted attribute value, including HTML tags." - ) + value: str = Field(alias="value") + """ Highlighted attribute value, including HTML tags. """ match_level: MatchLevel = Field(alias="matchLevel") - matched_words: List[StrictStr] = Field( - description="List of matched words from the search query.", alias="matchedWords" - ) - fully_highlighted: Optional[StrictBool] = Field( - default=None, - description="Whether the entire attribute value is highlighted.", - alias="fullyHighlighted", - ) + matched_words: List[str] = Field(alias="matchedWords") + """ List of matched words from the search query. """ + fully_highlighted: Optional[bool] = Field(default=None, alias="fullyHighlighted") + """ Whether the entire attribute value is highlighted. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of HighlightResultOption from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of HighlightResultOption from a dict""" if obj is None: return None @@ -78,12 +66,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "value": obj.get("value"), - "matchLevel": obj.get("matchLevel"), - "matchedWords": obj.get("matchedWords"), - "fullyHighlighted": obj.get("fullyHighlighted"), - } - ) - return _obj + obj["matchLevel"] = obj.get("matchLevel") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/hit.py b/algoliasearch/search/models/hit.py index c11ddda31..d2e725e56 100644 --- a/algoliasearch/search/models/hit.py +++ b/algoliasearch/search/models/hit.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, ClassVar, Dict, List, Optional +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,84 +28,45 @@ class Hit(BaseModel): Search result. A hit is a record from your index, augmented with special attributes for highlighting, snippeting, and ranking. """ - object_id: StrictStr = Field( - description="Unique record identifier.", alias="objectID" - ) + object_id: str = Field(alias="objectID") + """ Unique record identifier. """ highlight_result: Optional[Dict[str, HighlightResult]] = Field( - default=None, - description="Surround words that match the query with HTML tags for highlighting.", - alias="_highlightResult", + default=None, alias="_highlightResult" ) + """ Surround words that match the query with HTML tags for highlighting. """ snippet_result: Optional[Dict[str, SnippetResult]] = Field( - default=None, - description="Snippets that show the context around a matching search query.", - alias="_snippetResult", + default=None, alias="_snippetResult" ) + """ Snippets that show the context around a matching search query. """ ranking_info: Optional[RankingInfo] = Field(default=None, alias="_rankingInfo") - distinct_seq_id: Optional[StrictInt] = Field(default=None, alias="_distinctSeqID") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = [ - "objectID", - "_highlightResult", - "_snippetResult", - "_rankingInfo", - "_distinctSeqID", - ] + distinct_seq_id: Optional[int] = Field(default=None, alias="_distinctSeqID") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + extra="allow", ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Hit from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={ - "additional_properties", - }, exclude_none=True, exclude_unset=True, ) - _field_dict = {} - if self.highlight_result: - for _key in self.highlight_result: - if self.highlight_result[_key]: - _field_dict[_key] = self.highlight_result[_key].to_dict() - _dict["_highlightResult"] = _field_dict - _field_dict = {} - if self.snippet_result: - for _key in self.snippet_result: - if self.snippet_result[_key]: - _field_dict[_key] = self.snippet_result[_key].to_dict() - _dict["_snippetResult"] = _field_dict - if self.ranking_info: - _dict["_rankingInfo"] = self.ranking_info.to_dict() - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Hit from a dict""" if obj is None: return None @@ -113,36 +74,26 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "objectID": obj.get("objectID"), - "_highlightResult": ( - dict( - (_k, HighlightResult.from_dict(_v)) - for _k, _v in obj.get("_highlightResult").items() - ) - if obj.get("_highlightResult") is not None - else None - ), - "_snippetResult": ( - dict( - (_k, SnippetResult.from_dict(_v)) - for _k, _v in obj.get("_snippetResult").items() - ) - if obj.get("_snippetResult") is not None - else None - ), - "_rankingInfo": ( - RankingInfo.from_dict(obj.get("_rankingInfo")) - if obj.get("_rankingInfo") is not None - else None - ), - "_distinctSeqID": obj.get("_distinctSeqID"), - } + obj["_highlightResult"] = ( + dict( + (_k, HighlightResult.from_dict(_v)) + for _k, _v in obj["_highlightResult"].items() + ) + if obj.get("_highlightResult") is not None + else None + ) + obj["_snippetResult"] = ( + dict( + (_k, SnippetResult.from_dict(_v)) + for _k, _v in obj["_snippetResult"].items() + ) + if obj.get("_snippetResult") is not None + else None + ) + obj["_rankingInfo"] = ( + RankingInfo.from_dict(obj["_rankingInfo"]) + if obj.get("_rankingInfo") is not None + else None ) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/ignore_plurals.py b/algoliasearch/search/models/ignore_plurals.py index 0af25aeb1..3076c80ea 100644 --- a/algoliasearch/search/models/ignore_plurals.py +++ b/algoliasearch/search/models/ignore_plurals.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, Field, StrictBool, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -27,18 +27,16 @@ class IgnorePlurals(BaseModel): Treat singular, plurals, and other forms of declensions as equivalent. You should only use this feature for the languages used in your index. """ - oneof_schema_1_validator: Optional[List[SupportedLanguage]] = Field( - default=None, - description="ISO code for languages for which this feature should be active. This overrides languages you set with `queryLanguages`. ", - ) - oneof_schema_2_validator: Optional[BooleanString] = None - oneof_schema_3_validator: Optional[StrictBool] = Field( - default=False, - description="If true, `ignorePlurals` is active for all languages included in `queryLanguages`, or for all supported languages, if `queryLanguges` is empty. If false, singulars, plurals, and other declensions won't be considered equivalent. ", - ) + oneof_schema_1_validator: Optional[List[SupportedLanguage]] = Field(default=None) + """ ISO code for languages for which this feature should be active. This overrides languages you set with `queryLanguages`. """ + oneof_schema_2_validator: Optional[BooleanString] = Field(default=None) + + oneof_schema_3_validator: Optional[bool] = Field(default=None) + """ If true, `ignorePlurals` is active for all languages included in `queryLanguages`, or for all supported languages, if `queryLanguges` is empty. If false, singulars, plurals, and other declensions won't be considered equivalent. """ actual_instance: Optional[Union[BooleanString, List[SupportedLanguage], bool]] = ( None ) + one_of_schemas: Set[str] = {"BooleanString", "List[SupportedLanguage]", "bool"} def __init__(self, *args, **kwargs) -> None: if args: @@ -64,7 +62,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of IgnorePlurals from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -104,17 +103,23 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[Union[Dict[str, Any], BooleanString, List[SupportedLanguage], bool]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/index_settings.py b/algoliasearch/search/models/index_settings.py index 08d4bf4fe..777956056 100644 --- a/algoliasearch/search/models/index_settings.py +++ b/algoliasearch/search/models/index_settings.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.advanced_syntax_features import AdvancedSyntaxFeatures @@ -43,322 +43,219 @@ class IndexSettings(BaseModel): Index settings. """ - attributes_for_faceting: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes used for [faceting](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/). Facets are attributes that let you categorize search results. They can be used for filtering search results. By default, no attribute is used for faceting. Attribute names are case-sensitive. **Modifiers** - `filterOnly("ATTRIBUTE")`. Allows using this attribute as a filter, but doesn\'t evalue the facet values. - `searchable("ATTRIBUTE")`. Allows searching for facet values. - `afterDistinct("ATTRIBUTE")`. Evaluates the facet count _after_ deduplication with `distinct`. This ensures accurate facet counts. You can apply this modifier to searchable facets: `afterDistinct(searchable(ATTRIBUTE))`. ', - alias="attributesForFaceting", - ) - replicas: Optional[List[StrictStr]] = Field( - default=None, - description="Creates [replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/). Replicas are copies of a primary index with the same records but different settings, synonyms, or rules. If you want to offer a different ranking or sorting of your search results, you'll use replica indices. All index operations on a primary index are automatically forwarded to its replicas. To add a replica index, you must provide the complete set of replicas to this parameter. If you omit a replica from this list, the replica turns into a regular, standalone index that will no longer by synced with the primary index. **Modifier** - `virtual(\"REPLICA\")`. Create a virtual replica, Virtual replicas don't increase the number of records and are optimized for [Relevant sorting](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/relevant-sort/). ", - ) - pagination_limited_to: Optional[Annotated[int, Field(le=20000, strict=True)]] = ( - Field( - default=1000, - description="Maximum number of search results that can be obtained through pagination. Higher pagination limits might slow down your search. For pagination limits above 1,000, the sorting of results beyond the 1,000th hit can't be guaranteed. ", - alias="paginationLimitedTo", - ) + attributes_for_faceting: Optional[List[str]] = Field( + default=None, alias="attributesForFaceting" ) - unretrievable_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes that can't be retrieved at query time. This can be useful if you want to use an attribute for ranking or to [restrict access](https://www.algolia.com/doc/guides/security/api-keys/how-to/user-restricted-access-to-data/), but don't want to include it in the search results. Attribute names are case-sensitive. ", - alias="unretrievableAttributes", + """ Attributes used for [faceting](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/). Facets are attributes that let you categorize search results. They can be used for filtering search results. By default, no attribute is used for faceting. Attribute names are case-sensitive. **Modifiers** - `filterOnly(\"ATTRIBUTE\")`. Allows using this attribute as a filter, but doesn't evalue the facet values. - `searchable(\"ATTRIBUTE\")`. Allows searching for facet values. - `afterDistinct(\"ATTRIBUTE\")`. Evaluates the facet count _after_ deduplication with `distinct`. This ensures accurate facet counts. You can apply this modifier to searchable facets: `afterDistinct(searchable(ATTRIBUTE))`. """ + replicas: Optional[List[str]] = Field(default=None, alias="replicas") + """ Creates [replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/). Replicas are copies of a primary index with the same records but different settings, synonyms, or rules. If you want to offer a different ranking or sorting of your search results, you'll use replica indices. All index operations on a primary index are automatically forwarded to its replicas. To add a replica index, you must provide the complete set of replicas to this parameter. If you omit a replica from this list, the replica turns into a regular, standalone index that will no longer by synced with the primary index. **Modifier** - `virtual(\"REPLICA\")`. Create a virtual replica, Virtual replicas don't increase the number of records and are optimized for [Relevant sorting](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/relevant-sort/). """ + pagination_limited_to: Optional[int] = Field( + default=None, alias="paginationLimitedTo" ) - disable_typo_tolerance_on_words: Optional[List[StrictStr]] = Field( - default=None, - description="Words for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). This also turns off [word splitting and concatenation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/splitting-and-concatenation/) for the specified words. ", - alias="disableTypoToleranceOnWords", + """ Maximum number of search results that can be obtained through pagination. Higher pagination limits might slow down your search. For pagination limits above 1,000, the sorting of results beyond the 1,000th hit can't be guaranteed. """ + unretrievable_attributes: Optional[List[str]] = Field( + default=None, alias="unretrievableAttributes" ) - attributes_to_transliterate: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes, for which you want to support [Japanese transliteration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#japanese-transliteration-and-type-ahead). Transliteration supports searching in any of the Japanese writing systems. To support transliteration, you must set the indexing language to Japanese. Attribute names are case-sensitive. ", - alias="attributesToTransliterate", + """ Attributes that can't be retrieved at query time. This can be useful if you want to use an attribute for ranking or to [restrict access](https://www.algolia.com/doc/guides/security/api-keys/how-to/user-restricted-access-to-data/), but don't want to include it in the search results. Attribute names are case-sensitive. """ + disable_typo_tolerance_on_words: Optional[List[str]] = Field( + default=None, alias="disableTypoToleranceOnWords" ) - camel_case_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which to split [camel case](https://wikipedia.org/wiki/Camel_case) words. Attribute names are case-sensitive. ", - alias="camelCaseAttributes", + """ Words for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). This also turns off [word splitting and concatenation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/splitting-and-concatenation/) for the specified words. """ + attributes_to_transliterate: Optional[List[str]] = Field( + default=None, alias="attributesToTransliterate" ) - decompounded_attributes: Optional[Dict[str, Any]] = Field( - default=None, - description="Searchable attributes to which Algolia should apply [word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-segmentation/) (decompounding). Attribute names are case-sensitive. Compound words are formed by combining two or more individual words, and are particularly prevalent in Germanic languages—for example, \"firefighter\". With decompounding, the individual components are indexed separately. You can specify different lists for different languages. Decompounding is supported for these languages: Dutch (`nl`), German (`de`), Finnish (`fi`), Danish (`da`), Swedish (`sv`), and Norwegian (`no`). Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). ", - alias="decompoundedAttributes", + """ Attributes, for which you want to support [Japanese transliteration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#japanese-transliteration-and-type-ahead). Transliteration supports searching in any of the Japanese writing systems. To support transliteration, you must set the indexing language to Japanese. Attribute names are case-sensitive. """ + camel_case_attributes: Optional[List[str]] = Field( + default=None, alias="camelCaseAttributes" ) - index_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="Languages for language-specific processing steps, such as word detection and dictionary settings. **You should always specify an indexing language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). ", - alias="indexLanguages", - ) - disable_prefix_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Searchable attributes for which you want to turn off [prefix matching](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/#adjusting-prefix-search). Attribute names are case-sensitive. ", - alias="disablePrefixOnAttributes", - ) - allow_compression_of_integer_array: Optional[StrictBool] = Field( - default=False, - description="Whether arrays with exclusively non-negative integers should be compressed for better performance. If true, the compressed arrays may be reordered. ", - alias="allowCompressionOfIntegerArray", - ) - numeric_attributes_for_filtering: Optional[List[StrictStr]] = Field( - default=None, - description='Numeric attributes that can be used as [numerical filters](https://www.algolia.com/doc/guides/managing-results/rules/detecting-intent/how-to/applying-a-custom-filter-for-a-specific-query/#numerical-filters). Attribute names are case-sensitive. By default, all numeric attributes are available as numerical filters. For faster indexing, reduce the number of numeric attributes. If you want to turn off filtering for all numeric attributes, specifiy an attribute that doesn\'t exist in your index, such as `NO_NUMERIC_FILTERING`. **Modifier** - `equalOnly("ATTRIBUTE")`. Support only filtering based on equality comparisons `=` and `!=`. ', - alias="numericAttributesForFiltering", - ) - separators_to_index: Optional[StrictStr] = Field( - default="", - description="Controls which separators are indexed. Separators are all non-letter characters except spaces and currency characters, such as $€£¥. By default, separator characters aren't indexed. With `separatorsToIndex`, Algolia treats separator characters as separate words. For example, a search for `C#` would report two matches. ", - alias="separatorsToIndex", - ) - searchable_attributes: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes used for searching. Attribute names are case-sensitive. By default, all attributes are searchable and the [Attribute](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#attribute) ranking criterion is turned off. With a non-empty list, Algolia only returns results with matches in the selected attributes. In addition, the Attribute ranking criterion is turned on: matches in attributes that are higher in the list of `searchableAttributes` rank first. To make matches in two attributes rank equally, include them in a comma-separated string, such as `"title,alternate_title"`. Attributes with the same priority are always unordered. For more information, see [Searchable attributes](https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/how-to/setting-searchable-attributes/). **Modifier** - `unordered("ATTRIBUTE")`. Ignore the position of a match within the attribute. Without modifier, matches at the beginning of an attribute rank higer than matches at the end. ', - alias="searchableAttributes", - ) - user_data: Optional[Dict[str, Any]] = Field( - default=None, - description="An object with custom data. You can store up to 32kB as custom data. ", - alias="userData", - ) - custom_normalization: Optional[Dict[str, Dict[str, StrictStr]]] = Field( - default=None, - description="Characters and their normalized replacements. This overrides Algolia's default [normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/). ", - alias="customNormalization", - ) - attribute_for_distinct: Optional[StrictStr] = Field( - default=None, - description="Attribute that should be used to establish groups of results. Attribute names are case-sensitive. All records with the same value for this attribute are considered a group. You can combine `attributeForDistinct` with the `distinct` search parameter to control how many items per group are included in the search results. If you want to use the same attribute also for faceting, use the `afterDistinct` modifier of the `attributesForFaceting` setting. This applies faceting _after_ deduplication, which will result in accurate facet counts. ", - alias="attributeForDistinct", - ) - attributes_to_retrieve: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `["*", "-ATTRIBUTE"]`. - The `objectID` attribute is always included. ', - alias="attributesToRetrieve", - ) - ranking: Optional[List[StrictStr]] = Field( - default=None, - description='Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they\'re specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc("ATTRIBUTE")`. Sort the index by the values of an attribute, in ascending order. - `desc("ATTRIBUTE")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). ', - ) - custom_ranking: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes to use as [custom ranking](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/). Attribute names are case-sensitive. The custom ranking attributes decide which items are shown first if the other ranking criteria are equal. Records with missing values for your selected custom ranking attributes are always sorted last. Boolean attributes are sorted based on their alphabetical order. **Modifiers** - `asc("ATTRIBUTE")`. Sort the index by the values of an attribute, in ascending order. - `desc("ATTRIBUTE")`. Sort the index by the values of an attribute, in descending order. If you use two or more custom ranking attributes, [reduce the precision](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/how-to/controlling-custom-ranking-metrics-precision/) of your first attributes, or the other attributes will never be applied. ', - alias="customRanking", - ) - relevancy_strictness: Optional[StrictInt] = Field( - default=100, - description="Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. ", - alias="relevancyStrictness", - ) - attributes_to_highlight: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). ", - alias="attributesToHighlight", - ) - attributes_to_snippet: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. ", - alias="attributesToSnippet", - ) - highlight_pre_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert before the highlighted parts in all highlighted results and snippets.", - alias="highlightPreTag", - ) - highlight_post_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert after the highlighted parts in all highlighted results and snippets.", - alias="highlightPostTag", - ) - snippet_ellipsis_text: Optional[StrictStr] = Field( - default="…", - description="String used as an ellipsis indicator when a snippet is truncated.", - alias="snippetEllipsisText", - ) - restrict_highlight_and_snippet_arrays: Optional[StrictBool] = Field( - default=False, - description="Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. ", - alias="restrictHighlightAndSnippetArrays", - ) - hits_per_page: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = Field( - default=20, description="Number of hits per page.", alias="hitsPerPage" - ) - min_word_sizefor1_typo: Optional[StrictInt] = Field( - default=4, - description="Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor1Typo", - ) - min_word_sizefor2_typos: Optional[StrictInt] = Field( - default=8, - description="Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor2Typos", + """ Attributes for which to split [camel case](https://wikipedia.org/wiki/Camel_case) words. Attribute names are case-sensitive. """ + decompounded_attributes: Optional[object] = Field( + default=None, alias="decompoundedAttributes" ) + """ Searchable attributes to which Algolia should apply [word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-segmentation/) (decompounding). Attribute names are case-sensitive. Compound words are formed by combining two or more individual words, and are particularly prevalent in Germanic languages—for example, \"firefighter\". With decompounding, the individual components are indexed separately. You can specify different lists for different languages. Decompounding is supported for these languages: Dutch (`nl`), German (`de`), Finnish (`fi`), Danish (`da`), Swedish (`sv`), and Norwegian (`no`). Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). """ + index_languages: Optional[List[SupportedLanguage]] = Field( + default=None, alias="indexLanguages" + ) + """ Languages for language-specific processing steps, such as word detection and dictionary settings. **You should always specify an indexing language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). """ + disable_prefix_on_attributes: Optional[List[str]] = Field( + default=None, alias="disablePrefixOnAttributes" + ) + """ Searchable attributes for which you want to turn off [prefix matching](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/#adjusting-prefix-search). Attribute names are case-sensitive. """ + allow_compression_of_integer_array: Optional[bool] = Field( + default=None, alias="allowCompressionOfIntegerArray" + ) + """ Whether arrays with exclusively non-negative integers should be compressed for better performance. If true, the compressed arrays may be reordered. """ + numeric_attributes_for_filtering: Optional[List[str]] = Field( + default=None, alias="numericAttributesForFiltering" + ) + """ Numeric attributes that can be used as [numerical filters](https://www.algolia.com/doc/guides/managing-results/rules/detecting-intent/how-to/applying-a-custom-filter-for-a-specific-query/#numerical-filters). Attribute names are case-sensitive. By default, all numeric attributes are available as numerical filters. For faster indexing, reduce the number of numeric attributes. If you want to turn off filtering for all numeric attributes, specifiy an attribute that doesn't exist in your index, such as `NO_NUMERIC_FILTERING`. **Modifier** - `equalOnly(\"ATTRIBUTE\")`. Support only filtering based on equality comparisons `=` and `!=`. """ + separators_to_index: Optional[str] = Field(default=None, alias="separatorsToIndex") + """ Controls which separators are indexed. Separators are all non-letter characters except spaces and currency characters, such as $€£¥. By default, separator characters aren't indexed. With `separatorsToIndex`, Algolia treats separator characters as separate words. For example, a search for `C#` would report two matches. """ + searchable_attributes: Optional[List[str]] = Field( + default=None, alias="searchableAttributes" + ) + """ Attributes used for searching. Attribute names are case-sensitive. By default, all attributes are searchable and the [Attribute](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#attribute) ranking criterion is turned off. With a non-empty list, Algolia only returns results with matches in the selected attributes. In addition, the Attribute ranking criterion is turned on: matches in attributes that are higher in the list of `searchableAttributes` rank first. To make matches in two attributes rank equally, include them in a comma-separated string, such as `\"title,alternate_title\"`. Attributes with the same priority are always unordered. For more information, see [Searchable attributes](https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/how-to/setting-searchable-attributes/). **Modifier** - `unordered(\"ATTRIBUTE\")`. Ignore the position of a match within the attribute. Without modifier, matches at the beginning of an attribute rank higer than matches at the end. """ + user_data: Optional[object] = Field(default=None, alias="userData") + """ An object with custom data. You can store up to 32kB as custom data. """ + custom_normalization: Optional[Dict[str, Dict[str, str]]] = Field( + default=None, alias="customNormalization" + ) + """ Characters and their normalized replacements. This overrides Algolia's default [normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/). """ + attribute_for_distinct: Optional[str] = Field( + default=None, alias="attributeForDistinct" + ) + """ Attribute that should be used to establish groups of results. Attribute names are case-sensitive. All records with the same value for this attribute are considered a group. You can combine `attributeForDistinct` with the `distinct` search parameter to control how many items per group are included in the search results. If you want to use the same attribute also for faceting, use the `afterDistinct` modifier of the `attributesForFaceting` setting. This applies faceting _after_ deduplication, which will result in accurate facet counts. """ + attributes_to_retrieve: Optional[List[str]] = Field( + default=None, alias="attributesToRetrieve" + ) + """ Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `[\"*\", \"-ATTRIBUTE\"]`. - The `objectID` attribute is always included. """ + ranking: Optional[List[str]] = Field(default=None, alias="ranking") + """ Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they're specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in ascending order. - `desc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). """ + custom_ranking: Optional[List[str]] = Field(default=None, alias="customRanking") + """ Attributes to use as [custom ranking](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/). Attribute names are case-sensitive. The custom ranking attributes decide which items are shown first if the other ranking criteria are equal. Records with missing values for your selected custom ranking attributes are always sorted last. Boolean attributes are sorted based on their alphabetical order. **Modifiers** - `asc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in ascending order. - `desc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in descending order. If you use two or more custom ranking attributes, [reduce the precision](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/how-to/controlling-custom-ranking-metrics-precision/) of your first attributes, or the other attributes will never be applied. """ + relevancy_strictness: Optional[int] = Field( + default=None, alias="relevancyStrictness" + ) + """ Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. """ + attributes_to_highlight: Optional[List[str]] = Field( + default=None, alias="attributesToHighlight" + ) + """ Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). """ + attributes_to_snippet: Optional[List[str]] = Field( + default=None, alias="attributesToSnippet" + ) + """ Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. """ + highlight_pre_tag: Optional[str] = Field(default=None, alias="highlightPreTag") + """ HTML tag to insert before the highlighted parts in all highlighted results and snippets. """ + highlight_post_tag: Optional[str] = Field(default=None, alias="highlightPostTag") + """ HTML tag to insert after the highlighted parts in all highlighted results and snippets. """ + snippet_ellipsis_text: Optional[str] = Field( + default=None, alias="snippetEllipsisText" + ) + """ String used as an ellipsis indicator when a snippet is truncated. """ + restrict_highlight_and_snippet_arrays: Optional[bool] = Field( + default=None, alias="restrictHighlightAndSnippetArrays" + ) + """ Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. """ + hits_per_page: Optional[int] = Field(default=None, alias="hitsPerPage") + """ Number of hits per page. """ + min_word_sizefor1_typo: Optional[int] = Field( + default=None, alias="minWordSizefor1Typo" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ + min_word_sizefor2_typos: Optional[int] = Field( + default=None, alias="minWordSizefor2Typos" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ typo_tolerance: Optional[TypoTolerance] = Field(default=None, alias="typoTolerance") - allow_typos_on_numeric_tokens: Optional[StrictBool] = Field( - default=True, - description="Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. ", - alias="allowTyposOnNumericTokens", + allow_typos_on_numeric_tokens: Optional[bool] = Field( + default=None, alias="allowTyposOnNumericTokens" ) - disable_typo_tolerance_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. ", - alias="disableTypoToleranceOnAttributes", + """ Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. """ + disable_typo_tolerance_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableTypoToleranceOnAttributes" ) + """ Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. """ ignore_plurals: Optional[IgnorePlurals] = Field(default=None, alias="ignorePlurals") remove_stop_words: Optional[RemoveStopWords] = Field( default=None, alias="removeStopWords" ) - keep_diacritics_on_characters: Optional[StrictStr] = Field( - default="", - description="Characters for which diacritics should be preserved. By default, Algolia removes diacritics from letters. For example, `é` becomes `e`. If this causes issues in your search, you can specify characters that should keep their diacritics. ", - alias="keepDiacriticsOnCharacters", + keep_diacritics_on_characters: Optional[str] = Field( + default=None, alias="keepDiacriticsOnCharacters" ) + """ Characters for which diacritics should be preserved. By default, Algolia removes diacritics from letters. For example, `é` becomes `e`. If this causes issues in your search, you can specify characters that should keep their diacritics. """ query_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). ", - alias="queryLanguages", - ) - decompound_query: Optional[StrictBool] = Field( - default=True, - description="Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). ", - alias="decompoundQuery", - ) - enable_rules: Optional[StrictBool] = Field( - default=True, description="Whether to enable rules.", alias="enableRules" + default=None, alias="queryLanguages" ) - enable_personalization: Optional[StrictBool] = Field( - default=False, - description="Whether to enable Personalization.", - alias="enablePersonalization", + """ Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). """ + decompound_query: Optional[bool] = Field(default=None, alias="decompoundQuery") + """ Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). """ + enable_rules: Optional[bool] = Field(default=None, alias="enableRules") + """ Whether to enable rules. """ + enable_personalization: Optional[bool] = Field( + default=None, alias="enablePersonalization" ) + """ Whether to enable Personalization. """ query_type: Optional[QueryType] = Field(default=None, alias="queryType") remove_words_if_no_results: Optional[RemoveWordsIfNoResults] = Field( default=None, alias="removeWordsIfNoResults" ) - mode: Optional[Mode] = None + mode: Optional[Mode] = Field(default=None, alias="mode") semantic_search: Optional[SemanticSearch] = Field( default=None, alias="semanticSearch" ) - advanced_syntax: Optional[StrictBool] = Field( - default=False, - description="Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. ", - alias="advancedSyntax", - ) - optional_words: Optional[List[StrictStr]] = Field( - default=None, - description='Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn\'t include the optional words. For example, if the search query is "action video" and "video" is an optional word, the search engine runs two queries. One for "action video" and one for "action". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). ', - alias="optionalWords", - ) - disable_exact_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. ", - alias="disableExactOnAttributes", + advanced_syntax: Optional[bool] = Field(default=None, alias="advancedSyntax") + """ Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. """ + optional_words: Optional[List[str]] = Field(default=None, alias="optionalWords") + """ Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn't include the optional words. For example, if the search query is \"action video\" and \"video\" is an optional word, the search engine runs two queries. One for \"action video\" and one for \"action\". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). """ + disable_exact_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableExactOnAttributes" ) + """ Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. """ exact_on_single_word_query: Optional[ExactOnSingleWordQuery] = Field( default=None, alias="exactOnSingleWordQuery" ) alternatives_as_exact: Optional[List[AlternativesAsExact]] = Field( - default=None, - description='Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as "NY/NYC" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as "NY/New York" are considered exact matches. ', - alias="alternativesAsExact", + default=None, alias="alternativesAsExact" ) + """ Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as \"NY/NYC\" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as \"NY/New York\" are considered exact matches. """ advanced_syntax_features: Optional[List[AdvancedSyntaxFeatures]] = Field( - default=None, - description='Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue "iPhone case"` only returns records with the exact string "iPhone case". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain "search" but not "engine". This setting only has an effect if `advancedSyntax` is true. ', - alias="advancedSyntaxFeatures", - ) - distinct: Optional[Distinct] = None - replace_synonyms_in_highlight: Optional[StrictBool] = Field( - default=False, - description='Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either "home" or "house" are included in the search results, and either "home" or "house" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of "house" are replaced by "home" in the highlighted response. ', - alias="replaceSynonymsInHighlight", - ) - min_proximity: Optional[Annotated[int, Field(le=7, strict=True, ge=1)]] = Field( - default=1, - description="Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. ", - alias="minProximity", - ) - response_fields: Optional[List[StrictStr]] = Field( - default=None, - description="Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. ", - alias="responseFields", - ) - max_facet_hits: Optional[Annotated[int, Field(le=100, strict=True)]] = Field( - default=10, - description="Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values).", - alias="maxFacetHits", - ) - max_values_per_facet: Optional[Annotated[int, Field(le=1000, strict=True)]] = Field( - default=100, - description="Maximum number of facet values to return for each facet.", - alias="maxValuesPerFacet", - ) - sort_facet_values_by: Optional[StrictStr] = Field( - default="count", - description="Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). ", - alias="sortFacetValuesBy", - ) - attribute_criteria_computed_by_min_proximity: Optional[StrictBool] = Field( - default=False, - description="Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. ", - alias="attributeCriteriaComputedByMinProximity", - ) + default=None, alias="advancedSyntaxFeatures" + ) + """ Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue \"iPhone case\"` only returns records with the exact string \"iPhone case\". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain \"search\" but not \"engine\". This setting only has an effect if `advancedSyntax` is true. """ + distinct: Optional[Distinct] = Field(default=None, alias="distinct") + replace_synonyms_in_highlight: Optional[bool] = Field( + default=None, alias="replaceSynonymsInHighlight" + ) + """ Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either \"home\" or \"house\" are included in the search results, and either \"home\" or \"house\" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of \"house\" are replaced by \"home\" in the highlighted response. """ + min_proximity: Optional[int] = Field(default=None, alias="minProximity") + """ Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. """ + response_fields: Optional[List[str]] = Field(default=None, alias="responseFields") + """ Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. """ + max_facet_hits: Optional[int] = Field(default=None, alias="maxFacetHits") + """ Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values). """ + max_values_per_facet: Optional[int] = Field(default=None, alias="maxValuesPerFacet") + """ Maximum number of facet values to return for each facet. """ + sort_facet_values_by: Optional[str] = Field(default=None, alias="sortFacetValuesBy") + """ Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). """ + attribute_criteria_computed_by_min_proximity: Optional[bool] = Field( + default=None, alias="attributeCriteriaComputedByMinProximity" + ) + """ Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. """ rendering_content: Optional[RenderingContent] = Field( default=None, alias="renderingContent" ) - enable_re_ranking: Optional[StrictBool] = Field( - default=True, - description="Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. ", - alias="enableReRanking", - ) + enable_re_ranking: Optional[bool] = Field(default=None, alias="enableReRanking") + """ Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. """ re_ranking_apply_filter: Optional[ReRankingApplyFilter] = Field( default=None, alias="reRankingApplyFilter" ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of IndexSettings from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.typo_tolerance: - _dict["typoTolerance"] = self.typo_tolerance.to_dict() - if self.ignore_plurals: - _dict["ignorePlurals"] = self.ignore_plurals.to_dict() - if self.remove_stop_words: - _dict["removeStopWords"] = self.remove_stop_words.to_dict() - if self.semantic_search: - _dict["semanticSearch"] = self.semantic_search.to_dict() - if self.distinct: - _dict["distinct"] = self.distinct.to_dict() - if self.rendering_content: - _dict["renderingContent"] = self.rendering_content.to_dict() - if self.re_ranking_apply_filter: - _dict["reRankingApplyFilter"] = self.re_ranking_apply_filter.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of IndexSettings from a dict""" if obj is None: return None @@ -366,107 +263,48 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "attributesForFaceting": obj.get("attributesForFaceting"), - "replicas": obj.get("replicas"), - "paginationLimitedTo": obj.get("paginationLimitedTo"), - "unretrievableAttributes": obj.get("unretrievableAttributes"), - "disableTypoToleranceOnWords": obj.get("disableTypoToleranceOnWords"), - "attributesToTransliterate": obj.get("attributesToTransliterate"), - "camelCaseAttributes": obj.get("camelCaseAttributes"), - "decompoundedAttributes": obj.get("decompoundedAttributes"), - "indexLanguages": obj.get("indexLanguages"), - "disablePrefixOnAttributes": obj.get("disablePrefixOnAttributes"), - "allowCompressionOfIntegerArray": obj.get( - "allowCompressionOfIntegerArray" - ), - "numericAttributesForFiltering": obj.get( - "numericAttributesForFiltering" - ), - "separatorsToIndex": obj.get("separatorsToIndex"), - "searchableAttributes": obj.get("searchableAttributes"), - "userData": obj.get("userData"), - "customNormalization": obj.get("customNormalization"), - "attributeForDistinct": obj.get("attributeForDistinct"), - "attributesToRetrieve": obj.get("attributesToRetrieve"), - "ranking": obj.get("ranking"), - "customRanking": obj.get("customRanking"), - "relevancyStrictness": obj.get("relevancyStrictness"), - "attributesToHighlight": obj.get("attributesToHighlight"), - "attributesToSnippet": obj.get("attributesToSnippet"), - "highlightPreTag": obj.get("highlightPreTag"), - "highlightPostTag": obj.get("highlightPostTag"), - "snippetEllipsisText": obj.get("snippetEllipsisText"), - "restrictHighlightAndSnippetArrays": obj.get( - "restrictHighlightAndSnippetArrays" - ), - "hitsPerPage": obj.get("hitsPerPage"), - "minWordSizefor1Typo": obj.get("minWordSizefor1Typo"), - "minWordSizefor2Typos": obj.get("minWordSizefor2Typos"), - "typoTolerance": ( - TypoTolerance.from_dict(obj.get("typoTolerance")) - if obj.get("typoTolerance") is not None - else None - ), - "allowTyposOnNumericTokens": obj.get("allowTyposOnNumericTokens"), - "disableTypoToleranceOnAttributes": obj.get( - "disableTypoToleranceOnAttributes" - ), - "ignorePlurals": ( - IgnorePlurals.from_dict(obj.get("ignorePlurals")) - if obj.get("ignorePlurals") is not None - else None - ), - "removeStopWords": ( - RemoveStopWords.from_dict(obj.get("removeStopWords")) - if obj.get("removeStopWords") is not None - else None - ), - "keepDiacriticsOnCharacters": obj.get("keepDiacriticsOnCharacters"), - "queryLanguages": obj.get("queryLanguages"), - "decompoundQuery": obj.get("decompoundQuery"), - "enableRules": obj.get("enableRules"), - "enablePersonalization": obj.get("enablePersonalization"), - "queryType": obj.get("queryType"), - "removeWordsIfNoResults": obj.get("removeWordsIfNoResults"), - "mode": obj.get("mode"), - "semanticSearch": ( - SemanticSearch.from_dict(obj.get("semanticSearch")) - if obj.get("semanticSearch") is not None - else None - ), - "advancedSyntax": obj.get("advancedSyntax"), - "optionalWords": obj.get("optionalWords"), - "disableExactOnAttributes": obj.get("disableExactOnAttributes"), - "exactOnSingleWordQuery": obj.get("exactOnSingleWordQuery"), - "alternativesAsExact": obj.get("alternativesAsExact"), - "advancedSyntaxFeatures": obj.get("advancedSyntaxFeatures"), - "distinct": ( - Distinct.from_dict(obj.get("distinct")) - if obj.get("distinct") is not None - else None - ), - "replaceSynonymsInHighlight": obj.get("replaceSynonymsInHighlight"), - "minProximity": obj.get("minProximity"), - "responseFields": obj.get("responseFields"), - "maxFacetHits": obj.get("maxFacetHits"), - "maxValuesPerFacet": obj.get("maxValuesPerFacet"), - "sortFacetValuesBy": obj.get("sortFacetValuesBy"), - "attributeCriteriaComputedByMinProximity": obj.get( - "attributeCriteriaComputedByMinProximity" - ), - "renderingContent": ( - RenderingContent.from_dict(obj.get("renderingContent")) - if obj.get("renderingContent") is not None - else None - ), - "enableReRanking": obj.get("enableReRanking"), - "reRankingApplyFilter": ( - ReRankingApplyFilter.from_dict(obj.get("reRankingApplyFilter")) - if obj.get("reRankingApplyFilter") is not None - else None - ), - } + obj["indexLanguages"] = obj.get("indexLanguages") + obj["typoTolerance"] = ( + TypoTolerance.from_dict(obj["typoTolerance"]) + if obj.get("typoTolerance") is not None + else None + ) + obj["ignorePlurals"] = ( + IgnorePlurals.from_dict(obj["ignorePlurals"]) + if obj.get("ignorePlurals") is not None + else None + ) + obj["removeStopWords"] = ( + RemoveStopWords.from_dict(obj["removeStopWords"]) + if obj.get("removeStopWords") is not None + else None + ) + obj["queryLanguages"] = obj.get("queryLanguages") + obj["queryType"] = obj.get("queryType") + obj["removeWordsIfNoResults"] = obj.get("removeWordsIfNoResults") + obj["mode"] = obj.get("mode") + obj["semanticSearch"] = ( + SemanticSearch.from_dict(obj["semanticSearch"]) + if obj.get("semanticSearch") is not None + else None ) - return _obj + obj["exactOnSingleWordQuery"] = obj.get("exactOnSingleWordQuery") + obj["alternativesAsExact"] = obj.get("alternativesAsExact") + obj["advancedSyntaxFeatures"] = obj.get("advancedSyntaxFeatures") + obj["distinct"] = ( + Distinct.from_dict(obj["distinct"]) + if obj.get("distinct") is not None + else None + ) + obj["renderingContent"] = ( + RenderingContent.from_dict(obj["renderingContent"]) + if obj.get("renderingContent") is not None + else None + ) + obj["reRankingApplyFilter"] = ( + ReRankingApplyFilter.from_dict(obj["reRankingApplyFilter"]) + if obj.get("reRankingApplyFilter") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/languages.py b/algoliasearch/search/models/languages.py index 679ec6966..33fd6f26b 100644 --- a/algoliasearch/search/models/languages.py +++ b/algoliasearch/search/models/languages.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,48 +26,35 @@ class Languages(BaseModel): Dictionary language. """ - plurals: Optional[DictionaryLanguage] - stopwords: Optional[DictionaryLanguage] - compounds: Optional[DictionaryLanguage] + plurals: DictionaryLanguage = Field(alias="plurals") + stopwords: DictionaryLanguage = Field(alias="stopwords") + compounds: DictionaryLanguage = Field(alias="compounds") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Languages from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.plurals: - _dict["plurals"] = self.plurals.to_dict() - if self.stopwords: - _dict["stopwords"] = self.stopwords.to_dict() - if self.compounds: - _dict["compounds"] = self.compounds.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Languages from a dict""" if obj is None: return None @@ -75,23 +62,20 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "plurals": ( - DictionaryLanguage.from_dict(obj.get("plurals")) - if obj.get("plurals") is not None - else None - ), - "stopwords": ( - DictionaryLanguage.from_dict(obj.get("stopwords")) - if obj.get("stopwords") is not None - else None - ), - "compounds": ( - DictionaryLanguage.from_dict(obj.get("compounds")) - if obj.get("compounds") is not None - else None - ), - } + obj["plurals"] = ( + DictionaryLanguage.from_dict(obj["plurals"]) + if obj.get("plurals") is not None + else None + ) + obj["stopwords"] = ( + DictionaryLanguage.from_dict(obj["stopwords"]) + if obj.get("stopwords") is not None + else None ) - return _obj + obj["compounds"] = ( + DictionaryLanguage.from_dict(obj["compounds"]) + if obj.get("compounds") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/list_api_keys_response.py b/algoliasearch/search/models/list_api_keys_response.py index c26f776da..49066b327 100644 --- a/algoliasearch/search/models/list_api_keys_response.py +++ b/algoliasearch/search/models/list_api_keys_response.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -26,46 +26,34 @@ class ListApiKeysResponse(BaseModel): ListApiKeysResponse """ - keys: List[GetApiKeyResponse] = Field(description="API keys.") + keys: List[GetApiKeyResponse] = Field(alias="keys") + """ API keys. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ListApiKeysResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.keys: - for _item in self.keys: - if _item: - _items.append(_item.to_dict()) - _dict["keys"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ListApiKeysResponse from a dict""" if obj is None: return None @@ -73,13 +61,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "keys": ( - [GetApiKeyResponse.from_dict(_item) for _item in obj.get("keys")] - if obj.get("keys") is not None - else None - ) - } + obj["keys"] = ( + [GetApiKeyResponse.from_dict(_item) for _item in obj["keys"]] + if obj.get("keys") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/list_clusters_response.py b/algoliasearch/search/models/list_clusters_response.py index 9e3a3e7fb..98655ca43 100644 --- a/algoliasearch/search/models/list_clusters_response.py +++ b/algoliasearch/search/models/list_clusters_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,34 @@ class ListClustersResponse(BaseModel): Clusters. """ - top_users: List[StrictStr] = Field( - description="Key-value pairs with cluster names as keys and lists of users with the highest number of records per cluster as values.", - alias="topUsers", - ) + top_users: List[str] = Field(alias="topUsers") + """ Key-value pairs with cluster names as keys and lists of users with the highest number of records per cluster as values. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ListClustersResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ListClustersResponse from a dict""" if obj is None: return None @@ -67,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"topUsers": obj.get("topUsers")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/list_indices_response.py b/algoliasearch/search/models/list_indices_response.py index f12b8d8f2..2c504d6a1 100644 --- a/algoliasearch/search/models/list_indices_response.py +++ b/algoliasearch/search/models/list_indices_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,51 +26,36 @@ class ListIndicesResponse(BaseModel): ListIndicesResponse """ - items: List[FetchedIndex] = Field( - description="All indices in your Algolia application." - ) - nb_pages: Optional[StrictInt] = Field( - default=None, description="Number of pages.", alias="nbPages" - ) + items: List[FetchedIndex] = Field(alias="items") + """ All indices in your Algolia application. """ + nb_pages: Optional[int] = Field(default=None, alias="nbPages") + """ Number of pages. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ListIndicesResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.items: - for _item in self.items: - if _item: - _items.append(_item.to_dict()) - _dict["items"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ListIndicesResponse from a dict""" if obj is None: return None @@ -78,14 +63,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "items": ( - [FetchedIndex.from_dict(_item) for _item in obj.get("items")] - if obj.get("items") is not None - else None - ), - "nbPages": obj.get("nbPages"), - } + obj["items"] = ( + [FetchedIndex.from_dict(_item) for _item in obj["items"]] + if obj.get("items") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/list_user_ids_response.py b/algoliasearch/search/models/list_user_ids_response.py index d1c7fbc15..7f25d4c7d 100644 --- a/algoliasearch/search/models/list_user_ids_response.py +++ b/algoliasearch/search/models/list_user_ids_response.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -26,46 +26,34 @@ class ListUserIdsResponse(BaseModel): User ID data. """ - user_ids: List[UserId] = Field(description="User IDs.", alias="userIDs") + user_ids: List[UserId] = Field(alias="userIDs") + """ User IDs. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ListUserIdsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.user_ids: - for _item in self.user_ids: - if _item: - _items.append(_item.to_dict()) - _dict["userIDs"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ListUserIdsResponse from a dict""" if obj is None: return None @@ -73,13 +61,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "userIDs": ( - [UserId.from_dict(_item) for _item in obj.get("userIDs")] - if obj.get("userIDs") is not None - else None - ) - } + obj["userIDs"] = ( + [UserId.from_dict(_item) for _item in obj["userIDs"]] + if obj.get("userIDs") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/log.py b/algoliasearch/search/models/log.py index fcd103e1e..90f05ef3d 100644 --- a/algoliasearch/search/models/log.py +++ b/algoliasearch/search/models/log.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.log_query import LogQuery @@ -26,83 +26,62 @@ class Log(BaseModel): Log """ - timestamp: StrictStr = Field( - description="Date and time of the API request, in RFC 3339 format." - ) - method: StrictStr = Field(description="HTTP method of the request.") - answer_code: StrictStr = Field(description="HTTP status code of the response.") - query_body: Annotated[str, Field(strict=True, max_length=1000)] = Field( - description="Request body." - ) - answer: Annotated[str, Field(strict=True, max_length=1000)] = Field( - description="Response body." - ) - url: StrictStr = Field(description="URL of the API endpoint.") - ip: StrictStr = Field( - description="IP address of the client that performed the request." - ) - query_headers: StrictStr = Field( - description="Request headers (API keys are obfuscated)." - ) - sha1: StrictStr = Field(description="SHA1 signature of the log entry.") - nb_api_calls: StrictStr = Field(description="Number of API requests.") - processing_time_ms: StrictStr = Field( - description="Processing time for the query in milliseconds. This doesn't include latency due to the network. " - ) - index: Optional[StrictStr] = Field( - default=None, description="Index targeted by the query." - ) - var_query_params: Optional[StrictStr] = Field( - default=None, - description="Query parameters sent with the request.", - alias="query_params", - ) - query_nb_hits: Optional[StrictStr] = Field( - default=None, - description="Number of search results (hits) returned for the query.", - ) - inner_queries: Optional[List[LogQuery]] = Field( - default=None, description="Queries performed for the given request." - ) + timestamp: str = Field(alias="timestamp") + """ Date and time of the API request, in RFC 3339 format. """ + method: str = Field(alias="method") + """ HTTP method of the request. """ + answer_code: str = Field(alias="answer_code") + """ HTTP status code of the response. """ + query_body: str = Field(alias="query_body") + """ Request body. """ + answer: str = Field(alias="answer") + """ Response body. """ + url: str = Field(alias="url") + """ URL of the API endpoint. """ + ip: str = Field(alias="ip") + """ IP address of the client that performed the request. """ + query_headers: str = Field(alias="query_headers") + """ Request headers (API keys are obfuscated). """ + sha1: str = Field(alias="sha1") + """ SHA1 signature of the log entry. """ + nb_api_calls: str = Field(alias="nb_api_calls") + """ Number of API requests. """ + processing_time_ms: str = Field(alias="processing_time_ms") + """ Processing time for the query in milliseconds. This doesn't include latency due to the network. """ + index: Optional[str] = Field(default=None, alias="index") + """ Index targeted by the query. """ + var_query_params: Optional[str] = Field(default=None, alias="query_params") + """ Query parameters sent with the request. """ + query_nb_hits: Optional[str] = Field(default=None, alias="query_nb_hits") + """ Number of search results (hits) returned for the query. """ + inner_queries: Optional[List[LogQuery]] = Field(default=None, alias="inner_queries") + """ Queries performed for the given request. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Log from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.inner_queries: - for _item in self.inner_queries: - if _item: - _items.append(_item.to_dict()) - _dict["inner_queries"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Log from a dict""" if obj is None: return None @@ -110,27 +89,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "timestamp": obj.get("timestamp"), - "method": obj.get("method"), - "answer_code": obj.get("answer_code"), - "query_body": obj.get("query_body"), - "answer": obj.get("answer"), - "url": obj.get("url"), - "ip": obj.get("ip"), - "query_headers": obj.get("query_headers"), - "sha1": obj.get("sha1"), - "nb_api_calls": obj.get("nb_api_calls"), - "processing_time_ms": obj.get("processing_time_ms"), - "index": obj.get("index"), - "query_params": obj.get("query_params"), - "query_nb_hits": obj.get("query_nb_hits"), - "inner_queries": ( - [LogQuery.from_dict(_item) for _item in obj.get("inner_queries")] - if obj.get("inner_queries") is not None - else None - ), - } + obj["inner_queries"] = ( + [LogQuery.from_dict(_item) for _item in obj["inner_queries"]] + if obj.get("inner_queries") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/log_query.py b/algoliasearch/search/models/log_query.py index c78ed0c83..47ba27001 100644 --- a/algoliasearch/search/models/log_query.py +++ b/algoliasearch/search/models/log_query.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,48 +23,38 @@ class LogQuery(BaseModel): LogQuery """ - index_name: Optional[StrictStr] = Field( - default=None, description="Index targeted by the query." - ) - user_token: Optional[StrictStr] = Field( - default=None, description="A user identifier." - ) - query_id: Optional[StrictStr] = Field( - default=None, description="Unique query identifier." - ) + index_name: Optional[str] = Field(default=None, alias="index_name") + """ Index targeted by the query. """ + user_token: Optional[str] = Field(default=None, alias="user_token") + """ A user identifier. """ + query_id: Optional[str] = Field(default=None, alias="query_id") + """ Unique query identifier. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of LogQuery from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of LogQuery from a dict""" if obj is None: return None @@ -72,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "index_name": obj.get("index_name"), - "user_token": obj.get("user_token"), - "query_id": obj.get("query_id"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/log_type.py b/algoliasearch/search/models/log_type.py index da44611e9..1cb70e76d 100644 --- a/algoliasearch/search/models/log_type.py +++ b/algoliasearch/search/models/log_type.py @@ -25,8 +25,11 @@ class LogType(str, Enum): allowed enum values """ ALL = "all" + QUERY = "query" + BUILD = "build" + ERROR = "error" @classmethod diff --git a/algoliasearch/search/models/match_level.py b/algoliasearch/search/models/match_level.py index 373e611e9..e1bfbaf0b 100644 --- a/algoliasearch/search/models/match_level.py +++ b/algoliasearch/search/models/match_level.py @@ -25,7 +25,9 @@ class MatchLevel(str, Enum): allowed enum values """ NONE = "none" + PARTIAL = "partial" + FULL = "full" @classmethod diff --git a/algoliasearch/search/models/matched_geo_location.py b/algoliasearch/search/models/matched_geo_location.py index 94c88ca7e..b5de4a639 100644 --- a/algoliasearch/search/models/matched_geo_location.py +++ b/algoliasearch/search/models/matched_geo_location.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,49 +23,38 @@ class MatchedGeoLocation(BaseModel): MatchedGeoLocation """ - lat: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, description="Latitude of the matched location." - ) - lng: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, description="Longitude of the matched location." - ) - distance: Optional[StrictInt] = Field( - default=None, - description="Distance between the matched location and the search location (in meters).", - ) + lat: Optional[float] = Field(default=None, alias="lat") + """ Latitude of the matched location. """ + lng: Optional[float] = Field(default=None, alias="lng") + """ Longitude of the matched location. """ + distance: Optional[int] = Field(default=None, alias="distance") + """ Distance between the matched location and the search location (in meters). """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of MatchedGeoLocation from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of MatchedGeoLocation from a dict""" if obj is None: return None @@ -73,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "lat": obj.get("lat"), - "lng": obj.get("lng"), - "distance": obj.get("distance"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/mode.py b/algoliasearch/search/models/mode.py index ef958a7a7..f3fd0da9c 100644 --- a/algoliasearch/search/models/mode.py +++ b/algoliasearch/search/models/mode.py @@ -25,6 +25,7 @@ class Mode(str, Enum): allowed enum values """ NEURALSEARCH = "neuralSearch" + KEYWORDSEARCH = "keywordSearch" @classmethod diff --git a/algoliasearch/search/models/multiple_batch_request.py b/algoliasearch/search/models/multiple_batch_request.py index 3d24319dd..758af41ad 100644 --- a/algoliasearch/search/models/multiple_batch_request.py +++ b/algoliasearch/search/models/multiple_batch_request.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,47 +26,37 @@ class MultipleBatchRequest(BaseModel): MultipleBatchRequest """ - action: Action - body: Optional[Dict[str, Any]] = Field( - default=None, - description="Operation arguments (varies with specified `action`).", - ) - index_name: StrictStr = Field( - description="Index name (case-sensitive).", alias="indexName" - ) + action: Action = Field(alias="action") + body: Optional[object] = Field(default=None, alias="body") + """ Operation arguments (varies with specified `action`). """ + index_name: str = Field(alias="indexName") + """ Index name (case-sensitive). """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of MultipleBatchRequest from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of MultipleBatchRequest from a dict""" if obj is None: return None @@ -74,11 +64,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "action": obj.get("action"), - "body": obj.get("body"), - "indexName": obj.get("indexName"), - } - ) - return _obj + obj["action"] = obj.get("action") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/multiple_batch_response.py b/algoliasearch/search/models/multiple_batch_response.py index a4d35195a..758db396f 100644 --- a/algoliasearch/search/models/multiple_batch_response.py +++ b/algoliasearch/search/models/multiple_batch_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,45 +23,36 @@ class MultipleBatchResponse(BaseModel): MultipleBatchResponse """ - task_id: Dict[str, StrictInt] = Field( - description="Task IDs. One for each index.", alias="taskID" - ) - object_ids: List[StrictStr] = Field( - description="Unique record identifiers.", alias="objectIDs" - ) + task_id: Dict[str, int] = Field(alias="taskID") + """ Task IDs. One for each index. """ + object_ids: List[str] = Field(alias="objectIDs") + """ Unique record identifiers. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of MultipleBatchResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of MultipleBatchResponse from a dict""" if obj is None: return None @@ -69,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"taskID": obj.get("taskID"), "objectIDs": obj.get("objectIDs")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/numeric_filters.py b/algoliasearch/search/models/numeric_filters.py index e96417a1f..bd805e7e8 100644 --- a/algoliasearch/search/models/numeric_filters.py +++ b/algoliasearch/search/models/numeric_filters.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, StrictStr, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -23,9 +23,12 @@ class NumericFilters(BaseModel): Filter by numeric facets. **Prefer using the `filters` parameter, which supports all filter types and combinations with boolean operators.** You can use numeric comparison operators: `<`, `<=`, `=`, `!=`, `>`, `>=`. Comparsions are precise up to 3 decimals. You can also provide ranges: `facet: TO `. The range includes the lower and upper boundaries. The same combination rules apply as for `facetFilters`. """ - oneof_schema_1_validator: Optional[List[NumericFilters]] = None - oneof_schema_2_validator: Optional[StrictStr] = None + oneof_schema_1_validator: Optional[List[NumericFilters]] = Field(default=None) + + oneof_schema_2_validator: Optional[str] = Field(default=None) + actual_instance: Optional[Union[List[NumericFilters], str]] = None + one_of_schemas: Set[str] = {"List[NumericFilters]", "str"} def __init__(self, *args, **kwargs) -> None: if args: @@ -49,7 +52,8 @@ def unwrap_actual_instance(self) -> Optional[Union[List[NumericFilters], str]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of NumericFilters from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -83,17 +87,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], List[NumericFilters], str]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/operation_index_params.py b/algoliasearch/search/models/operation_index_params.py index 4b1ee094f..cb6cbb3c5 100644 --- a/algoliasearch/search/models/operation_index_params.py +++ b/algoliasearch/search/models/operation_index_params.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,45 +27,37 @@ class OperationIndexParams(BaseModel): OperationIndexParams """ - operation: OperationType - destination: StrictStr = Field(description="Index name (case-sensitive).") - scope: Optional[List[ScopeType]] = Field( - default=None, - description="**Only for copying.** If you specify a scope, only the selected scopes are copied. Records and the other scopes are left unchanged. If you omit the `scope` parameter, everything is copied: records, settings, synonyms, and rules. ", - ) + operation: OperationType = Field(alias="operation") + destination: str = Field(alias="destination") + """ Index name (case-sensitive). """ + scope: Optional[List[ScopeType]] = Field(default=None, alias="scope") + """ **Only for copying.** If you specify a scope, only the selected scopes are copied. Records and the other scopes are left unchanged. If you omit the `scope` parameter, everything is copied: records, settings, synonyms, and rules. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of OperationIndexParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of OperationIndexParams from a dict""" if obj is None: return None @@ -73,11 +65,7 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "operation": obj.get("operation"), - "destination": obj.get("destination"), - "scope": obj.get("scope"), - } - ) - return _obj + obj["operation"] = obj.get("operation") + obj["scope"] = obj.get("scope") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/operation_type.py b/algoliasearch/search/models/operation_type.py index 7c6ba2e24..549e8d2cf 100644 --- a/algoliasearch/search/models/operation_type.py +++ b/algoliasearch/search/models/operation_type.py @@ -25,6 +25,7 @@ class OperationType(str, Enum): allowed enum values """ MOVE = "move" + COPY = "copy" @classmethod diff --git a/algoliasearch/search/models/optional_filters.py b/algoliasearch/search/models/optional_filters.py index 737b83ab5..08edec6fb 100644 --- a/algoliasearch/search/models/optional_filters.py +++ b/algoliasearch/search/models/optional_filters.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, StrictStr, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -23,9 +23,12 @@ class OptionalFilters(BaseModel): Filters to promote or demote records in the search results. Optional filters work like facet filters, but they don't exclude records from the search results. Records that match the optional filter rank before records that don't match. If you're using a negative filter `facet:-value`, matching records rank after records that don't match. - Optional filters don't work on virtual replicas. - Optional filters are applied _after_ sort-by attributes. - Optional filters don't work with numeric attributes. """ - oneof_schema_1_validator: Optional[List[OptionalFilters]] = None - oneof_schema_2_validator: Optional[StrictStr] = None + oneof_schema_1_validator: Optional[List[OptionalFilters]] = Field(default=None) + + oneof_schema_2_validator: Optional[str] = Field(default=None) + actual_instance: Optional[Union[List[OptionalFilters], str]] = None + one_of_schemas: Set[str] = {"List[OptionalFilters]", "str"} def __init__(self, *args, **kwargs) -> None: if args: @@ -49,7 +52,8 @@ def unwrap_actual_instance(self) -> Optional[Union[List[OptionalFilters], str]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of OptionalFilters from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -83,17 +87,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], List[OptionalFilters], str]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/personalization.py b/algoliasearch/search/models/personalization.py index 81aafb7ca..a6dcf022c 100644 --- a/algoliasearch/search/models/personalization.py +++ b/algoliasearch/search/models/personalization.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,48 +23,38 @@ class Personalization(BaseModel): Personalization """ - filters_score: Optional[StrictInt] = Field( - default=None, description="The score of the filters.", alias="filtersScore" - ) - ranking_score: Optional[StrictInt] = Field( - default=None, description="The score of the ranking.", alias="rankingScore" - ) - score: Optional[StrictInt] = Field( - default=None, description="The score of the event." - ) + filters_score: Optional[int] = Field(default=None, alias="filtersScore") + """ The score of the filters. """ + ranking_score: Optional[int] = Field(default=None, alias="rankingScore") + """ The score of the ranking. """ + score: Optional[int] = Field(default=None, alias="score") + """ The score of the event. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Personalization from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Personalization from a dict""" if obj is None: return None @@ -72,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "filtersScore": obj.get("filtersScore"), - "rankingScore": obj.get("rankingScore"), - "score": obj.get("score"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/promote.py b/algoliasearch/search/models/promote.py index 2c36b09d3..aaa1c0c10 100644 --- a/algoliasearch/search/models/promote.py +++ b/algoliasearch/search/models/promote.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -27,9 +27,12 @@ class Promote(BaseModel): Promote """ - oneof_schema_1_validator: Optional[PromoteObjectIDs] = None - oneof_schema_2_validator: Optional[PromoteObjectID] = None + oneof_schema_1_validator: Optional[PromoteObjectIDs] = Field(default=None) + + oneof_schema_2_validator: Optional[PromoteObjectID] = Field(default=None) + actual_instance: Optional[Union[PromoteObjectID, PromoteObjectIDs]] = None + one_of_schemas: Set[str] = {"PromoteObjectID", "PromoteObjectIDs"} def __init__(self, *args, **kwargs) -> None: if args: @@ -55,7 +58,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of Promote from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -87,17 +91,23 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[Union[Dict[str, Any], PromoteObjectID, PromoteObjectIDs]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/promote_object_id.py b/algoliasearch/search/models/promote_object_id.py index c8655d9c7..9652e16b6 100644 --- a/algoliasearch/search/models/promote_object_id.py +++ b/algoliasearch/search/models/promote_object_id.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,45 +23,36 @@ class PromoteObjectID(BaseModel): Record to promote. """ - object_id: StrictStr = Field( - description="Unique record identifier.", alias="objectID" - ) - position: StrictInt = Field( - description="Position in the search results where you want to show the promoted records." - ) + object_id: str = Field(alias="objectID") + """ Unique record identifier. """ + position: int = Field(alias="position") + """ Position in the search results where you want to show the promoted records. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of PromoteObjectID from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of PromoteObjectID from a dict""" if obj is None: return None @@ -69,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"objectID": obj.get("objectID"), "position": obj.get("position")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/promote_object_ids.py b/algoliasearch/search/models/promote_object_ids.py index a784e5c09..d19e755b1 100644 --- a/algoliasearch/search/models/promote_object_ids.py +++ b/algoliasearch/search/models/promote_object_ids.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class PromoteObjectIDs(BaseModel): @@ -23,46 +23,36 @@ class PromoteObjectIDs(BaseModel): Records to promote. """ - object_ids: Annotated[List[StrictStr], Field(max_length=100)] = Field( - description="Object IDs of the records you want to promote. The records are placed as a group at the `position`. For example, if you want to promote four records to position `0`, they will be the first four search results. ", - alias="objectIDs", - ) - position: StrictInt = Field( - description="Position in the search results where you want to show the promoted records." - ) + object_ids: List[str] = Field(alias="objectIDs") + """ Object IDs of the records you want to promote. The records are placed as a group at the `position`. For example, if you want to promote four records to position `0`, they will be the first four search results. """ + position: int = Field(alias="position") + """ Position in the search results where you want to show the promoted records. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of PromoteObjectIDs from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of PromoteObjectIDs from a dict""" if obj is None: return None @@ -70,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"objectIDs": obj.get("objectIDs"), "position": obj.get("position")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/query_type.py b/algoliasearch/search/models/query_type.py index bf9d1b5b0..8ceeac433 100644 --- a/algoliasearch/search/models/query_type.py +++ b/algoliasearch/search/models/query_type.py @@ -25,7 +25,9 @@ class QueryType(str, Enum): allowed enum values """ PREFIXLAST = "prefixLast" + PREFIXALL = "prefixAll" + PREFIXNONE = "prefixNone" @classmethod diff --git a/algoliasearch/search/models/range.py b/algoliasearch/search/models/range.py index 14f3b0086..4cda204fa 100644 --- a/algoliasearch/search/models/range.py +++ b/algoliasearch/search/models/range.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,48 +23,36 @@ class Range(BaseModel): Range object with lower and upper values in meters to define custom ranges. """ - var_from: Optional[StrictInt] = Field( - default=None, - description="Lower boundary of a range in meters. The Geo ranking criterion considers all records within the range to be equal.", - alias="from", - ) - value: Optional[StrictInt] = Field( - default=None, - description="Upper boundary of a range in meters. The Geo ranking criterion considers all records within the range to be equal.", - ) + var_from: Optional[int] = Field(default=None, alias="from") + """ Lower boundary of a range in meters. The Geo ranking criterion considers all records within the range to be equal. """ + value: Optional[int] = Field(default=None, alias="value") + """ Upper boundary of a range in meters. The Geo ranking criterion considers all records within the range to be equal. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Range from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Range from a dict""" if obj is None: return None @@ -72,5 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"from": obj.get("from"), "value": obj.get("value")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/ranking_info.py b/algoliasearch/search/models/ranking_info.py index 4e33b8b00..fd71e5264 100644 --- a/algoliasearch/search/models/ranking_info.py +++ b/algoliasearch/search/models/ranking_info.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.matched_geo_location import MatchedGeoLocation @@ -27,90 +27,62 @@ class RankingInfo(BaseModel): Object with detailed information about the record's ranking. """ - filters: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=None, description="Whether a filter matched the query." - ) - first_matched_word: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Position of the first matched word in the best matching attribute of the record.", - alias="firstMatchedWord", - ) - geo_distance: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Distance between the geo location in the search query and the best matching geo location in the record, divided by the geo precision (in meters).", - alias="geoDistance", - ) - geo_precision: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field( - default=None, - description="Precision used when computing the geo distance, in meters.", - alias="geoPrecision", - ) + filters: Optional[int] = Field(default=None, alias="filters") + """ Whether a filter matched the query. """ + first_matched_word: int = Field(alias="firstMatchedWord") + """ Position of the first matched word in the best matching attribute of the record. """ + geo_distance: int = Field(alias="geoDistance") + """ Distance between the geo location in the search query and the best matching geo location in the record, divided by the geo precision (in meters). """ + geo_precision: Optional[int] = Field(default=None, alias="geoPrecision") + """ Precision used when computing the geo distance, in meters. """ matched_geo_location: Optional[MatchedGeoLocation] = Field( default=None, alias="matchedGeoLocation" ) - personalization: Optional[Personalization] = None - nb_exact_words: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of exactly matched words.", alias="nbExactWords" - ) - nb_typos: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Number of typos encountered when matching the record.", - alias="nbTypos", - ) - promoted: Optional[StrictBool] = Field( - default=None, description="Whether the record was promoted by a rule." - ) - proximity_distance: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=None, - description="Number of words between multiple matches in the query plus 1. For single word queries, `proximityDistance` is 0.", - alias="proximityDistance", + personalization: Optional[Personalization] = Field( + default=None, alias="personalization" ) - user_score: StrictInt = Field( - description="Overall ranking of the record, expressed as a single integer. This attribute is internal.", - alias="userScore", - ) - words: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field( - default=None, description="Number of matched words." - ) - promoted_by_re_ranking: Optional[StrictBool] = Field( - default=None, - description="Whether the record is re-ranked.", - alias="promotedByReRanking", + nb_exact_words: int = Field(alias="nbExactWords") + """ Number of exactly matched words. """ + nb_typos: int = Field(alias="nbTypos") + """ Number of typos encountered when matching the record. """ + promoted: Optional[bool] = Field(default=None, alias="promoted") + """ Whether the record was promoted by a rule. """ + proximity_distance: Optional[int] = Field(default=None, alias="proximityDistance") + """ Number of words between multiple matches in the query plus 1. For single word queries, `proximityDistance` is 0. """ + user_score: int = Field(alias="userScore") + """ Overall ranking of the record, expressed as a single integer. This attribute is internal. """ + words: Optional[int] = Field(default=None, alias="words") + """ Number of matched words. """ + promoted_by_re_ranking: Optional[bool] = Field( + default=None, alias="promotedByReRanking" ) + """ Whether the record is re-ranked. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RankingInfo from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.matched_geo_location: - _dict["matchedGeoLocation"] = self.matched_geo_location.to_dict() - if self.personalization: - _dict["personalization"] = self.personalization.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RankingInfo from a dict""" if obj is None: return None @@ -118,29 +90,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "filters": obj.get("filters"), - "firstMatchedWord": obj.get("firstMatchedWord"), - "geoDistance": obj.get("geoDistance"), - "geoPrecision": obj.get("geoPrecision"), - "matchedGeoLocation": ( - MatchedGeoLocation.from_dict(obj.get("matchedGeoLocation")) - if obj.get("matchedGeoLocation") is not None - else None - ), - "personalization": ( - Personalization.from_dict(obj.get("personalization")) - if obj.get("personalization") is not None - else None - ), - "nbExactWords": obj.get("nbExactWords"), - "nbTypos": obj.get("nbTypos"), - "promoted": obj.get("promoted"), - "proximityDistance": obj.get("proximityDistance"), - "userScore": obj.get("userScore"), - "words": obj.get("words"), - "promotedByReRanking": obj.get("promotedByReRanking"), - } + obj["matchedGeoLocation"] = ( + MatchedGeoLocation.from_dict(obj["matchedGeoLocation"]) + if obj.get("matchedGeoLocation") is not None + else None + ) + obj["personalization"] = ( + Personalization.from_dict(obj["personalization"]) + if obj.get("personalization") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/re_ranking_apply_filter.py b/algoliasearch/search/models/re_ranking_apply_filter.py index 051b772b3..39053345c 100644 --- a/algoliasearch/search/models/re_ranking_apply_filter.py +++ b/algoliasearch/search/models/re_ranking_apply_filter.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, StrictStr, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -23,9 +23,12 @@ class ReRankingApplyFilter(BaseModel): Restrict [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/) to records that match these filters. """ - oneof_schema_1_validator: Optional[List[ReRankingApplyFilter]] = None - oneof_schema_2_validator: Optional[StrictStr] = None + oneof_schema_1_validator: Optional[List[ReRankingApplyFilter]] = Field(default=None) + + oneof_schema_2_validator: Optional[str] = Field(default=None) + actual_instance: Optional[Union[List[ReRankingApplyFilter], str]] = None + one_of_schemas: Set[str] = {"List[ReRankingApplyFilter]", "str"} def __init__(self, *args, **kwargs) -> None: if args: @@ -51,7 +54,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of ReRankingApplyFilter from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -85,17 +89,23 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[Union[Dict[str, Any], List[ReRankingApplyFilter], str]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/redirect.py b/algoliasearch/search/models/redirect.py index 16a754450..30c032127 100644 --- a/algoliasearch/search/models/redirect.py +++ b/algoliasearch/search/models/redirect.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -28,46 +28,35 @@ class Redirect(BaseModel): [Redirect results to a URL](https://www.algolia.com/doc/guides/managing-results/rules/merchandising-and-promoting/how-to/redirects/), this this parameter is for internal use only. """ - index: Optional[List[RedirectRuleIndexMetadata]] = None + index: Optional[List[RedirectRuleIndexMetadata]] = Field( + default=None, alias="index" + ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Redirect from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.index: - for _item in self.index: - if _item: - _items.append(_item.to_dict()) - _dict["index"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Redirect from a dict""" if obj is None: return None @@ -75,16 +64,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "index": ( - [ - RedirectRuleIndexMetadata.from_dict(_item) - for _item in obj.get("index") - ] - if obj.get("index") is not None - else None - ) - } + obj["index"] = ( + [RedirectRuleIndexMetadata.from_dict(_item) for _item in obj["index"]] + if obj.get("index") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/redirect_rule_index_data.py b/algoliasearch/search/models/redirect_rule_index_data.py index 799354cc7..bb6826e62 100644 --- a/algoliasearch/search/models/redirect_rule_index_data.py +++ b/algoliasearch/search/models/redirect_rule_index_data.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,40 +23,33 @@ class RedirectRuleIndexData(BaseModel): Redirect rule data. """ - rule_object_id: StrictStr = Field(alias="ruleObjectID") + rule_object_id: str = Field(alias="ruleObjectID") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RedirectRuleIndexData from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RedirectRuleIndexData from a dict""" if obj is None: return None @@ -64,5 +57,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"ruleObjectID": obj.get("ruleObjectID")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/redirect_rule_index_metadata.py b/algoliasearch/search/models/redirect_rule_index_metadata.py index 2a2e80a1d..2ae66259e 100644 --- a/algoliasearch/search/models/redirect_rule_index_metadata.py +++ b/algoliasearch/search/models/redirect_rule_index_metadata.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,46 +26,41 @@ class RedirectRuleIndexMetadata(BaseModel): RedirectRuleIndexMetadata """ - source: StrictStr = Field(description="Source index for the redirect rule.") - dest: StrictStr = Field(description="Destination index for the redirect rule.") - reason: StrictStr = Field(description="Reason for the redirect rule.") - succeed: StrictBool = Field(description="Redirect rule status.") - data: RedirectRuleIndexData + source: str = Field(alias="source") + """ Source index for the redirect rule. """ + dest: str = Field(alias="dest") + """ Destination index for the redirect rule. """ + reason: str = Field(alias="reason") + """ Reason for the redirect rule. """ + succeed: bool = Field(alias="succeed") + """ Redirect rule status. """ + data: RedirectRuleIndexData = Field(alias="data") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RedirectRuleIndexMetadata from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.data: - _dict["data"] = self.data.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RedirectRuleIndexMetadata from a dict""" if obj is None: return None @@ -73,17 +68,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "source": obj.get("source"), - "dest": obj.get("dest"), - "reason": obj.get("reason"), - "succeed": obj.get("succeed"), - "data": ( - RedirectRuleIndexData.from_dict(obj.get("data")) - if obj.get("data") is not None - else None - ), - } + obj["data"] = ( + RedirectRuleIndexData.from_dict(obj["data"]) + if obj.get("data") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/redirect_url.py b/algoliasearch/search/models/redirect_url.py index 8adefe638..fce44987e 100644 --- a/algoliasearch/search/models/redirect_url.py +++ b/algoliasearch/search/models/redirect_url.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,40 +23,33 @@ class RedirectURL(BaseModel): The redirect rule container. """ - url: Optional[StrictStr] = None + url: Optional[str] = Field(default=None, alias="url") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RedirectURL from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RedirectURL from a dict""" if obj is None: return None @@ -64,5 +57,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"url": obj.get("url")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/remove_stop_words.py b/algoliasearch/search/models/remove_stop_words.py index 055ab8c79..828055465 100644 --- a/algoliasearch/search/models/remove_stop_words.py +++ b/algoliasearch/search/models/remove_stop_words.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, Field, StrictBool, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -26,15 +26,12 @@ class RemoveStopWords(BaseModel): Removes stop words from the search query. Stop words are common words like articles, conjunctions, prepositions, or pronouns that have little or no meaning on their own. In English, \"the\", \"a\", or \"and\" are stop words. You should only use this feature for the languages used in your index. """ - oneof_schema_1_validator: Optional[List[SupportedLanguage]] = Field( - default=None, - description="ISO code for languages for which stop words should be removed. This overrides languages you set in `queryLanguges`.", - ) - oneof_schema_2_validator: Optional[StrictBool] = Field( - default=False, - description="If true, stop words are removed for all languages you included in `queryLanguages`, or for all supported languages, if `queryLanguages` is empty. If false, stop words are not removed. ", - ) + oneof_schema_1_validator: Optional[List[SupportedLanguage]] = Field(default=None) + """ ISO code for languages for which stop words should be removed. This overrides languages you set in `queryLanguges`. """ + oneof_schema_2_validator: Optional[bool] = Field(default=None) + """ If true, stop words are removed for all languages you included in `queryLanguages`, or for all supported languages, if `queryLanguages` is empty. If false, stop words are not removed. """ actual_instance: Optional[Union[List[SupportedLanguage], bool]] = None + one_of_schemas: Set[str] = {"List[SupportedLanguage]", "bool"} def __init__(self, *args, **kwargs) -> None: if args: @@ -58,7 +55,8 @@ def unwrap_actual_instance(self) -> Optional[Union[List[SupportedLanguage], bool return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of RemoveStopWords from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -92,17 +90,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], List[SupportedLanguage], bool]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/remove_user_id_response.py b/algoliasearch/search/models/remove_user_id_response.py index fe40d2b79..29659a3fd 100644 --- a/algoliasearch/search/models/remove_user_id_response.py +++ b/algoliasearch/search/models/remove_user_id_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,34 @@ class RemoveUserIdResponse(BaseModel): RemoveUserIdResponse """ - deleted_at: StrictStr = Field( - description="Date and time when the object was deleted, in RFC 3339 format.", - alias="deletedAt", - ) + deleted_at: str = Field(alias="deletedAt") + """ Date and time when the object was deleted, in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RemoveUserIdResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RemoveUserIdResponse from a dict""" if obj is None: return None @@ -67,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"deletedAt": obj.get("deletedAt")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/remove_words_if_no_results.py b/algoliasearch/search/models/remove_words_if_no_results.py index 8961dee90..3466ed947 100644 --- a/algoliasearch/search/models/remove_words_if_no_results.py +++ b/algoliasearch/search/models/remove_words_if_no_results.py @@ -25,8 +25,11 @@ class RemoveWordsIfNoResults(str, Enum): allowed enum values """ NONE = "none" + LASTWORDS = "lastWords" + FIRSTWORDS = "firstWords" + ALLOPTIONAL = "allOptional" @classmethod diff --git a/algoliasearch/search/models/rendering_content.py b/algoliasearch/search/models/rendering_content.py index 1c76d413a..81782d2c6 100644 --- a/algoliasearch/search/models/rendering_content.py +++ b/algoliasearch/search/models/rendering_content.py @@ -28,44 +28,33 @@ class RenderingContent(BaseModel): """ facet_ordering: Optional[FacetOrdering] = Field(default=None, alias="facetOrdering") - redirect: Optional[RedirectURL] = None + redirect: Optional[RedirectURL] = Field(default=None, alias="redirect") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of RenderingContent from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.facet_ordering: - _dict["facetOrdering"] = self.facet_ordering.to_dict() - if self.redirect: - _dict["redirect"] = self.redirect.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of RenderingContent from a dict""" if obj is None: return None @@ -73,18 +62,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "facetOrdering": ( - FacetOrdering.from_dict(obj.get("facetOrdering")) - if obj.get("facetOrdering") is not None - else None - ), - "redirect": ( - RedirectURL.from_dict(obj.get("redirect")) - if obj.get("redirect") is not None - else None - ), - } + obj["facetOrdering"] = ( + FacetOrdering.from_dict(obj["facetOrdering"]) + if obj.get("facetOrdering") is not None + else None ) - return _obj + obj["redirect"] = ( + RedirectURL.from_dict(obj["redirect"]) + if obj.get("redirect") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/replace_all_objects_response.py b/algoliasearch/search/models/replace_all_objects_response.py index 7b2a82905..89cb3363f 100644 --- a/algoliasearch/search/models/replace_all_objects_response.py +++ b/algoliasearch/search/models/replace_all_objects_response.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field @@ -28,53 +28,35 @@ class ReplaceAllObjectsResponse(BaseModel): """ copy_operation_response: UpdatedAtResponse = Field(alias="copyOperationResponse") - batch_responses: List[BatchResponse] = Field( - description="The response of the `batch` request(s).", alias="batchResponses" - ) + batch_responses: List[BatchResponse] = Field(alias="batchResponses") + """ The response of the `batch` request(s). """ move_operation_response: UpdatedAtResponse = Field(alias="moveOperationResponse") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ReplaceAllObjectsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.copy_operation_response: - _dict["copyOperationResponse"] = self.copy_operation_response.to_dict() - _items = [] - if self.batch_responses: - for _item in self.batch_responses: - if _item: - _items.append(_item.to_dict()) - _dict["batchResponses"] = _items - if self.move_operation_response: - _dict["moveOperationResponse"] = self.move_operation_response.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ReplaceAllObjectsResponse from a dict""" if obj is None: return None @@ -82,26 +64,20 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "copyOperationResponse": ( - UpdatedAtResponse.from_dict(obj.get("copyOperationResponse")) - if obj.get("copyOperationResponse") is not None - else None - ), - "batchResponses": ( - [ - BatchResponse.from_dict(_item) - for _item in obj.get("batchResponses") - ] - if obj.get("batchResponses") is not None - else None - ), - "moveOperationResponse": ( - UpdatedAtResponse.from_dict(obj.get("moveOperationResponse")) - if obj.get("moveOperationResponse") is not None - else None - ), - } + obj["copyOperationResponse"] = ( + UpdatedAtResponse.from_dict(obj["copyOperationResponse"]) + if obj.get("copyOperationResponse") is not None + else None ) - return _obj + obj["batchResponses"] = ( + [BatchResponse.from_dict(_item) for _item in obj["batchResponses"]] + if obj.get("batchResponses") is not None + else None + ) + obj["moveOperationResponse"] = ( + UpdatedAtResponse.from_dict(obj["moveOperationResponse"]) + if obj.get("moveOperationResponse") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/replace_source_response.py b/algoliasearch/search/models/replace_source_response.py index 27ae85ad8..b422652a4 100644 --- a/algoliasearch/search/models/replace_source_response.py +++ b/algoliasearch/search/models/replace_source_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,34 @@ class ReplaceSourceResponse(BaseModel): ReplaceSourceResponse """ - updated_at: StrictStr = Field( - description="Date and time when the object was updated, in RFC 3339 format.", - alias="updatedAt", - ) + updated_at: str = Field(alias="updatedAt") + """ Date and time when the object was updated, in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of ReplaceSourceResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of ReplaceSourceResponse from a dict""" if obj is None: return None @@ -67,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"updatedAt": obj.get("updatedAt")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/rule.py b/algoliasearch/search/models/rule.py index 87f448cb5..6dee4a44b 100644 --- a/algoliasearch/search/models/rule.py +++ b/algoliasearch/search/models/rule.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.condition import Condition @@ -28,73 +28,43 @@ class Rule(BaseModel): Rule object. """ - object_id: StrictStr = Field( - description="Unique identifier of a rule object.", alias="objectID" - ) - conditions: Optional[ - Annotated[List[Condition], Field(min_length=0, max_length=25)] - ] = Field( - default=None, - description="Conditions that trigger a rule. Some consequences require specific conditions or don't require any condition. For more information, see [Conditions](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/#conditions). ", - ) - consequence: Optional[Consequence] = None - description: Optional[StrictStr] = Field( - default=None, - description="Description of the rule's purpose to help you distinguish between different rules.", - ) - enabled: Optional[StrictBool] = Field( - default=True, description="Whether the rule is active." - ) - validity: Optional[List[TimeRange]] = Field( - default=None, description="Time periods when the rule is active." - ) + object_id: str = Field(alias="objectID") + """ Unique identifier of a rule object. """ + conditions: Optional[List[Condition]] = Field(default=None, alias="conditions") + """ Conditions that trigger a rule. Some consequences require specific conditions or don't require any condition. For more information, see [Conditions](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/#conditions). """ + consequence: Optional[Consequence] = Field(default=None, alias="consequence") + description: Optional[str] = Field(default=None, alias="description") + """ Description of the rule's purpose to help you distinguish between different rules. """ + enabled: Optional[bool] = Field(default=None, alias="enabled") + """ Whether the rule is active. """ + validity: Optional[List[TimeRange]] = Field(default=None, alias="validity") + """ Time periods when the rule is active. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Rule from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.conditions: - for _item in self.conditions: - if _item: - _items.append(_item.to_dict()) - _dict["conditions"] = _items - if self.consequence: - _dict["consequence"] = self.consequence.to_dict() - _items = [] - if self.validity: - for _item in self.validity: - if _item: - _items.append(_item.to_dict()) - _dict["validity"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Rule from a dict""" if obj is None: return None @@ -102,26 +72,20 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "objectID": obj.get("objectID"), - "conditions": ( - [Condition.from_dict(_item) for _item in obj.get("conditions")] - if obj.get("conditions") is not None - else None - ), - "consequence": ( - Consequence.from_dict(obj.get("consequence")) - if obj.get("consequence") is not None - else None - ), - "description": obj.get("description"), - "enabled": obj.get("enabled"), - "validity": ( - [TimeRange.from_dict(_item) for _item in obj.get("validity")] - if obj.get("validity") is not None - else None - ), - } + obj["conditions"] = ( + [Condition.from_dict(_item) for _item in obj["conditions"]] + if obj.get("conditions") is not None + else None + ) + obj["consequence"] = ( + Consequence.from_dict(obj["consequence"]) + if obj.get("consequence") is not None + else None ) - return _obj + obj["validity"] = ( + [TimeRange.from_dict(_item) for _item in obj["validity"]] + if obj.get("validity") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/save_object_response.py b/algoliasearch/search/models/save_object_response.py index 2ba06b852..7d9d757a8 100644 --- a/algoliasearch/search/models/save_object_response.py +++ b/algoliasearch/search/models/save_object_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,50 +23,38 @@ class SaveObjectResponse(BaseModel): SaveObjectResponse """ - created_at: StrictStr = Field( - description="Date and time when the object was created, in RFC 3339 format.", - alias="createdAt", - ) - task_id: StrictInt = Field( - description="Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. ", - alias="taskID", - ) - object_id: Optional[StrictStr] = Field( - default=None, description="Unique record identifier.", alias="objectID" - ) + created_at: str = Field(alias="createdAt") + """ Date and time when the object was created, in RFC 3339 format. """ + task_id: int = Field(alias="taskID") + """ Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. """ + object_id: Optional[str] = Field(default=None, alias="objectID") + """ Unique record identifier. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SaveObjectResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SaveObjectResponse from a dict""" if obj is None: return None @@ -74,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "createdAt": obj.get("createdAt"), - "taskID": obj.get("taskID"), - "objectID": obj.get("objectID"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/save_synonym_response.py b/algoliasearch/search/models/save_synonym_response.py index 4bba0f73a..9bf9e357a 100644 --- a/algoliasearch/search/models/save_synonym_response.py +++ b/algoliasearch/search/models/save_synonym_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,48 +23,38 @@ class SaveSynonymResponse(BaseModel): SaveSynonymResponse """ - task_id: StrictInt = Field( - description="Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. ", - alias="taskID", - ) - updated_at: StrictStr = Field( - description="Date and time when the object was updated, in RFC 3339 format.", - alias="updatedAt", - ) - id: StrictStr = Field(description="Unique identifier of a synonym object.") + task_id: int = Field(alias="taskID") + """ Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. """ + updated_at: str = Field(alias="updatedAt") + """ Date and time when the object was updated, in RFC 3339 format. """ + id: str = Field(alias="id") + """ Unique identifier of a synonym object. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SaveSynonymResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SaveSynonymResponse from a dict""" if obj is None: return None @@ -72,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "taskID": obj.get("taskID"), - "updatedAt": obj.get("updatedAt"), - "id": obj.get("id"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/scope_type.py b/algoliasearch/search/models/scope_type.py index 5d5f90e19..75fbc3c2b 100644 --- a/algoliasearch/search/models/scope_type.py +++ b/algoliasearch/search/models/scope_type.py @@ -25,7 +25,9 @@ class ScopeType(str, Enum): allowed enum values """ SETTINGS = "settings" + SYNONYMS = "synonyms" + RULES = "rules" @classmethod diff --git a/algoliasearch/search/models/search_dictionary_entries_params.py b/algoliasearch/search/models/search_dictionary_entries_params.py index 0641fa468..955fb69a1 100644 --- a/algoliasearch/search/models/search_dictionary_entries_params.py +++ b/algoliasearch/search/models/search_dictionary_entries_params.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.supported_language import SupportedLanguage @@ -26,47 +26,39 @@ class SearchDictionaryEntriesParams(BaseModel): Search parameter. """ - query: StrictStr = Field(description="Search query.") - page: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=0, description="Page of search results to retrieve." - ) - hits_per_page: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = Field( - default=20, description="Number of hits per page.", alias="hitsPerPage" - ) - language: Optional[SupportedLanguage] = None + query: str = Field(alias="query") + """ Search query. """ + page: Optional[int] = Field(default=None, alias="page") + """ Page of search results to retrieve. """ + hits_per_page: Optional[int] = Field(default=None, alias="hitsPerPage") + """ Number of hits per page. """ + language: Optional[SupportedLanguage] = Field(default=None, alias="language") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchDictionaryEntriesParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchDictionaryEntriesParams from a dict""" if obj is None: return None @@ -74,12 +66,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "query": obj.get("query"), - "page": obj.get("page"), - "hitsPerPage": obj.get("hitsPerPage"), - "language": obj.get("language"), - } - ) - return _obj + obj["language"] = obj.get("language") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/search_dictionary_entries_response.py b/algoliasearch/search/models/search_dictionary_entries_response.py index d048f8e42..7b96fa125 100644 --- a/algoliasearch/search/models/search_dictionary_entries_response.py +++ b/algoliasearch/search/models/search_dictionary_entries_response.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.dictionary_entry import DictionaryEntry @@ -26,55 +26,40 @@ class SearchDictionaryEntriesResponse(BaseModel): SearchDictionaryEntriesResponse """ - hits: List[DictionaryEntry] = Field( - description="Dictionary entries matching the search criteria." - ) - page: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Requested page of the API response." - ) - nb_hits: StrictInt = Field(description="Number of results (hits).", alias="nbHits") - nb_pages: StrictInt = Field( - description="Number of pages of results.", alias="nbPages" - ) + hits: List[DictionaryEntry] = Field(alias="hits") + """ Dictionary entries matching the search criteria. """ + page: int = Field(alias="page") + """ Requested page of the API response. """ + nb_hits: int = Field(alias="nbHits") + """ Number of results (hits). """ + nb_pages: int = Field(alias="nbPages") + """ Number of pages of results. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchDictionaryEntriesResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.hits: - for _item in self.hits: - if _item: - _items.append(_item.to_dict()) - _dict["hits"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchDictionaryEntriesResponse from a dict""" if obj is None: return None @@ -82,16 +67,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "hits": ( - [DictionaryEntry.from_dict(_item) for _item in obj.get("hits")] - if obj.get("hits") is not None - else None - ), - "page": obj.get("page"), - "nbHits": obj.get("nbHits"), - "nbPages": obj.get("nbPages"), - } + obj["hits"] = ( + [DictionaryEntry.from_dict(_item) for _item in obj["hits"]] + if obj.get("hits") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/search_for_facet_values_request.py b/algoliasearch/search/models/search_for_facet_values_request.py index 7f6ab57fd..3a83de727 100644 --- a/algoliasearch/search/models/search_for_facet_values_request.py +++ b/algoliasearch/search/models/search_for_facet_values_request.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class SearchForFacetValuesRequest(BaseModel): @@ -23,52 +23,38 @@ class SearchForFacetValuesRequest(BaseModel): SearchForFacetValuesRequest """ - params: Optional[StrictStr] = Field( - default="", description="Search parameters as a URL-encoded query string." - ) - facet_query: Optional[StrictStr] = Field( - default="", - description="Text to search inside the facet's values.", - alias="facetQuery", - ) - max_facet_hits: Optional[Annotated[int, Field(le=100, strict=True)]] = Field( - default=10, - description="Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values).", - alias="maxFacetHits", - ) + params: Optional[str] = Field(default=None, alias="params") + """ Search parameters as a URL-encoded query string. """ + facet_query: Optional[str] = Field(default=None, alias="facetQuery") + """ Text to search inside the facet's values. """ + max_facet_hits: Optional[int] = Field(default=None, alias="maxFacetHits") + """ Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values). """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchForFacetValuesRequest from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchForFacetValuesRequest from a dict""" if obj is None: return None @@ -76,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "params": obj.get("params"), - "facetQuery": obj.get("facetQuery"), - "maxFacetHits": obj.get("maxFacetHits"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/search_for_facet_values_response.py b/algoliasearch/search/models/search_for_facet_values_response.py index 32c49e73c..2afdd0002 100644 --- a/algoliasearch/search/models/search_for_facet_values_response.py +++ b/algoliasearch/search/models/search_for_facet_values_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,57 +26,38 @@ class SearchForFacetValuesResponse(BaseModel): SearchForFacetValuesResponse """ - facet_hits: List[FacetHits] = Field( - description="Matching facet values.", alias="facetHits" - ) - exhaustive_facets_count: StrictBool = Field( - description="Whether the facet count is exhaustive (true) or approximate (false). For more information, see [Why are my facet and hit counts not accurate](https://support.algolia.com/hc/en-us/articles/4406975248145-Why-are-my-facet-and-hit-counts-not-accurate-). ", - alias="exhaustiveFacetsCount", - ) - processing_time_ms: Optional[StrictInt] = Field( - default=None, - description="Time the server took to process the request, in milliseconds.", - alias="processingTimeMS", - ) + facet_hits: List[FacetHits] = Field(alias="facetHits") + """ Matching facet values. """ + exhaustive_facets_count: bool = Field(alias="exhaustiveFacetsCount") + """ Whether the facet count is exhaustive (true) or approximate (false). For more information, see [Why are my facet and hit counts not accurate](https://support.algolia.com/hc/en-us/articles/4406975248145-Why-are-my-facet-and-hit-counts-not-accurate-). """ + processing_time_ms: Optional[int] = Field(default=None, alias="processingTimeMS") + """ Time the server took to process the request, in milliseconds. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchForFacetValuesResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.facet_hits: - for _item in self.facet_hits: - if _item: - _items.append(_item.to_dict()) - _dict["facetHits"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchForFacetValuesResponse from a dict""" if obj is None: return None @@ -84,15 +65,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "facetHits": ( - [FacetHits.from_dict(_item) for _item in obj.get("facetHits")] - if obj.get("facetHits") is not None - else None - ), - "exhaustiveFacetsCount": obj.get("exhaustiveFacetsCount"), - "processingTimeMS": obj.get("processingTimeMS"), - } + obj["facetHits"] = ( + [FacetHits.from_dict(_item) for _item in obj["facetHits"]] + if obj.get("facetHits") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/search_for_facets.py b/algoliasearch/search/models/search_for_facets.py index a32ea27ba..49a8becf2 100644 --- a/algoliasearch/search/models/search_for_facets.py +++ b/algoliasearch/search/models/search_for_facets.py @@ -8,22 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional -from pydantic import ( - BaseModel, - ConfigDict, - Field, - StrictBool, - StrictFloat, - StrictInt, - StrictStr, -) +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.advanced_syntax_features import AdvancedSyntaxFeatures @@ -58,19 +50,14 @@ class SearchForFacets(BaseModel): SearchForFacets """ - params: Optional[StrictStr] = Field( - default="", description="Search parameters as a URL-encoded query string." - ) - query: Optional[StrictStr] = Field(default="", description="Search query.") - similar_query: Optional[StrictStr] = Field( - default="", - description="Keywords to be used instead of the search query to conduct a more broader search. Using the `similarQuery` parameter changes other settings: - `queryType` is set to `prefixNone`. - `removeStopWords` is set to true. - `words` is set as the first ranking criterion. - All remaining words are treated as `optionalWords`. Since the `similarQuery` is supposed to do a broad search, they usually return many results. Combine it with `filters` to narrow down the list of results. ", - alias="similarQuery", - ) - filters: Optional[StrictStr] = Field( - default=None, - description="Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). ", - ) + params: Optional[str] = Field(default=None, alias="params") + """ Search parameters as a URL-encoded query string. """ + query: Optional[str] = Field(default=None, alias="query") + """ Search query. """ + similar_query: Optional[str] = Field(default=None, alias="similarQuery") + """ Keywords to be used instead of the search query to conduct a more broader search. Using the `similarQuery` parameter changes other settings: - `queryType` is set to `prefixNone`. - `removeStopWords` is set to true. - `words` is set as the first ranking criterion. - All remaining words are treated as `optionalWords`. Since the `similarQuery` is supposed to do a broad search, they usually return many results. Combine it with `filters` to narrow down the list of results. """ + filters: Optional[str] = Field(default=None, alias="filters") + """ Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). """ facet_filters: Optional[FacetFilters] = Field(default=None, alias="facetFilters") optional_filters: Optional[OptionalFilters] = Field( default=None, alias="optionalFilters" @@ -79,383 +66,234 @@ class SearchForFacets(BaseModel): default=None, alias="numericFilters" ) tag_filters: Optional[TagFilters] = Field(default=None, alias="tagFilters") - sum_or_filters_scores: Optional[StrictBool] = Field( - default=False, - description="Whether to sum all filter scores. If true, all filter scores are summed. Otherwise, the maximum filter score is kept. For more information, see [filter scores](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/#accumulating-scores-with-sumorfiltersscores). ", - alias="sumOrFiltersScores", - ) - restrict_searchable_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Restricts a search to a subset of your searchable attributes. Attribute names are case-sensitive. ", - alias="restrictSearchableAttributes", - ) - facets: Optional[List[StrictStr]] = Field( - default=None, - description="Facets for which to retrieve facet values that match the search criteria and the number of matching facet values. To retrieve all facets, use the wildcard character `*`. For more information, see [facets](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#contextual-facet-values-and-counts). ", - ) - faceting_after_distinct: Optional[StrictBool] = Field( - default=False, - description="Whether faceting should be applied after deduplication with `distinct`. This leads to accurate facet counts when using faceting in combination with `distinct`. It's usually better to use `afterDistinct` modifiers in the `attributesForFaceting` setting, as `facetingAfterDistinct` only computes correct facet counts if all records have the same facet values for the `attributeForDistinct`. ", - alias="facetingAfterDistinct", - ) - page: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=0, description="Page of search results to retrieve." - ) - offset: Optional[StrictInt] = Field( - default=None, description="Position of the first hit to retrieve." - ) - length: Optional[Annotated[int, Field(le=1000, strict=True, ge=0)]] = Field( - default=None, - description="Number of hits to retrieve (used in combination with `offset`).", - ) - around_lat_lng: Optional[StrictStr] = Field( - default="", - description="Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude. Only records included within circle around this central location are included in the results. The radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings. This parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`. ", - alias="aroundLatLng", - ) - around_lat_lng_via_ip: Optional[StrictBool] = Field( - default=False, - description="Whether to obtain the coordinates from the request's IP address.", - alias="aroundLatLngViaIP", - ) + sum_or_filters_scores: Optional[bool] = Field( + default=None, alias="sumOrFiltersScores" + ) + """ Whether to sum all filter scores. If true, all filter scores are summed. Otherwise, the maximum filter score is kept. For more information, see [filter scores](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/#accumulating-scores-with-sumorfiltersscores). """ + restrict_searchable_attributes: Optional[List[str]] = Field( + default=None, alias="restrictSearchableAttributes" + ) + """ Restricts a search to a subset of your searchable attributes. Attribute names are case-sensitive. """ + facets: Optional[List[str]] = Field(default=None, alias="facets") + """ Facets for which to retrieve facet values that match the search criteria and the number of matching facet values. To retrieve all facets, use the wildcard character `*`. For more information, see [facets](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#contextual-facet-values-and-counts). """ + faceting_after_distinct: Optional[bool] = Field( + default=None, alias="facetingAfterDistinct" + ) + """ Whether faceting should be applied after deduplication with `distinct`. This leads to accurate facet counts when using faceting in combination with `distinct`. It's usually better to use `afterDistinct` modifiers in the `attributesForFaceting` setting, as `facetingAfterDistinct` only computes correct facet counts if all records have the same facet values for the `attributeForDistinct`. """ + page: Optional[int] = Field(default=None, alias="page") + """ Page of search results to retrieve. """ + offset: Optional[int] = Field(default=None, alias="offset") + """ Position of the first hit to retrieve. """ + length: Optional[int] = Field(default=None, alias="length") + """ Number of hits to retrieve (used in combination with `offset`). """ + around_lat_lng: Optional[str] = Field(default=None, alias="aroundLatLng") + """ Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude. Only records included within circle around this central location are included in the results. The radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings. This parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`. """ + around_lat_lng_via_ip: Optional[bool] = Field( + default=None, alias="aroundLatLngViaIP" + ) + """ Whether to obtain the coordinates from the request's IP address. """ around_radius: Optional[AroundRadius] = Field(default=None, alias="aroundRadius") around_precision: Optional[AroundPrecision] = Field( default=None, alias="aroundPrecision" ) - minimum_around_radius: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field( - default=None, - description="Minimum radius (in meters) for a search around a location when `aroundRadius` isn't set.", - alias="minimumAroundRadius", - ) - inside_bounding_box: Optional[ - List[ - Annotated[ - List[Union[StrictFloat, StrictInt]], Field(min_length=4, max_length=4) - ] - ] - ] = Field( - default=None, - description="Coordinates for a rectangular area in which to search. Each bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair: `[p1 lat, p1 long, p2 lat, p2 long]`. Provide multiple bounding boxes as nested arrays. For more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). ", - alias="insideBoundingBox", - ) - inside_polygon: Optional[ - List[ - Annotated[ - List[Union[StrictFloat, StrictInt]], - Field(min_length=6, max_length=20000), - ] - ] - ] = Field( - default=None, - description="Coordinates of a polygon in which to search. Polygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude. Provide multiple polygons as nested arrays. For more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). This parameter is ignored if you also specify `insideBoundingBox`. ", - alias="insidePolygon", + minimum_around_radius: Optional[int] = Field( + default=None, alias="minimumAroundRadius" ) - natural_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="ISO language codes that adjust settings that are useful for processing natural language queries (as opposed to keyword searches): - Sets `removeStopWords` and `ignorePlurals` to the list of provided languages. - Sets `removeWordsIfNoResults` to `allOptional`. - Adds a `natural_language` attribute to `ruleContexts` and `analyticsTags`. ", - alias="naturalLanguages", - ) - rule_contexts: Optional[List[StrictStr]] = Field( - default=None, - description="Assigns a rule context to the search query. [Rule contexts](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/how-to/customize-search-results-by-platform/#whats-a-context) are strings that you can use to trigger matching rules. ", - alias="ruleContexts", - ) - personalization_impact: Optional[ - Annotated[int, Field(le=100, strict=True, ge=0)] - ] = Field( - default=100, - description="Impact that Personalization should have on this search. The higher this value is, the more Personalization determines the ranking compared to other factors. For more information, see [Understanding Personalization impact](https://www.algolia.com/doc/guides/personalization/personalizing-results/in-depth/configuring-personalization/#understanding-personalization-impact). ", - alias="personalizationImpact", - ) - user_token: Optional[StrictStr] = Field( - default=None, - description="Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - get_ranking_info: Optional[StrictBool] = Field( - default=False, - description="Whether the search response should include detailed ranking information.", - alias="getRankingInfo", - ) - synonyms: Optional[StrictBool] = Field( - default=True, - description="Whether to take into account an index's synonyms for this search.", - ) - click_analytics: Optional[StrictBool] = Field( - default=False, - description="Whether to include a `queryID` attribute in the response. The query ID is a unique identifier for a search query and is required for tracking [click and conversion events](https://www.algolia.com/guides/sending-events/getting-started/). ", - alias="clickAnalytics", - ) - analytics: Optional[StrictBool] = Field( - default=True, description="Whether this search will be included in Analytics." - ) - analytics_tags: Optional[List[StrictStr]] = Field( - default=None, - description="Tags to apply to the query for [segmenting analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/).", - alias="analyticsTags", - ) - percentile_computation: Optional[StrictBool] = Field( - default=True, - description="Whether to include this search when calculating processing-time percentiles.", - alias="percentileComputation", - ) - enable_ab_test: Optional[StrictBool] = Field( - default=True, - description="Whether to enable A/B testing for this search.", - alias="enableABTest", - ) - attributes_to_retrieve: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `["*", "-ATTRIBUTE"]`. - The `objectID` attribute is always included. ', - alias="attributesToRetrieve", - ) - ranking: Optional[List[StrictStr]] = Field( - default=None, - description='Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they\'re specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc("ATTRIBUTE")`. Sort the index by the values of an attribute, in ascending order. - `desc("ATTRIBUTE")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). ', - ) - custom_ranking: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes to use as [custom ranking](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/). Attribute names are case-sensitive. The custom ranking attributes decide which items are shown first if the other ranking criteria are equal. Records with missing values for your selected custom ranking attributes are always sorted last. Boolean attributes are sorted based on their alphabetical order. **Modifiers** - `asc("ATTRIBUTE")`. Sort the index by the values of an attribute, in ascending order. - `desc("ATTRIBUTE")`. Sort the index by the values of an attribute, in descending order. If you use two or more custom ranking attributes, [reduce the precision](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/how-to/controlling-custom-ranking-metrics-precision/) of your first attributes, or the other attributes will never be applied. ', - alias="customRanking", - ) - relevancy_strictness: Optional[StrictInt] = Field( - default=100, - description="Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. ", - alias="relevancyStrictness", - ) - attributes_to_highlight: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). ", - alias="attributesToHighlight", - ) - attributes_to_snippet: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. ", - alias="attributesToSnippet", - ) - highlight_pre_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert before the highlighted parts in all highlighted results and snippets.", - alias="highlightPreTag", - ) - highlight_post_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert after the highlighted parts in all highlighted results and snippets.", - alias="highlightPostTag", - ) - snippet_ellipsis_text: Optional[StrictStr] = Field( - default="…", - description="String used as an ellipsis indicator when a snippet is truncated.", - alias="snippetEllipsisText", - ) - restrict_highlight_and_snippet_arrays: Optional[StrictBool] = Field( - default=False, - description="Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. ", - alias="restrictHighlightAndSnippetArrays", - ) - hits_per_page: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = Field( - default=20, description="Number of hits per page.", alias="hitsPerPage" - ) - min_word_sizefor1_typo: Optional[StrictInt] = Field( - default=4, - description="Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor1Typo", - ) - min_word_sizefor2_typos: Optional[StrictInt] = Field( - default=8, - description="Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor2Typos", + """ Minimum radius (in meters) for a search around a location when `aroundRadius` isn't set. """ + inside_bounding_box: Optional[List[List[float]]] = Field( + default=None, alias="insideBoundingBox" + ) + """ Coordinates for a rectangular area in which to search. Each bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair: `[p1 lat, p1 long, p2 lat, p2 long]`. Provide multiple bounding boxes as nested arrays. For more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). """ + inside_polygon: Optional[List[List[float]]] = Field( + default=None, alias="insidePolygon" ) + """ Coordinates of a polygon in which to search. Polygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude. Provide multiple polygons as nested arrays. For more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). This parameter is ignored if you also specify `insideBoundingBox`. """ + natural_languages: Optional[List[SupportedLanguage]] = Field( + default=None, alias="naturalLanguages" + ) + """ ISO language codes that adjust settings that are useful for processing natural language queries (as opposed to keyword searches): - Sets `removeStopWords` and `ignorePlurals` to the list of provided languages. - Sets `removeWordsIfNoResults` to `allOptional`. - Adds a `natural_language` attribute to `ruleContexts` and `analyticsTags`. """ + rule_contexts: Optional[List[str]] = Field(default=None, alias="ruleContexts") + """ Assigns a rule context to the search query. [Rule contexts](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/how-to/customize-search-results-by-platform/#whats-a-context) are strings that you can use to trigger matching rules. """ + personalization_impact: Optional[int] = Field( + default=None, alias="personalizationImpact" + ) + """ Impact that Personalization should have on this search. The higher this value is, the more Personalization determines the ranking compared to other factors. For more information, see [Understanding Personalization impact](https://www.algolia.com/doc/guides/personalization/personalizing-results/in-depth/configuring-personalization/#understanding-personalization-impact). """ + user_token: Optional[str] = Field(default=None, alias="userToken") + """ Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + get_ranking_info: Optional[bool] = Field(default=None, alias="getRankingInfo") + """ Whether the search response should include detailed ranking information. """ + synonyms: Optional[bool] = Field(default=None, alias="synonyms") + """ Whether to take into account an index's synonyms for this search. """ + click_analytics: Optional[bool] = Field(default=None, alias="clickAnalytics") + """ Whether to include a `queryID` attribute in the response. The query ID is a unique identifier for a search query and is required for tracking [click and conversion events](https://www.algolia.com/guides/sending-events/getting-started/). """ + analytics: Optional[bool] = Field(default=None, alias="analytics") + """ Whether this search will be included in Analytics. """ + analytics_tags: Optional[List[str]] = Field(default=None, alias="analyticsTags") + """ Tags to apply to the query for [segmenting analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). """ + percentile_computation: Optional[bool] = Field( + default=None, alias="percentileComputation" + ) + """ Whether to include this search when calculating processing-time percentiles. """ + enable_ab_test: Optional[bool] = Field(default=None, alias="enableABTest") + """ Whether to enable A/B testing for this search. """ + attributes_to_retrieve: Optional[List[str]] = Field( + default=None, alias="attributesToRetrieve" + ) + """ Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `[\"*\", \"-ATTRIBUTE\"]`. - The `objectID` attribute is always included. """ + ranking: Optional[List[str]] = Field(default=None, alias="ranking") + """ Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they're specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in ascending order. - `desc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). """ + custom_ranking: Optional[List[str]] = Field(default=None, alias="customRanking") + """ Attributes to use as [custom ranking](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/). Attribute names are case-sensitive. The custom ranking attributes decide which items are shown first if the other ranking criteria are equal. Records with missing values for your selected custom ranking attributes are always sorted last. Boolean attributes are sorted based on their alphabetical order. **Modifiers** - `asc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in ascending order. - `desc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in descending order. If you use two or more custom ranking attributes, [reduce the precision](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/how-to/controlling-custom-ranking-metrics-precision/) of your first attributes, or the other attributes will never be applied. """ + relevancy_strictness: Optional[int] = Field( + default=None, alias="relevancyStrictness" + ) + """ Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. """ + attributes_to_highlight: Optional[List[str]] = Field( + default=None, alias="attributesToHighlight" + ) + """ Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). """ + attributes_to_snippet: Optional[List[str]] = Field( + default=None, alias="attributesToSnippet" + ) + """ Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. """ + highlight_pre_tag: Optional[str] = Field(default=None, alias="highlightPreTag") + """ HTML tag to insert before the highlighted parts in all highlighted results and snippets. """ + highlight_post_tag: Optional[str] = Field(default=None, alias="highlightPostTag") + """ HTML tag to insert after the highlighted parts in all highlighted results and snippets. """ + snippet_ellipsis_text: Optional[str] = Field( + default=None, alias="snippetEllipsisText" + ) + """ String used as an ellipsis indicator when a snippet is truncated. """ + restrict_highlight_and_snippet_arrays: Optional[bool] = Field( + default=None, alias="restrictHighlightAndSnippetArrays" + ) + """ Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. """ + hits_per_page: Optional[int] = Field(default=None, alias="hitsPerPage") + """ Number of hits per page. """ + min_word_sizefor1_typo: Optional[int] = Field( + default=None, alias="minWordSizefor1Typo" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ + min_word_sizefor2_typos: Optional[int] = Field( + default=None, alias="minWordSizefor2Typos" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ typo_tolerance: Optional[TypoTolerance] = Field(default=None, alias="typoTolerance") - allow_typos_on_numeric_tokens: Optional[StrictBool] = Field( - default=True, - description="Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. ", - alias="allowTyposOnNumericTokens", + allow_typos_on_numeric_tokens: Optional[bool] = Field( + default=None, alias="allowTyposOnNumericTokens" ) - disable_typo_tolerance_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. ", - alias="disableTypoToleranceOnAttributes", + """ Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. """ + disable_typo_tolerance_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableTypoToleranceOnAttributes" ) + """ Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. """ ignore_plurals: Optional[IgnorePlurals] = Field(default=None, alias="ignorePlurals") remove_stop_words: Optional[RemoveStopWords] = Field( default=None, alias="removeStopWords" ) - keep_diacritics_on_characters: Optional[StrictStr] = Field( - default="", - description="Characters for which diacritics should be preserved. By default, Algolia removes diacritics from letters. For example, `é` becomes `e`. If this causes issues in your search, you can specify characters that should keep their diacritics. ", - alias="keepDiacriticsOnCharacters", + keep_diacritics_on_characters: Optional[str] = Field( + default=None, alias="keepDiacriticsOnCharacters" ) + """ Characters for which diacritics should be preserved. By default, Algolia removes diacritics from letters. For example, `é` becomes `e`. If this causes issues in your search, you can specify characters that should keep their diacritics. """ query_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). ", - alias="queryLanguages", - ) - decompound_query: Optional[StrictBool] = Field( - default=True, - description="Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). ", - alias="decompoundQuery", - ) - enable_rules: Optional[StrictBool] = Field( - default=True, description="Whether to enable rules.", alias="enableRules" + default=None, alias="queryLanguages" ) - enable_personalization: Optional[StrictBool] = Field( - default=False, - description="Whether to enable Personalization.", - alias="enablePersonalization", + """ Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). """ + decompound_query: Optional[bool] = Field(default=None, alias="decompoundQuery") + """ Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). """ + enable_rules: Optional[bool] = Field(default=None, alias="enableRules") + """ Whether to enable rules. """ + enable_personalization: Optional[bool] = Field( + default=None, alias="enablePersonalization" ) + """ Whether to enable Personalization. """ query_type: Optional[QueryType] = Field(default=None, alias="queryType") remove_words_if_no_results: Optional[RemoveWordsIfNoResults] = Field( default=None, alias="removeWordsIfNoResults" ) - mode: Optional[Mode] = None + mode: Optional[Mode] = Field(default=None, alias="mode") semantic_search: Optional[SemanticSearch] = Field( default=None, alias="semanticSearch" ) - advanced_syntax: Optional[StrictBool] = Field( - default=False, - description="Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. ", - alias="advancedSyntax", - ) - optional_words: Optional[List[StrictStr]] = Field( - default=None, - description='Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn\'t include the optional words. For example, if the search query is "action video" and "video" is an optional word, the search engine runs two queries. One for "action video" and one for "action". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). ', - alias="optionalWords", - ) - disable_exact_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. ", - alias="disableExactOnAttributes", + advanced_syntax: Optional[bool] = Field(default=None, alias="advancedSyntax") + """ Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. """ + optional_words: Optional[List[str]] = Field(default=None, alias="optionalWords") + """ Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn't include the optional words. For example, if the search query is \"action video\" and \"video\" is an optional word, the search engine runs two queries. One for \"action video\" and one for \"action\". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). """ + disable_exact_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableExactOnAttributes" ) + """ Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. """ exact_on_single_word_query: Optional[ExactOnSingleWordQuery] = Field( default=None, alias="exactOnSingleWordQuery" ) alternatives_as_exact: Optional[List[AlternativesAsExact]] = Field( - default=None, - description='Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as "NY/NYC" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as "NY/New York" are considered exact matches. ', - alias="alternativesAsExact", + default=None, alias="alternativesAsExact" ) + """ Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as \"NY/NYC\" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as \"NY/New York\" are considered exact matches. """ advanced_syntax_features: Optional[List[AdvancedSyntaxFeatures]] = Field( - default=None, - description='Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue "iPhone case"` only returns records with the exact string "iPhone case". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain "search" but not "engine". This setting only has an effect if `advancedSyntax` is true. ', - alias="advancedSyntaxFeatures", - ) - distinct: Optional[Distinct] = None - replace_synonyms_in_highlight: Optional[StrictBool] = Field( - default=False, - description='Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either "home" or "house" are included in the search results, and either "home" or "house" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of "house" are replaced by "home" in the highlighted response. ', - alias="replaceSynonymsInHighlight", - ) - min_proximity: Optional[Annotated[int, Field(le=7, strict=True, ge=1)]] = Field( - default=1, - description="Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. ", - alias="minProximity", - ) - response_fields: Optional[List[StrictStr]] = Field( - default=None, - description="Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. ", - alias="responseFields", - ) - max_facet_hits: Optional[Annotated[int, Field(le=100, strict=True)]] = Field( - default=10, - description="Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values).", - alias="maxFacetHits", - ) - max_values_per_facet: Optional[Annotated[int, Field(le=1000, strict=True)]] = Field( - default=100, - description="Maximum number of facet values to return for each facet.", - alias="maxValuesPerFacet", - ) - sort_facet_values_by: Optional[StrictStr] = Field( - default="count", - description="Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). ", - alias="sortFacetValuesBy", - ) - attribute_criteria_computed_by_min_proximity: Optional[StrictBool] = Field( - default=False, - description="Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. ", - alias="attributeCriteriaComputedByMinProximity", - ) + default=None, alias="advancedSyntaxFeatures" + ) + """ Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue \"iPhone case\"` only returns records with the exact string \"iPhone case\". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain \"search\" but not \"engine\". This setting only has an effect if `advancedSyntax` is true. """ + distinct: Optional[Distinct] = Field(default=None, alias="distinct") + replace_synonyms_in_highlight: Optional[bool] = Field( + default=None, alias="replaceSynonymsInHighlight" + ) + """ Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either \"home\" or \"house\" are included in the search results, and either \"home\" or \"house\" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of \"house\" are replaced by \"home\" in the highlighted response. """ + min_proximity: Optional[int] = Field(default=None, alias="minProximity") + """ Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. """ + response_fields: Optional[List[str]] = Field(default=None, alias="responseFields") + """ Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. """ + max_facet_hits: Optional[int] = Field(default=None, alias="maxFacetHits") + """ Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values). """ + max_values_per_facet: Optional[int] = Field(default=None, alias="maxValuesPerFacet") + """ Maximum number of facet values to return for each facet. """ + sort_facet_values_by: Optional[str] = Field(default=None, alias="sortFacetValuesBy") + """ Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). """ + attribute_criteria_computed_by_min_proximity: Optional[bool] = Field( + default=None, alias="attributeCriteriaComputedByMinProximity" + ) + """ Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. """ rendering_content: Optional[RenderingContent] = Field( default=None, alias="renderingContent" ) - enable_re_ranking: Optional[StrictBool] = Field( - default=True, - description="Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. ", - alias="enableReRanking", - ) + enable_re_ranking: Optional[bool] = Field(default=None, alias="enableReRanking") + """ Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. """ re_ranking_apply_filter: Optional[ReRankingApplyFilter] = Field( default=None, alias="reRankingApplyFilter" ) - facet: StrictStr = Field(description="Facet name.") - index_name: StrictStr = Field( - description="Index name (case-sensitive).", alias="indexName" - ) - facet_query: Optional[StrictStr] = Field( - default="", - description="Text to search inside the facet's values.", - alias="facetQuery", - ) - type: SearchTypeFacet + facet: str = Field(alias="facet") + """ Facet name. """ + index_name: str = Field(alias="indexName") + """ Index name (case-sensitive). """ + facet_query: Optional[str] = Field(default=None, alias="facetQuery") + """ Text to search inside the facet's values. """ + type: SearchTypeFacet = Field(alias="type") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchForFacets from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.facet_filters: - _dict["facetFilters"] = self.facet_filters.to_dict() - if self.optional_filters: - _dict["optionalFilters"] = self.optional_filters.to_dict() - if self.numeric_filters: - _dict["numericFilters"] = self.numeric_filters.to_dict() - if self.tag_filters: - _dict["tagFilters"] = self.tag_filters.to_dict() - if self.around_radius: - _dict["aroundRadius"] = self.around_radius.to_dict() - if self.around_precision: - _dict["aroundPrecision"] = self.around_precision.to_dict() - if self.typo_tolerance: - _dict["typoTolerance"] = self.typo_tolerance.to_dict() - if self.ignore_plurals: - _dict["ignorePlurals"] = self.ignore_plurals.to_dict() - if self.remove_stop_words: - _dict["removeStopWords"] = self.remove_stop_words.to_dict() - if self.semantic_search: - _dict["semanticSearch"] = self.semantic_search.to_dict() - if self.distinct: - _dict["distinct"] = self.distinct.to_dict() - if self.rendering_content: - _dict["renderingContent"] = self.rendering_content.to_dict() - if self.re_ranking_apply_filter: - _dict["reRankingApplyFilter"] = self.re_ranking_apply_filter.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchForFacets from a dict""" if obj is None: return None @@ -463,147 +301,79 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "params": obj.get("params"), - "query": obj.get("query"), - "similarQuery": obj.get("similarQuery"), - "filters": obj.get("filters"), - "facetFilters": ( - FacetFilters.from_dict(obj.get("facetFilters")) - if obj.get("facetFilters") is not None - else None - ), - "optionalFilters": ( - OptionalFilters.from_dict(obj.get("optionalFilters")) - if obj.get("optionalFilters") is not None - else None - ), - "numericFilters": ( - NumericFilters.from_dict(obj.get("numericFilters")) - if obj.get("numericFilters") is not None - else None - ), - "tagFilters": ( - TagFilters.from_dict(obj.get("tagFilters")) - if obj.get("tagFilters") is not None - else None - ), - "sumOrFiltersScores": obj.get("sumOrFiltersScores"), - "restrictSearchableAttributes": obj.get("restrictSearchableAttributes"), - "facets": obj.get("facets"), - "facetingAfterDistinct": obj.get("facetingAfterDistinct"), - "page": obj.get("page"), - "offset": obj.get("offset"), - "length": obj.get("length"), - "aroundLatLng": obj.get("aroundLatLng"), - "aroundLatLngViaIP": obj.get("aroundLatLngViaIP"), - "aroundRadius": ( - AroundRadius.from_dict(obj.get("aroundRadius")) - if obj.get("aroundRadius") is not None - else None - ), - "aroundPrecision": ( - AroundPrecision.from_dict(obj.get("aroundPrecision")) - if obj.get("aroundPrecision") is not None - else None - ), - "minimumAroundRadius": obj.get("minimumAroundRadius"), - "insideBoundingBox": obj.get("insideBoundingBox"), - "insidePolygon": obj.get("insidePolygon"), - "naturalLanguages": obj.get("naturalLanguages"), - "ruleContexts": obj.get("ruleContexts"), - "personalizationImpact": obj.get("personalizationImpact"), - "userToken": obj.get("userToken"), - "getRankingInfo": obj.get("getRankingInfo"), - "synonyms": obj.get("synonyms"), - "clickAnalytics": obj.get("clickAnalytics"), - "analytics": obj.get("analytics"), - "analyticsTags": obj.get("analyticsTags"), - "percentileComputation": obj.get("percentileComputation"), - "enableABTest": obj.get("enableABTest"), - "attributesToRetrieve": obj.get("attributesToRetrieve"), - "ranking": obj.get("ranking"), - "customRanking": obj.get("customRanking"), - "relevancyStrictness": obj.get("relevancyStrictness"), - "attributesToHighlight": obj.get("attributesToHighlight"), - "attributesToSnippet": obj.get("attributesToSnippet"), - "highlightPreTag": obj.get("highlightPreTag"), - "highlightPostTag": obj.get("highlightPostTag"), - "snippetEllipsisText": obj.get("snippetEllipsisText"), - "restrictHighlightAndSnippetArrays": obj.get( - "restrictHighlightAndSnippetArrays" - ), - "hitsPerPage": obj.get("hitsPerPage"), - "minWordSizefor1Typo": obj.get("minWordSizefor1Typo"), - "minWordSizefor2Typos": obj.get("minWordSizefor2Typos"), - "typoTolerance": ( - TypoTolerance.from_dict(obj.get("typoTolerance")) - if obj.get("typoTolerance") is not None - else None - ), - "allowTyposOnNumericTokens": obj.get("allowTyposOnNumericTokens"), - "disableTypoToleranceOnAttributes": obj.get( - "disableTypoToleranceOnAttributes" - ), - "ignorePlurals": ( - IgnorePlurals.from_dict(obj.get("ignorePlurals")) - if obj.get("ignorePlurals") is not None - else None - ), - "removeStopWords": ( - RemoveStopWords.from_dict(obj.get("removeStopWords")) - if obj.get("removeStopWords") is not None - else None - ), - "keepDiacriticsOnCharacters": obj.get("keepDiacriticsOnCharacters"), - "queryLanguages": obj.get("queryLanguages"), - "decompoundQuery": obj.get("decompoundQuery"), - "enableRules": obj.get("enableRules"), - "enablePersonalization": obj.get("enablePersonalization"), - "queryType": obj.get("queryType"), - "removeWordsIfNoResults": obj.get("removeWordsIfNoResults"), - "mode": obj.get("mode"), - "semanticSearch": ( - SemanticSearch.from_dict(obj.get("semanticSearch")) - if obj.get("semanticSearch") is not None - else None - ), - "advancedSyntax": obj.get("advancedSyntax"), - "optionalWords": obj.get("optionalWords"), - "disableExactOnAttributes": obj.get("disableExactOnAttributes"), - "exactOnSingleWordQuery": obj.get("exactOnSingleWordQuery"), - "alternativesAsExact": obj.get("alternativesAsExact"), - "advancedSyntaxFeatures": obj.get("advancedSyntaxFeatures"), - "distinct": ( - Distinct.from_dict(obj.get("distinct")) - if obj.get("distinct") is not None - else None - ), - "replaceSynonymsInHighlight": obj.get("replaceSynonymsInHighlight"), - "minProximity": obj.get("minProximity"), - "responseFields": obj.get("responseFields"), - "maxFacetHits": obj.get("maxFacetHits"), - "maxValuesPerFacet": obj.get("maxValuesPerFacet"), - "sortFacetValuesBy": obj.get("sortFacetValuesBy"), - "attributeCriteriaComputedByMinProximity": obj.get( - "attributeCriteriaComputedByMinProximity" - ), - "renderingContent": ( - RenderingContent.from_dict(obj.get("renderingContent")) - if obj.get("renderingContent") is not None - else None - ), - "enableReRanking": obj.get("enableReRanking"), - "reRankingApplyFilter": ( - ReRankingApplyFilter.from_dict(obj.get("reRankingApplyFilter")) - if obj.get("reRankingApplyFilter") is not None - else None - ), - "facet": obj.get("facet"), - "indexName": obj.get("indexName"), - "facetQuery": obj.get("facetQuery"), - "type": obj.get("type"), - } + obj["facetFilters"] = ( + FacetFilters.from_dict(obj["facetFilters"]) + if obj.get("facetFilters") is not None + else None + ) + obj["optionalFilters"] = ( + OptionalFilters.from_dict(obj["optionalFilters"]) + if obj.get("optionalFilters") is not None + else None + ) + obj["numericFilters"] = ( + NumericFilters.from_dict(obj["numericFilters"]) + if obj.get("numericFilters") is not None + else None + ) + obj["tagFilters"] = ( + TagFilters.from_dict(obj["tagFilters"]) + if obj.get("tagFilters") is not None + else None + ) + obj["aroundRadius"] = ( + AroundRadius.from_dict(obj["aroundRadius"]) + if obj.get("aroundRadius") is not None + else None ) - return _obj + obj["aroundPrecision"] = ( + AroundPrecision.from_dict(obj["aroundPrecision"]) + if obj.get("aroundPrecision") is not None + else None + ) + obj["naturalLanguages"] = obj.get("naturalLanguages") + obj["typoTolerance"] = ( + TypoTolerance.from_dict(obj["typoTolerance"]) + if obj.get("typoTolerance") is not None + else None + ) + obj["ignorePlurals"] = ( + IgnorePlurals.from_dict(obj["ignorePlurals"]) + if obj.get("ignorePlurals") is not None + else None + ) + obj["removeStopWords"] = ( + RemoveStopWords.from_dict(obj["removeStopWords"]) + if obj.get("removeStopWords") is not None + else None + ) + obj["queryLanguages"] = obj.get("queryLanguages") + obj["queryType"] = obj.get("queryType") + obj["removeWordsIfNoResults"] = obj.get("removeWordsIfNoResults") + obj["mode"] = obj.get("mode") + obj["semanticSearch"] = ( + SemanticSearch.from_dict(obj["semanticSearch"]) + if obj.get("semanticSearch") is not None + else None + ) + obj["exactOnSingleWordQuery"] = obj.get("exactOnSingleWordQuery") + obj["alternativesAsExact"] = obj.get("alternativesAsExact") + obj["advancedSyntaxFeatures"] = obj.get("advancedSyntaxFeatures") + obj["distinct"] = ( + Distinct.from_dict(obj["distinct"]) + if obj.get("distinct") is not None + else None + ) + obj["renderingContent"] = ( + RenderingContent.from_dict(obj["renderingContent"]) + if obj.get("renderingContent") is not None + else None + ) + obj["reRankingApplyFilter"] = ( + ReRankingApplyFilter.from_dict(obj["reRankingApplyFilter"]) + if obj.get("reRankingApplyFilter") is not None + else None + ) + obj["type"] = obj.get("type") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/search_for_hits.py b/algoliasearch/search/models/search_for_hits.py index d454eab52..9fc5e3d7a 100644 --- a/algoliasearch/search/models/search_for_hits.py +++ b/algoliasearch/search/models/search_for_hits.py @@ -8,22 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional -from pydantic import ( - BaseModel, - ConfigDict, - Field, - StrictBool, - StrictFloat, - StrictInt, - StrictStr, -) +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.advanced_syntax_features import AdvancedSyntaxFeatures @@ -58,19 +50,14 @@ class SearchForHits(BaseModel): SearchForHits """ - params: Optional[StrictStr] = Field( - default="", description="Search parameters as a URL-encoded query string." - ) - query: Optional[StrictStr] = Field(default="", description="Search query.") - similar_query: Optional[StrictStr] = Field( - default="", - description="Keywords to be used instead of the search query to conduct a more broader search. Using the `similarQuery` parameter changes other settings: - `queryType` is set to `prefixNone`. - `removeStopWords` is set to true. - `words` is set as the first ranking criterion. - All remaining words are treated as `optionalWords`. Since the `similarQuery` is supposed to do a broad search, they usually return many results. Combine it with `filters` to narrow down the list of results. ", - alias="similarQuery", - ) - filters: Optional[StrictStr] = Field( - default=None, - description="Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). ", - ) + params: Optional[str] = Field(default=None, alias="params") + """ Search parameters as a URL-encoded query string. """ + query: Optional[str] = Field(default=None, alias="query") + """ Search query. """ + similar_query: Optional[str] = Field(default=None, alias="similarQuery") + """ Keywords to be used instead of the search query to conduct a more broader search. Using the `similarQuery` parameter changes other settings: - `queryType` is set to `prefixNone`. - `removeStopWords` is set to true. - `words` is set as the first ranking criterion. - All remaining words are treated as `optionalWords`. Since the `similarQuery` is supposed to do a broad search, they usually return many results. Combine it with `filters` to narrow down the list of results. """ + filters: Optional[str] = Field(default=None, alias="filters") + """ Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). """ facet_filters: Optional[FacetFilters] = Field(default=None, alias="facetFilters") optional_filters: Optional[OptionalFilters] = Field( default=None, alias="optionalFilters" @@ -79,377 +66,230 @@ class SearchForHits(BaseModel): default=None, alias="numericFilters" ) tag_filters: Optional[TagFilters] = Field(default=None, alias="tagFilters") - sum_or_filters_scores: Optional[StrictBool] = Field( - default=False, - description="Whether to sum all filter scores. If true, all filter scores are summed. Otherwise, the maximum filter score is kept. For more information, see [filter scores](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/#accumulating-scores-with-sumorfiltersscores). ", - alias="sumOrFiltersScores", - ) - restrict_searchable_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Restricts a search to a subset of your searchable attributes. Attribute names are case-sensitive. ", - alias="restrictSearchableAttributes", - ) - facets: Optional[List[StrictStr]] = Field( - default=None, - description="Facets for which to retrieve facet values that match the search criteria and the number of matching facet values. To retrieve all facets, use the wildcard character `*`. For more information, see [facets](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#contextual-facet-values-and-counts). ", - ) - faceting_after_distinct: Optional[StrictBool] = Field( - default=False, - description="Whether faceting should be applied after deduplication with `distinct`. This leads to accurate facet counts when using faceting in combination with `distinct`. It's usually better to use `afterDistinct` modifiers in the `attributesForFaceting` setting, as `facetingAfterDistinct` only computes correct facet counts if all records have the same facet values for the `attributeForDistinct`. ", - alias="facetingAfterDistinct", - ) - page: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=0, description="Page of search results to retrieve." - ) - offset: Optional[StrictInt] = Field( - default=None, description="Position of the first hit to retrieve." - ) - length: Optional[Annotated[int, Field(le=1000, strict=True, ge=0)]] = Field( - default=None, - description="Number of hits to retrieve (used in combination with `offset`).", - ) - around_lat_lng: Optional[StrictStr] = Field( - default="", - description="Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude. Only records included within circle around this central location are included in the results. The radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings. This parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`. ", - alias="aroundLatLng", - ) - around_lat_lng_via_ip: Optional[StrictBool] = Field( - default=False, - description="Whether to obtain the coordinates from the request's IP address.", - alias="aroundLatLngViaIP", - ) + sum_or_filters_scores: Optional[bool] = Field( + default=None, alias="sumOrFiltersScores" + ) + """ Whether to sum all filter scores. If true, all filter scores are summed. Otherwise, the maximum filter score is kept. For more information, see [filter scores](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/#accumulating-scores-with-sumorfiltersscores). """ + restrict_searchable_attributes: Optional[List[str]] = Field( + default=None, alias="restrictSearchableAttributes" + ) + """ Restricts a search to a subset of your searchable attributes. Attribute names are case-sensitive. """ + facets: Optional[List[str]] = Field(default=None, alias="facets") + """ Facets for which to retrieve facet values that match the search criteria and the number of matching facet values. To retrieve all facets, use the wildcard character `*`. For more information, see [facets](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#contextual-facet-values-and-counts). """ + faceting_after_distinct: Optional[bool] = Field( + default=None, alias="facetingAfterDistinct" + ) + """ Whether faceting should be applied after deduplication with `distinct`. This leads to accurate facet counts when using faceting in combination with `distinct`. It's usually better to use `afterDistinct` modifiers in the `attributesForFaceting` setting, as `facetingAfterDistinct` only computes correct facet counts if all records have the same facet values for the `attributeForDistinct`. """ + page: Optional[int] = Field(default=None, alias="page") + """ Page of search results to retrieve. """ + offset: Optional[int] = Field(default=None, alias="offset") + """ Position of the first hit to retrieve. """ + length: Optional[int] = Field(default=None, alias="length") + """ Number of hits to retrieve (used in combination with `offset`). """ + around_lat_lng: Optional[str] = Field(default=None, alias="aroundLatLng") + """ Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude. Only records included within circle around this central location are included in the results. The radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings. This parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`. """ + around_lat_lng_via_ip: Optional[bool] = Field( + default=None, alias="aroundLatLngViaIP" + ) + """ Whether to obtain the coordinates from the request's IP address. """ around_radius: Optional[AroundRadius] = Field(default=None, alias="aroundRadius") around_precision: Optional[AroundPrecision] = Field( default=None, alias="aroundPrecision" ) - minimum_around_radius: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field( - default=None, - description="Minimum radius (in meters) for a search around a location when `aroundRadius` isn't set.", - alias="minimumAroundRadius", - ) - inside_bounding_box: Optional[ - List[ - Annotated[ - List[Union[StrictFloat, StrictInt]], Field(min_length=4, max_length=4) - ] - ] - ] = Field( - default=None, - description="Coordinates for a rectangular area in which to search. Each bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair: `[p1 lat, p1 long, p2 lat, p2 long]`. Provide multiple bounding boxes as nested arrays. For more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). ", - alias="insideBoundingBox", - ) - inside_polygon: Optional[ - List[ - Annotated[ - List[Union[StrictFloat, StrictInt]], - Field(min_length=6, max_length=20000), - ] - ] - ] = Field( - default=None, - description="Coordinates of a polygon in which to search. Polygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude. Provide multiple polygons as nested arrays. For more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). This parameter is ignored if you also specify `insideBoundingBox`. ", - alias="insidePolygon", + minimum_around_radius: Optional[int] = Field( + default=None, alias="minimumAroundRadius" ) - natural_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="ISO language codes that adjust settings that are useful for processing natural language queries (as opposed to keyword searches): - Sets `removeStopWords` and `ignorePlurals` to the list of provided languages. - Sets `removeWordsIfNoResults` to `allOptional`. - Adds a `natural_language` attribute to `ruleContexts` and `analyticsTags`. ", - alias="naturalLanguages", - ) - rule_contexts: Optional[List[StrictStr]] = Field( - default=None, - description="Assigns a rule context to the search query. [Rule contexts](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/how-to/customize-search-results-by-platform/#whats-a-context) are strings that you can use to trigger matching rules. ", - alias="ruleContexts", - ) - personalization_impact: Optional[ - Annotated[int, Field(le=100, strict=True, ge=0)] - ] = Field( - default=100, - description="Impact that Personalization should have on this search. The higher this value is, the more Personalization determines the ranking compared to other factors. For more information, see [Understanding Personalization impact](https://www.algolia.com/doc/guides/personalization/personalizing-results/in-depth/configuring-personalization/#understanding-personalization-impact). ", - alias="personalizationImpact", - ) - user_token: Optional[StrictStr] = Field( - default=None, - description="Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - get_ranking_info: Optional[StrictBool] = Field( - default=False, - description="Whether the search response should include detailed ranking information.", - alias="getRankingInfo", - ) - synonyms: Optional[StrictBool] = Field( - default=True, - description="Whether to take into account an index's synonyms for this search.", - ) - click_analytics: Optional[StrictBool] = Field( - default=False, - description="Whether to include a `queryID` attribute in the response. The query ID is a unique identifier for a search query and is required for tracking [click and conversion events](https://www.algolia.com/guides/sending-events/getting-started/). ", - alias="clickAnalytics", - ) - analytics: Optional[StrictBool] = Field( - default=True, description="Whether this search will be included in Analytics." - ) - analytics_tags: Optional[List[StrictStr]] = Field( - default=None, - description="Tags to apply to the query for [segmenting analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/).", - alias="analyticsTags", - ) - percentile_computation: Optional[StrictBool] = Field( - default=True, - description="Whether to include this search when calculating processing-time percentiles.", - alias="percentileComputation", - ) - enable_ab_test: Optional[StrictBool] = Field( - default=True, - description="Whether to enable A/B testing for this search.", - alias="enableABTest", - ) - attributes_to_retrieve: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `["*", "-ATTRIBUTE"]`. - The `objectID` attribute is always included. ', - alias="attributesToRetrieve", - ) - ranking: Optional[List[StrictStr]] = Field( - default=None, - description='Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they\'re specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc("ATTRIBUTE")`. Sort the index by the values of an attribute, in ascending order. - `desc("ATTRIBUTE")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). ', - ) - custom_ranking: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes to use as [custom ranking](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/). Attribute names are case-sensitive. The custom ranking attributes decide which items are shown first if the other ranking criteria are equal. Records with missing values for your selected custom ranking attributes are always sorted last. Boolean attributes are sorted based on their alphabetical order. **Modifiers** - `asc("ATTRIBUTE")`. Sort the index by the values of an attribute, in ascending order. - `desc("ATTRIBUTE")`. Sort the index by the values of an attribute, in descending order. If you use two or more custom ranking attributes, [reduce the precision](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/how-to/controlling-custom-ranking-metrics-precision/) of your first attributes, or the other attributes will never be applied. ', - alias="customRanking", - ) - relevancy_strictness: Optional[StrictInt] = Field( - default=100, - description="Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. ", - alias="relevancyStrictness", - ) - attributes_to_highlight: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). ", - alias="attributesToHighlight", - ) - attributes_to_snippet: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. ", - alias="attributesToSnippet", - ) - highlight_pre_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert before the highlighted parts in all highlighted results and snippets.", - alias="highlightPreTag", - ) - highlight_post_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert after the highlighted parts in all highlighted results and snippets.", - alias="highlightPostTag", - ) - snippet_ellipsis_text: Optional[StrictStr] = Field( - default="…", - description="String used as an ellipsis indicator when a snippet is truncated.", - alias="snippetEllipsisText", - ) - restrict_highlight_and_snippet_arrays: Optional[StrictBool] = Field( - default=False, - description="Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. ", - alias="restrictHighlightAndSnippetArrays", - ) - hits_per_page: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = Field( - default=20, description="Number of hits per page.", alias="hitsPerPage" - ) - min_word_sizefor1_typo: Optional[StrictInt] = Field( - default=4, - description="Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor1Typo", - ) - min_word_sizefor2_typos: Optional[StrictInt] = Field( - default=8, - description="Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor2Typos", + """ Minimum radius (in meters) for a search around a location when `aroundRadius` isn't set. """ + inside_bounding_box: Optional[List[List[float]]] = Field( + default=None, alias="insideBoundingBox" + ) + """ Coordinates for a rectangular area in which to search. Each bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair: `[p1 lat, p1 long, p2 lat, p2 long]`. Provide multiple bounding boxes as nested arrays. For more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). """ + inside_polygon: Optional[List[List[float]]] = Field( + default=None, alias="insidePolygon" ) + """ Coordinates of a polygon in which to search. Polygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude. Provide multiple polygons as nested arrays. For more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). This parameter is ignored if you also specify `insideBoundingBox`. """ + natural_languages: Optional[List[SupportedLanguage]] = Field( + default=None, alias="naturalLanguages" + ) + """ ISO language codes that adjust settings that are useful for processing natural language queries (as opposed to keyword searches): - Sets `removeStopWords` and `ignorePlurals` to the list of provided languages. - Sets `removeWordsIfNoResults` to `allOptional`. - Adds a `natural_language` attribute to `ruleContexts` and `analyticsTags`. """ + rule_contexts: Optional[List[str]] = Field(default=None, alias="ruleContexts") + """ Assigns a rule context to the search query. [Rule contexts](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/how-to/customize-search-results-by-platform/#whats-a-context) are strings that you can use to trigger matching rules. """ + personalization_impact: Optional[int] = Field( + default=None, alias="personalizationImpact" + ) + """ Impact that Personalization should have on this search. The higher this value is, the more Personalization determines the ranking compared to other factors. For more information, see [Understanding Personalization impact](https://www.algolia.com/doc/guides/personalization/personalizing-results/in-depth/configuring-personalization/#understanding-personalization-impact). """ + user_token: Optional[str] = Field(default=None, alias="userToken") + """ Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + get_ranking_info: Optional[bool] = Field(default=None, alias="getRankingInfo") + """ Whether the search response should include detailed ranking information. """ + synonyms: Optional[bool] = Field(default=None, alias="synonyms") + """ Whether to take into account an index's synonyms for this search. """ + click_analytics: Optional[bool] = Field(default=None, alias="clickAnalytics") + """ Whether to include a `queryID` attribute in the response. The query ID is a unique identifier for a search query and is required for tracking [click and conversion events](https://www.algolia.com/guides/sending-events/getting-started/). """ + analytics: Optional[bool] = Field(default=None, alias="analytics") + """ Whether this search will be included in Analytics. """ + analytics_tags: Optional[List[str]] = Field(default=None, alias="analyticsTags") + """ Tags to apply to the query for [segmenting analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). """ + percentile_computation: Optional[bool] = Field( + default=None, alias="percentileComputation" + ) + """ Whether to include this search when calculating processing-time percentiles. """ + enable_ab_test: Optional[bool] = Field(default=None, alias="enableABTest") + """ Whether to enable A/B testing for this search. """ + attributes_to_retrieve: Optional[List[str]] = Field( + default=None, alias="attributesToRetrieve" + ) + """ Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `[\"*\", \"-ATTRIBUTE\"]`. - The `objectID` attribute is always included. """ + ranking: Optional[List[str]] = Field(default=None, alias="ranking") + """ Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they're specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in ascending order. - `desc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). """ + custom_ranking: Optional[List[str]] = Field(default=None, alias="customRanking") + """ Attributes to use as [custom ranking](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/). Attribute names are case-sensitive. The custom ranking attributes decide which items are shown first if the other ranking criteria are equal. Records with missing values for your selected custom ranking attributes are always sorted last. Boolean attributes are sorted based on their alphabetical order. **Modifiers** - `asc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in ascending order. - `desc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in descending order. If you use two or more custom ranking attributes, [reduce the precision](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/how-to/controlling-custom-ranking-metrics-precision/) of your first attributes, or the other attributes will never be applied. """ + relevancy_strictness: Optional[int] = Field( + default=None, alias="relevancyStrictness" + ) + """ Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. """ + attributes_to_highlight: Optional[List[str]] = Field( + default=None, alias="attributesToHighlight" + ) + """ Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). """ + attributes_to_snippet: Optional[List[str]] = Field( + default=None, alias="attributesToSnippet" + ) + """ Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. """ + highlight_pre_tag: Optional[str] = Field(default=None, alias="highlightPreTag") + """ HTML tag to insert before the highlighted parts in all highlighted results and snippets. """ + highlight_post_tag: Optional[str] = Field(default=None, alias="highlightPostTag") + """ HTML tag to insert after the highlighted parts in all highlighted results and snippets. """ + snippet_ellipsis_text: Optional[str] = Field( + default=None, alias="snippetEllipsisText" + ) + """ String used as an ellipsis indicator when a snippet is truncated. """ + restrict_highlight_and_snippet_arrays: Optional[bool] = Field( + default=None, alias="restrictHighlightAndSnippetArrays" + ) + """ Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. """ + hits_per_page: Optional[int] = Field(default=None, alias="hitsPerPage") + """ Number of hits per page. """ + min_word_sizefor1_typo: Optional[int] = Field( + default=None, alias="minWordSizefor1Typo" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ + min_word_sizefor2_typos: Optional[int] = Field( + default=None, alias="minWordSizefor2Typos" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ typo_tolerance: Optional[TypoTolerance] = Field(default=None, alias="typoTolerance") - allow_typos_on_numeric_tokens: Optional[StrictBool] = Field( - default=True, - description="Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. ", - alias="allowTyposOnNumericTokens", + allow_typos_on_numeric_tokens: Optional[bool] = Field( + default=None, alias="allowTyposOnNumericTokens" ) - disable_typo_tolerance_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. ", - alias="disableTypoToleranceOnAttributes", + """ Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. """ + disable_typo_tolerance_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableTypoToleranceOnAttributes" ) + """ Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. """ ignore_plurals: Optional[IgnorePlurals] = Field(default=None, alias="ignorePlurals") remove_stop_words: Optional[RemoveStopWords] = Field( default=None, alias="removeStopWords" ) - keep_diacritics_on_characters: Optional[StrictStr] = Field( - default="", - description="Characters for which diacritics should be preserved. By default, Algolia removes diacritics from letters. For example, `é` becomes `e`. If this causes issues in your search, you can specify characters that should keep their diacritics. ", - alias="keepDiacriticsOnCharacters", + keep_diacritics_on_characters: Optional[str] = Field( + default=None, alias="keepDiacriticsOnCharacters" ) + """ Characters for which diacritics should be preserved. By default, Algolia removes diacritics from letters. For example, `é` becomes `e`. If this causes issues in your search, you can specify characters that should keep their diacritics. """ query_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). ", - alias="queryLanguages", - ) - decompound_query: Optional[StrictBool] = Field( - default=True, - description="Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). ", - alias="decompoundQuery", + default=None, alias="queryLanguages" ) - enable_rules: Optional[StrictBool] = Field( - default=True, description="Whether to enable rules.", alias="enableRules" - ) - enable_personalization: Optional[StrictBool] = Field( - default=False, - description="Whether to enable Personalization.", - alias="enablePersonalization", + """ Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). """ + decompound_query: Optional[bool] = Field(default=None, alias="decompoundQuery") + """ Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). """ + enable_rules: Optional[bool] = Field(default=None, alias="enableRules") + """ Whether to enable rules. """ + enable_personalization: Optional[bool] = Field( + default=None, alias="enablePersonalization" ) + """ Whether to enable Personalization. """ query_type: Optional[QueryType] = Field(default=None, alias="queryType") remove_words_if_no_results: Optional[RemoveWordsIfNoResults] = Field( default=None, alias="removeWordsIfNoResults" ) - mode: Optional[Mode] = None + mode: Optional[Mode] = Field(default=None, alias="mode") semantic_search: Optional[SemanticSearch] = Field( default=None, alias="semanticSearch" ) - advanced_syntax: Optional[StrictBool] = Field( - default=False, - description="Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. ", - alias="advancedSyntax", - ) - optional_words: Optional[List[StrictStr]] = Field( - default=None, - description='Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn\'t include the optional words. For example, if the search query is "action video" and "video" is an optional word, the search engine runs two queries. One for "action video" and one for "action". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). ', - alias="optionalWords", - ) - disable_exact_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. ", - alias="disableExactOnAttributes", + advanced_syntax: Optional[bool] = Field(default=None, alias="advancedSyntax") + """ Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. """ + optional_words: Optional[List[str]] = Field(default=None, alias="optionalWords") + """ Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn't include the optional words. For example, if the search query is \"action video\" and \"video\" is an optional word, the search engine runs two queries. One for \"action video\" and one for \"action\". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). """ + disable_exact_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableExactOnAttributes" ) + """ Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. """ exact_on_single_word_query: Optional[ExactOnSingleWordQuery] = Field( default=None, alias="exactOnSingleWordQuery" ) alternatives_as_exact: Optional[List[AlternativesAsExact]] = Field( - default=None, - description='Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as "NY/NYC" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as "NY/New York" are considered exact matches. ', - alias="alternativesAsExact", + default=None, alias="alternativesAsExact" ) + """ Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as \"NY/NYC\" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as \"NY/New York\" are considered exact matches. """ advanced_syntax_features: Optional[List[AdvancedSyntaxFeatures]] = Field( - default=None, - description='Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue "iPhone case"` only returns records with the exact string "iPhone case". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain "search" but not "engine". This setting only has an effect if `advancedSyntax` is true. ', - alias="advancedSyntaxFeatures", - ) - distinct: Optional[Distinct] = None - replace_synonyms_in_highlight: Optional[StrictBool] = Field( - default=False, - description='Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either "home" or "house" are included in the search results, and either "home" or "house" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of "house" are replaced by "home" in the highlighted response. ', - alias="replaceSynonymsInHighlight", - ) - min_proximity: Optional[Annotated[int, Field(le=7, strict=True, ge=1)]] = Field( - default=1, - description="Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. ", - alias="minProximity", - ) - response_fields: Optional[List[StrictStr]] = Field( - default=None, - description="Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. ", - alias="responseFields", - ) - max_facet_hits: Optional[Annotated[int, Field(le=100, strict=True)]] = Field( - default=10, - description="Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values).", - alias="maxFacetHits", - ) - max_values_per_facet: Optional[Annotated[int, Field(le=1000, strict=True)]] = Field( - default=100, - description="Maximum number of facet values to return for each facet.", - alias="maxValuesPerFacet", - ) - sort_facet_values_by: Optional[StrictStr] = Field( - default="count", - description="Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). ", - alias="sortFacetValuesBy", - ) - attribute_criteria_computed_by_min_proximity: Optional[StrictBool] = Field( - default=False, - description="Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. ", - alias="attributeCriteriaComputedByMinProximity", - ) + default=None, alias="advancedSyntaxFeatures" + ) + """ Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue \"iPhone case\"` only returns records with the exact string \"iPhone case\". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain \"search\" but not \"engine\". This setting only has an effect if `advancedSyntax` is true. """ + distinct: Optional[Distinct] = Field(default=None, alias="distinct") + replace_synonyms_in_highlight: Optional[bool] = Field( + default=None, alias="replaceSynonymsInHighlight" + ) + """ Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either \"home\" or \"house\" are included in the search results, and either \"home\" or \"house\" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of \"house\" are replaced by \"home\" in the highlighted response. """ + min_proximity: Optional[int] = Field(default=None, alias="minProximity") + """ Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. """ + response_fields: Optional[List[str]] = Field(default=None, alias="responseFields") + """ Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. """ + max_facet_hits: Optional[int] = Field(default=None, alias="maxFacetHits") + """ Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values). """ + max_values_per_facet: Optional[int] = Field(default=None, alias="maxValuesPerFacet") + """ Maximum number of facet values to return for each facet. """ + sort_facet_values_by: Optional[str] = Field(default=None, alias="sortFacetValuesBy") + """ Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). """ + attribute_criteria_computed_by_min_proximity: Optional[bool] = Field( + default=None, alias="attributeCriteriaComputedByMinProximity" + ) + """ Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. """ rendering_content: Optional[RenderingContent] = Field( default=None, alias="renderingContent" ) - enable_re_ranking: Optional[StrictBool] = Field( - default=True, - description="Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. ", - alias="enableReRanking", - ) + enable_re_ranking: Optional[bool] = Field(default=None, alias="enableReRanking") + """ Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. """ re_ranking_apply_filter: Optional[ReRankingApplyFilter] = Field( default=None, alias="reRankingApplyFilter" ) - index_name: StrictStr = Field( - description="Index name (case-sensitive).", alias="indexName" - ) - type: Optional[SearchTypeDefault] = None + index_name: str = Field(alias="indexName") + """ Index name (case-sensitive). """ + type: Optional[SearchTypeDefault] = Field(default=None, alias="type") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchForHits from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.facet_filters: - _dict["facetFilters"] = self.facet_filters.to_dict() - if self.optional_filters: - _dict["optionalFilters"] = self.optional_filters.to_dict() - if self.numeric_filters: - _dict["numericFilters"] = self.numeric_filters.to_dict() - if self.tag_filters: - _dict["tagFilters"] = self.tag_filters.to_dict() - if self.around_radius: - _dict["aroundRadius"] = self.around_radius.to_dict() - if self.around_precision: - _dict["aroundPrecision"] = self.around_precision.to_dict() - if self.typo_tolerance: - _dict["typoTolerance"] = self.typo_tolerance.to_dict() - if self.ignore_plurals: - _dict["ignorePlurals"] = self.ignore_plurals.to_dict() - if self.remove_stop_words: - _dict["removeStopWords"] = self.remove_stop_words.to_dict() - if self.semantic_search: - _dict["semanticSearch"] = self.semantic_search.to_dict() - if self.distinct: - _dict["distinct"] = self.distinct.to_dict() - if self.rendering_content: - _dict["renderingContent"] = self.rendering_content.to_dict() - if self.re_ranking_apply_filter: - _dict["reRankingApplyFilter"] = self.re_ranking_apply_filter.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchForHits from a dict""" if obj is None: return None @@ -457,145 +297,79 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "params": obj.get("params"), - "query": obj.get("query"), - "similarQuery": obj.get("similarQuery"), - "filters": obj.get("filters"), - "facetFilters": ( - FacetFilters.from_dict(obj.get("facetFilters")) - if obj.get("facetFilters") is not None - else None - ), - "optionalFilters": ( - OptionalFilters.from_dict(obj.get("optionalFilters")) - if obj.get("optionalFilters") is not None - else None - ), - "numericFilters": ( - NumericFilters.from_dict(obj.get("numericFilters")) - if obj.get("numericFilters") is not None - else None - ), - "tagFilters": ( - TagFilters.from_dict(obj.get("tagFilters")) - if obj.get("tagFilters") is not None - else None - ), - "sumOrFiltersScores": obj.get("sumOrFiltersScores"), - "restrictSearchableAttributes": obj.get("restrictSearchableAttributes"), - "facets": obj.get("facets"), - "facetingAfterDistinct": obj.get("facetingAfterDistinct"), - "page": obj.get("page"), - "offset": obj.get("offset"), - "length": obj.get("length"), - "aroundLatLng": obj.get("aroundLatLng"), - "aroundLatLngViaIP": obj.get("aroundLatLngViaIP"), - "aroundRadius": ( - AroundRadius.from_dict(obj.get("aroundRadius")) - if obj.get("aroundRadius") is not None - else None - ), - "aroundPrecision": ( - AroundPrecision.from_dict(obj.get("aroundPrecision")) - if obj.get("aroundPrecision") is not None - else None - ), - "minimumAroundRadius": obj.get("minimumAroundRadius"), - "insideBoundingBox": obj.get("insideBoundingBox"), - "insidePolygon": obj.get("insidePolygon"), - "naturalLanguages": obj.get("naturalLanguages"), - "ruleContexts": obj.get("ruleContexts"), - "personalizationImpact": obj.get("personalizationImpact"), - "userToken": obj.get("userToken"), - "getRankingInfo": obj.get("getRankingInfo"), - "synonyms": obj.get("synonyms"), - "clickAnalytics": obj.get("clickAnalytics"), - "analytics": obj.get("analytics"), - "analyticsTags": obj.get("analyticsTags"), - "percentileComputation": obj.get("percentileComputation"), - "enableABTest": obj.get("enableABTest"), - "attributesToRetrieve": obj.get("attributesToRetrieve"), - "ranking": obj.get("ranking"), - "customRanking": obj.get("customRanking"), - "relevancyStrictness": obj.get("relevancyStrictness"), - "attributesToHighlight": obj.get("attributesToHighlight"), - "attributesToSnippet": obj.get("attributesToSnippet"), - "highlightPreTag": obj.get("highlightPreTag"), - "highlightPostTag": obj.get("highlightPostTag"), - "snippetEllipsisText": obj.get("snippetEllipsisText"), - "restrictHighlightAndSnippetArrays": obj.get( - "restrictHighlightAndSnippetArrays" - ), - "hitsPerPage": obj.get("hitsPerPage"), - "minWordSizefor1Typo": obj.get("minWordSizefor1Typo"), - "minWordSizefor2Typos": obj.get("minWordSizefor2Typos"), - "typoTolerance": ( - TypoTolerance.from_dict(obj.get("typoTolerance")) - if obj.get("typoTolerance") is not None - else None - ), - "allowTyposOnNumericTokens": obj.get("allowTyposOnNumericTokens"), - "disableTypoToleranceOnAttributes": obj.get( - "disableTypoToleranceOnAttributes" - ), - "ignorePlurals": ( - IgnorePlurals.from_dict(obj.get("ignorePlurals")) - if obj.get("ignorePlurals") is not None - else None - ), - "removeStopWords": ( - RemoveStopWords.from_dict(obj.get("removeStopWords")) - if obj.get("removeStopWords") is not None - else None - ), - "keepDiacriticsOnCharacters": obj.get("keepDiacriticsOnCharacters"), - "queryLanguages": obj.get("queryLanguages"), - "decompoundQuery": obj.get("decompoundQuery"), - "enableRules": obj.get("enableRules"), - "enablePersonalization": obj.get("enablePersonalization"), - "queryType": obj.get("queryType"), - "removeWordsIfNoResults": obj.get("removeWordsIfNoResults"), - "mode": obj.get("mode"), - "semanticSearch": ( - SemanticSearch.from_dict(obj.get("semanticSearch")) - if obj.get("semanticSearch") is not None - else None - ), - "advancedSyntax": obj.get("advancedSyntax"), - "optionalWords": obj.get("optionalWords"), - "disableExactOnAttributes": obj.get("disableExactOnAttributes"), - "exactOnSingleWordQuery": obj.get("exactOnSingleWordQuery"), - "alternativesAsExact": obj.get("alternativesAsExact"), - "advancedSyntaxFeatures": obj.get("advancedSyntaxFeatures"), - "distinct": ( - Distinct.from_dict(obj.get("distinct")) - if obj.get("distinct") is not None - else None - ), - "replaceSynonymsInHighlight": obj.get("replaceSynonymsInHighlight"), - "minProximity": obj.get("minProximity"), - "responseFields": obj.get("responseFields"), - "maxFacetHits": obj.get("maxFacetHits"), - "maxValuesPerFacet": obj.get("maxValuesPerFacet"), - "sortFacetValuesBy": obj.get("sortFacetValuesBy"), - "attributeCriteriaComputedByMinProximity": obj.get( - "attributeCriteriaComputedByMinProximity" - ), - "renderingContent": ( - RenderingContent.from_dict(obj.get("renderingContent")) - if obj.get("renderingContent") is not None - else None - ), - "enableReRanking": obj.get("enableReRanking"), - "reRankingApplyFilter": ( - ReRankingApplyFilter.from_dict(obj.get("reRankingApplyFilter")) - if obj.get("reRankingApplyFilter") is not None - else None - ), - "indexName": obj.get("indexName"), - "type": obj.get("type"), - } + obj["facetFilters"] = ( + FacetFilters.from_dict(obj["facetFilters"]) + if obj.get("facetFilters") is not None + else None + ) + obj["optionalFilters"] = ( + OptionalFilters.from_dict(obj["optionalFilters"]) + if obj.get("optionalFilters") is not None + else None + ) + obj["numericFilters"] = ( + NumericFilters.from_dict(obj["numericFilters"]) + if obj.get("numericFilters") is not None + else None + ) + obj["tagFilters"] = ( + TagFilters.from_dict(obj["tagFilters"]) + if obj.get("tagFilters") is not None + else None + ) + obj["aroundRadius"] = ( + AroundRadius.from_dict(obj["aroundRadius"]) + if obj.get("aroundRadius") is not None + else None ) - return _obj + obj["aroundPrecision"] = ( + AroundPrecision.from_dict(obj["aroundPrecision"]) + if obj.get("aroundPrecision") is not None + else None + ) + obj["naturalLanguages"] = obj.get("naturalLanguages") + obj["typoTolerance"] = ( + TypoTolerance.from_dict(obj["typoTolerance"]) + if obj.get("typoTolerance") is not None + else None + ) + obj["ignorePlurals"] = ( + IgnorePlurals.from_dict(obj["ignorePlurals"]) + if obj.get("ignorePlurals") is not None + else None + ) + obj["removeStopWords"] = ( + RemoveStopWords.from_dict(obj["removeStopWords"]) + if obj.get("removeStopWords") is not None + else None + ) + obj["queryLanguages"] = obj.get("queryLanguages") + obj["queryType"] = obj.get("queryType") + obj["removeWordsIfNoResults"] = obj.get("removeWordsIfNoResults") + obj["mode"] = obj.get("mode") + obj["semanticSearch"] = ( + SemanticSearch.from_dict(obj["semanticSearch"]) + if obj.get("semanticSearch") is not None + else None + ) + obj["exactOnSingleWordQuery"] = obj.get("exactOnSingleWordQuery") + obj["alternativesAsExact"] = obj.get("alternativesAsExact") + obj["advancedSyntaxFeatures"] = obj.get("advancedSyntaxFeatures") + obj["distinct"] = ( + Distinct.from_dict(obj["distinct"]) + if obj.get("distinct") is not None + else None + ) + obj["renderingContent"] = ( + RenderingContent.from_dict(obj["renderingContent"]) + if obj.get("renderingContent") is not None + else None + ) + obj["reRankingApplyFilter"] = ( + ReRankingApplyFilter.from_dict(obj["reRankingApplyFilter"]) + if obj.get("reRankingApplyFilter") is not None + else None + ) + obj["type"] = obj.get("type") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/search_method_params.py b/algoliasearch/search/models/search_method_params.py index d184f8928..10884527b 100644 --- a/algoliasearch/search/models/search_method_params.py +++ b/algoliasearch/search/models/search_method_params.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -27,47 +27,34 @@ class SearchMethodParams(BaseModel): SearchMethodParams """ - requests: List[SearchQuery] - strategy: Optional[SearchStrategy] = None + requests: List[SearchQuery] = Field(alias="requests") + strategy: Optional[SearchStrategy] = Field(default=None, alias="strategy") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchMethodParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.requests: - for _item in self.requests: - if _item: - _items.append(_item.to_dict()) - _dict["requests"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchMethodParams from a dict""" if obj is None: return None @@ -75,14 +62,11 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "requests": ( - [SearchQuery.from_dict(_item) for _item in obj.get("requests")] - if obj.get("requests") is not None - else None - ), - "strategy": obj.get("strategy"), - } + obj["requests"] = ( + [SearchQuery.from_dict(_item) for _item in obj["requests"]] + if obj.get("requests") is not None + else None ) - return _obj + obj["strategy"] = obj.get("strategy") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/search_params.py b/algoliasearch/search/models/search_params.py index 7db71fd13..597003a07 100644 --- a/algoliasearch/search/models/search_params.py +++ b/algoliasearch/search/models/search_params.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -27,9 +27,12 @@ class SearchParams(BaseModel): SearchParams """ - oneof_schema_1_validator: Optional[SearchParamsString] = None - oneof_schema_2_validator: Optional[SearchParamsObject] = None + oneof_schema_1_validator: Optional[SearchParamsString] = Field(default=None) + + oneof_schema_2_validator: Optional[SearchParamsObject] = Field(default=None) + actual_instance: Optional[Union[SearchParamsObject, SearchParamsString]] = None + one_of_schemas: Set[str] = {"SearchParamsObject", "SearchParamsString"} def __init__(self, *args, **kwargs) -> None: if args: @@ -55,7 +58,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of SearchParams from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -87,17 +91,23 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[Union[Dict[str, Any], SearchParamsObject, SearchParamsString]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/search_params_object.py b/algoliasearch/search/models/search_params_object.py index 4cffcbeb8..91d977052 100644 --- a/algoliasearch/search/models/search_params_object.py +++ b/algoliasearch/search/models/search_params_object.py @@ -8,22 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional -from pydantic import ( - BaseModel, - ConfigDict, - Field, - StrictBool, - StrictFloat, - StrictInt, - StrictStr, -) +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.advanced_syntax_features import AdvancedSyntaxFeatures @@ -57,16 +49,12 @@ class SearchParamsObject(BaseModel): Each parameter value, including the `query` must not be larger than 512 bytes. """ - query: Optional[StrictStr] = Field(default="", description="Search query.") - similar_query: Optional[StrictStr] = Field( - default="", - description="Keywords to be used instead of the search query to conduct a more broader search. Using the `similarQuery` parameter changes other settings: - `queryType` is set to `prefixNone`. - `removeStopWords` is set to true. - `words` is set as the first ranking criterion. - All remaining words are treated as `optionalWords`. Since the `similarQuery` is supposed to do a broad search, they usually return many results. Combine it with `filters` to narrow down the list of results. ", - alias="similarQuery", - ) - filters: Optional[StrictStr] = Field( - default=None, - description="Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). ", - ) + query: Optional[str] = Field(default=None, alias="query") + """ Search query. """ + similar_query: Optional[str] = Field(default=None, alias="similarQuery") + """ Keywords to be used instead of the search query to conduct a more broader search. Using the `similarQuery` parameter changes other settings: - `queryType` is set to `prefixNone`. - `removeStopWords` is set to true. - `words` is set as the first ranking criterion. - All remaining words are treated as `optionalWords`. Since the `similarQuery` is supposed to do a broad search, they usually return many results. Combine it with `filters` to narrow down the list of results. """ + filters: Optional[str] = Field(default=None, alias="filters") + """ Filter expression to only include items that match the filter criteria in the response. You can use these filter expressions: - **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`. - **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive). - **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value. - **Tag filters.** `_tags:` or just `` (case-sensitive). - **Boolean filters.** `: true | false`. You can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions: - You can only combine filters of the same type with `OR`. **Not supported:** `facet:value OR num > 3`. - You can't use `NOT` with combinations of filters. **Not supported:** `NOT(facet:value OR facet:value)` - You can't combine conjunctions (`AND`) with `OR`. **Not supported:** `facet:value OR (facet:value AND facet:value)` Use quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes. If a facet attribute is an array, the filter matches if it matches at least one element of the array. For more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/). """ facet_filters: Optional[FacetFilters] = Field(default=None, alias="facetFilters") optional_filters: Optional[OptionalFilters] = Field( default=None, alias="optionalFilters" @@ -75,373 +63,227 @@ class SearchParamsObject(BaseModel): default=None, alias="numericFilters" ) tag_filters: Optional[TagFilters] = Field(default=None, alias="tagFilters") - sum_or_filters_scores: Optional[StrictBool] = Field( - default=False, - description="Whether to sum all filter scores. If true, all filter scores are summed. Otherwise, the maximum filter score is kept. For more information, see [filter scores](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/#accumulating-scores-with-sumorfiltersscores). ", - alias="sumOrFiltersScores", - ) - restrict_searchable_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Restricts a search to a subset of your searchable attributes. Attribute names are case-sensitive. ", - alias="restrictSearchableAttributes", - ) - facets: Optional[List[StrictStr]] = Field( - default=None, - description="Facets for which to retrieve facet values that match the search criteria and the number of matching facet values. To retrieve all facets, use the wildcard character `*`. For more information, see [facets](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#contextual-facet-values-and-counts). ", - ) - faceting_after_distinct: Optional[StrictBool] = Field( - default=False, - description="Whether faceting should be applied after deduplication with `distinct`. This leads to accurate facet counts when using faceting in combination with `distinct`. It's usually better to use `afterDistinct` modifiers in the `attributesForFaceting` setting, as `facetingAfterDistinct` only computes correct facet counts if all records have the same facet values for the `attributeForDistinct`. ", - alias="facetingAfterDistinct", - ) - page: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=0, description="Page of search results to retrieve." - ) - offset: Optional[StrictInt] = Field( - default=None, description="Position of the first hit to retrieve." - ) - length: Optional[Annotated[int, Field(le=1000, strict=True, ge=0)]] = Field( - default=None, - description="Number of hits to retrieve (used in combination with `offset`).", - ) - around_lat_lng: Optional[StrictStr] = Field( - default="", - description="Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude. Only records included within circle around this central location are included in the results. The radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings. This parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`. ", - alias="aroundLatLng", - ) - around_lat_lng_via_ip: Optional[StrictBool] = Field( - default=False, - description="Whether to obtain the coordinates from the request's IP address.", - alias="aroundLatLngViaIP", - ) + sum_or_filters_scores: Optional[bool] = Field( + default=None, alias="sumOrFiltersScores" + ) + """ Whether to sum all filter scores. If true, all filter scores are summed. Otherwise, the maximum filter score is kept. For more information, see [filter scores](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/#accumulating-scores-with-sumorfiltersscores). """ + restrict_searchable_attributes: Optional[List[str]] = Field( + default=None, alias="restrictSearchableAttributes" + ) + """ Restricts a search to a subset of your searchable attributes. Attribute names are case-sensitive. """ + facets: Optional[List[str]] = Field(default=None, alias="facets") + """ Facets for which to retrieve facet values that match the search criteria and the number of matching facet values. To retrieve all facets, use the wildcard character `*`. For more information, see [facets](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#contextual-facet-values-and-counts). """ + faceting_after_distinct: Optional[bool] = Field( + default=None, alias="facetingAfterDistinct" + ) + """ Whether faceting should be applied after deduplication with `distinct`. This leads to accurate facet counts when using faceting in combination with `distinct`. It's usually better to use `afterDistinct` modifiers in the `attributesForFaceting` setting, as `facetingAfterDistinct` only computes correct facet counts if all records have the same facet values for the `attributeForDistinct`. """ + page: Optional[int] = Field(default=None, alias="page") + """ Page of search results to retrieve. """ + offset: Optional[int] = Field(default=None, alias="offset") + """ Position of the first hit to retrieve. """ + length: Optional[int] = Field(default=None, alias="length") + """ Number of hits to retrieve (used in combination with `offset`). """ + around_lat_lng: Optional[str] = Field(default=None, alias="aroundLatLng") + """ Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude. Only records included within circle around this central location are included in the results. The radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings. This parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`. """ + around_lat_lng_via_ip: Optional[bool] = Field( + default=None, alias="aroundLatLngViaIP" + ) + """ Whether to obtain the coordinates from the request's IP address. """ around_radius: Optional[AroundRadius] = Field(default=None, alias="aroundRadius") around_precision: Optional[AroundPrecision] = Field( default=None, alias="aroundPrecision" ) - minimum_around_radius: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field( - default=None, - description="Minimum radius (in meters) for a search around a location when `aroundRadius` isn't set.", - alias="minimumAroundRadius", - ) - inside_bounding_box: Optional[ - List[ - Annotated[ - List[Union[StrictFloat, StrictInt]], Field(min_length=4, max_length=4) - ] - ] - ] = Field( - default=None, - description="Coordinates for a rectangular area in which to search. Each bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair: `[p1 lat, p1 long, p2 lat, p2 long]`. Provide multiple bounding boxes as nested arrays. For more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). ", - alias="insideBoundingBox", - ) - inside_polygon: Optional[ - List[ - Annotated[ - List[Union[StrictFloat, StrictInt]], - Field(min_length=6, max_length=20000), - ] - ] - ] = Field( - default=None, - description="Coordinates of a polygon in which to search. Polygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude. Provide multiple polygons as nested arrays. For more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). This parameter is ignored if you also specify `insideBoundingBox`. ", - alias="insidePolygon", + minimum_around_radius: Optional[int] = Field( + default=None, alias="minimumAroundRadius" ) - natural_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="ISO language codes that adjust settings that are useful for processing natural language queries (as opposed to keyword searches): - Sets `removeStopWords` and `ignorePlurals` to the list of provided languages. - Sets `removeWordsIfNoResults` to `allOptional`. - Adds a `natural_language` attribute to `ruleContexts` and `analyticsTags`. ", - alias="naturalLanguages", - ) - rule_contexts: Optional[List[StrictStr]] = Field( - default=None, - description="Assigns a rule context to the search query. [Rule contexts](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/how-to/customize-search-results-by-platform/#whats-a-context) are strings that you can use to trigger matching rules. ", - alias="ruleContexts", - ) - personalization_impact: Optional[ - Annotated[int, Field(le=100, strict=True, ge=0)] - ] = Field( - default=100, - description="Impact that Personalization should have on this search. The higher this value is, the more Personalization determines the ranking compared to other factors. For more information, see [Understanding Personalization impact](https://www.algolia.com/doc/guides/personalization/personalizing-results/in-depth/configuring-personalization/#understanding-personalization-impact). ", - alias="personalizationImpact", - ) - user_token: Optional[StrictStr] = Field( - default=None, - description="Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). ", - alias="userToken", - ) - get_ranking_info: Optional[StrictBool] = Field( - default=False, - description="Whether the search response should include detailed ranking information.", - alias="getRankingInfo", - ) - synonyms: Optional[StrictBool] = Field( - default=True, - description="Whether to take into account an index's synonyms for this search.", - ) - click_analytics: Optional[StrictBool] = Field( - default=False, - description="Whether to include a `queryID` attribute in the response. The query ID is a unique identifier for a search query and is required for tracking [click and conversion events](https://www.algolia.com/guides/sending-events/getting-started/). ", - alias="clickAnalytics", - ) - analytics: Optional[StrictBool] = Field( - default=True, description="Whether this search will be included in Analytics." - ) - analytics_tags: Optional[List[StrictStr]] = Field( - default=None, - description="Tags to apply to the query for [segmenting analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/).", - alias="analyticsTags", - ) - percentile_computation: Optional[StrictBool] = Field( - default=True, - description="Whether to include this search when calculating processing-time percentiles.", - alias="percentileComputation", - ) - enable_ab_test: Optional[StrictBool] = Field( - default=True, - description="Whether to enable A/B testing for this search.", - alias="enableABTest", - ) - attributes_to_retrieve: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `["*", "-ATTRIBUTE"]`. - The `objectID` attribute is always included. ', - alias="attributesToRetrieve", - ) - ranking: Optional[List[StrictStr]] = Field( - default=None, - description='Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they\'re specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc("ATTRIBUTE")`. Sort the index by the values of an attribute, in ascending order. - `desc("ATTRIBUTE")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). ', - ) - custom_ranking: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes to use as [custom ranking](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/). Attribute names are case-sensitive. The custom ranking attributes decide which items are shown first if the other ranking criteria are equal. Records with missing values for your selected custom ranking attributes are always sorted last. Boolean attributes are sorted based on their alphabetical order. **Modifiers** - `asc("ATTRIBUTE")`. Sort the index by the values of an attribute, in ascending order. - `desc("ATTRIBUTE")`. Sort the index by the values of an attribute, in descending order. If you use two or more custom ranking attributes, [reduce the precision](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/how-to/controlling-custom-ranking-metrics-precision/) of your first attributes, or the other attributes will never be applied. ', - alias="customRanking", - ) - relevancy_strictness: Optional[StrictInt] = Field( - default=100, - description="Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. ", - alias="relevancyStrictness", - ) - attributes_to_highlight: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). ", - alias="attributesToHighlight", - ) - attributes_to_snippet: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. ", - alias="attributesToSnippet", - ) - highlight_pre_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert before the highlighted parts in all highlighted results and snippets.", - alias="highlightPreTag", - ) - highlight_post_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert after the highlighted parts in all highlighted results and snippets.", - alias="highlightPostTag", - ) - snippet_ellipsis_text: Optional[StrictStr] = Field( - default="…", - description="String used as an ellipsis indicator when a snippet is truncated.", - alias="snippetEllipsisText", - ) - restrict_highlight_and_snippet_arrays: Optional[StrictBool] = Field( - default=False, - description="Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. ", - alias="restrictHighlightAndSnippetArrays", - ) - hits_per_page: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = Field( - default=20, description="Number of hits per page.", alias="hitsPerPage" - ) - min_word_sizefor1_typo: Optional[StrictInt] = Field( - default=4, - description="Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor1Typo", - ) - min_word_sizefor2_typos: Optional[StrictInt] = Field( - default=8, - description="Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor2Typos", + """ Minimum radius (in meters) for a search around a location when `aroundRadius` isn't set. """ + inside_bounding_box: Optional[List[List[float]]] = Field( + default=None, alias="insideBoundingBox" + ) + """ Coordinates for a rectangular area in which to search. Each bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair: `[p1 lat, p1 long, p2 lat, p2 long]`. Provide multiple bounding boxes as nested arrays. For more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). """ + inside_polygon: Optional[List[List[float]]] = Field( + default=None, alias="insidePolygon" ) + """ Coordinates of a polygon in which to search. Polygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude. Provide multiple polygons as nested arrays. For more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas). This parameter is ignored if you also specify `insideBoundingBox`. """ + natural_languages: Optional[List[SupportedLanguage]] = Field( + default=None, alias="naturalLanguages" + ) + """ ISO language codes that adjust settings that are useful for processing natural language queries (as opposed to keyword searches): - Sets `removeStopWords` and `ignorePlurals` to the list of provided languages. - Sets `removeWordsIfNoResults` to `allOptional`. - Adds a `natural_language` attribute to `ruleContexts` and `analyticsTags`. """ + rule_contexts: Optional[List[str]] = Field(default=None, alias="ruleContexts") + """ Assigns a rule context to the search query. [Rule contexts](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/how-to/customize-search-results-by-platform/#whats-a-context) are strings that you can use to trigger matching rules. """ + personalization_impact: Optional[int] = Field( + default=None, alias="personalizationImpact" + ) + """ Impact that Personalization should have on this search. The higher this value is, the more Personalization determines the ranking compared to other factors. For more information, see [Understanding Personalization impact](https://www.algolia.com/doc/guides/personalization/personalizing-results/in-depth/configuring-personalization/#understanding-personalization-impact). """ + user_token: Optional[str] = Field(default=None, alias="userToken") + """ Unique pseudonymous or anonymous user identifier. This helps with analytics and click and conversion events. For more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/). """ + get_ranking_info: Optional[bool] = Field(default=None, alias="getRankingInfo") + """ Whether the search response should include detailed ranking information. """ + synonyms: Optional[bool] = Field(default=None, alias="synonyms") + """ Whether to take into account an index's synonyms for this search. """ + click_analytics: Optional[bool] = Field(default=None, alias="clickAnalytics") + """ Whether to include a `queryID` attribute in the response. The query ID is a unique identifier for a search query and is required for tracking [click and conversion events](https://www.algolia.com/guides/sending-events/getting-started/). """ + analytics: Optional[bool] = Field(default=None, alias="analytics") + """ Whether this search will be included in Analytics. """ + analytics_tags: Optional[List[str]] = Field(default=None, alias="analyticsTags") + """ Tags to apply to the query for [segmenting analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). """ + percentile_computation: Optional[bool] = Field( + default=None, alias="percentileComputation" + ) + """ Whether to include this search when calculating processing-time percentiles. """ + enable_ab_test: Optional[bool] = Field(default=None, alias="enableABTest") + """ Whether to enable A/B testing for this search. """ + attributes_to_retrieve: Optional[List[str]] = Field( + default=None, alias="attributesToRetrieve" + ) + """ Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `[\"*\", \"-ATTRIBUTE\"]`. - The `objectID` attribute is always included. """ + ranking: Optional[List[str]] = Field(default=None, alias="ranking") + """ Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they're specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in ascending order. - `desc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). """ + custom_ranking: Optional[List[str]] = Field(default=None, alias="customRanking") + """ Attributes to use as [custom ranking](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/). Attribute names are case-sensitive. The custom ranking attributes decide which items are shown first if the other ranking criteria are equal. Records with missing values for your selected custom ranking attributes are always sorted last. Boolean attributes are sorted based on their alphabetical order. **Modifiers** - `asc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in ascending order. - `desc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in descending order. If you use two or more custom ranking attributes, [reduce the precision](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/how-to/controlling-custom-ranking-metrics-precision/) of your first attributes, or the other attributes will never be applied. """ + relevancy_strictness: Optional[int] = Field( + default=None, alias="relevancyStrictness" + ) + """ Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. """ + attributes_to_highlight: Optional[List[str]] = Field( + default=None, alias="attributesToHighlight" + ) + """ Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). """ + attributes_to_snippet: Optional[List[str]] = Field( + default=None, alias="attributesToSnippet" + ) + """ Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. """ + highlight_pre_tag: Optional[str] = Field(default=None, alias="highlightPreTag") + """ HTML tag to insert before the highlighted parts in all highlighted results and snippets. """ + highlight_post_tag: Optional[str] = Field(default=None, alias="highlightPostTag") + """ HTML tag to insert after the highlighted parts in all highlighted results and snippets. """ + snippet_ellipsis_text: Optional[str] = Field( + default=None, alias="snippetEllipsisText" + ) + """ String used as an ellipsis indicator when a snippet is truncated. """ + restrict_highlight_and_snippet_arrays: Optional[bool] = Field( + default=None, alias="restrictHighlightAndSnippetArrays" + ) + """ Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. """ + hits_per_page: Optional[int] = Field(default=None, alias="hitsPerPage") + """ Number of hits per page. """ + min_word_sizefor1_typo: Optional[int] = Field( + default=None, alias="minWordSizefor1Typo" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ + min_word_sizefor2_typos: Optional[int] = Field( + default=None, alias="minWordSizefor2Typos" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ typo_tolerance: Optional[TypoTolerance] = Field(default=None, alias="typoTolerance") - allow_typos_on_numeric_tokens: Optional[StrictBool] = Field( - default=True, - description="Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. ", - alias="allowTyposOnNumericTokens", + allow_typos_on_numeric_tokens: Optional[bool] = Field( + default=None, alias="allowTyposOnNumericTokens" ) - disable_typo_tolerance_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. ", - alias="disableTypoToleranceOnAttributes", + """ Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. """ + disable_typo_tolerance_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableTypoToleranceOnAttributes" ) + """ Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. """ ignore_plurals: Optional[IgnorePlurals] = Field(default=None, alias="ignorePlurals") remove_stop_words: Optional[RemoveStopWords] = Field( default=None, alias="removeStopWords" ) - keep_diacritics_on_characters: Optional[StrictStr] = Field( - default="", - description="Characters for which diacritics should be preserved. By default, Algolia removes diacritics from letters. For example, `é` becomes `e`. If this causes issues in your search, you can specify characters that should keep their diacritics. ", - alias="keepDiacriticsOnCharacters", + keep_diacritics_on_characters: Optional[str] = Field( + default=None, alias="keepDiacriticsOnCharacters" ) + """ Characters for which diacritics should be preserved. By default, Algolia removes diacritics from letters. For example, `é` becomes `e`. If this causes issues in your search, you can specify characters that should keep their diacritics. """ query_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). ", - alias="queryLanguages", - ) - decompound_query: Optional[StrictBool] = Field( - default=True, - description="Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). ", - alias="decompoundQuery", + default=None, alias="queryLanguages" ) - enable_rules: Optional[StrictBool] = Field( - default=True, description="Whether to enable rules.", alias="enableRules" - ) - enable_personalization: Optional[StrictBool] = Field( - default=False, - description="Whether to enable Personalization.", - alias="enablePersonalization", + """ Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). """ + decompound_query: Optional[bool] = Field(default=None, alias="decompoundQuery") + """ Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). """ + enable_rules: Optional[bool] = Field(default=None, alias="enableRules") + """ Whether to enable rules. """ + enable_personalization: Optional[bool] = Field( + default=None, alias="enablePersonalization" ) + """ Whether to enable Personalization. """ query_type: Optional[QueryType] = Field(default=None, alias="queryType") remove_words_if_no_results: Optional[RemoveWordsIfNoResults] = Field( default=None, alias="removeWordsIfNoResults" ) - mode: Optional[Mode] = None + mode: Optional[Mode] = Field(default=None, alias="mode") semantic_search: Optional[SemanticSearch] = Field( default=None, alias="semanticSearch" ) - advanced_syntax: Optional[StrictBool] = Field( - default=False, - description="Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. ", - alias="advancedSyntax", - ) - optional_words: Optional[List[StrictStr]] = Field( - default=None, - description='Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn\'t include the optional words. For example, if the search query is "action video" and "video" is an optional word, the search engine runs two queries. One for "action video" and one for "action". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). ', - alias="optionalWords", - ) - disable_exact_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. ", - alias="disableExactOnAttributes", + advanced_syntax: Optional[bool] = Field(default=None, alias="advancedSyntax") + """ Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. """ + optional_words: Optional[List[str]] = Field(default=None, alias="optionalWords") + """ Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn't include the optional words. For example, if the search query is \"action video\" and \"video\" is an optional word, the search engine runs two queries. One for \"action video\" and one for \"action\". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). """ + disable_exact_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableExactOnAttributes" ) + """ Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. """ exact_on_single_word_query: Optional[ExactOnSingleWordQuery] = Field( default=None, alias="exactOnSingleWordQuery" ) alternatives_as_exact: Optional[List[AlternativesAsExact]] = Field( - default=None, - description='Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as "NY/NYC" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as "NY/New York" are considered exact matches. ', - alias="alternativesAsExact", + default=None, alias="alternativesAsExact" ) + """ Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as \"NY/NYC\" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as \"NY/New York\" are considered exact matches. """ advanced_syntax_features: Optional[List[AdvancedSyntaxFeatures]] = Field( - default=None, - description='Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue "iPhone case"` only returns records with the exact string "iPhone case". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain "search" but not "engine". This setting only has an effect if `advancedSyntax` is true. ', - alias="advancedSyntaxFeatures", - ) - distinct: Optional[Distinct] = None - replace_synonyms_in_highlight: Optional[StrictBool] = Field( - default=False, - description='Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either "home" or "house" are included in the search results, and either "home" or "house" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of "house" are replaced by "home" in the highlighted response. ', - alias="replaceSynonymsInHighlight", - ) - min_proximity: Optional[Annotated[int, Field(le=7, strict=True, ge=1)]] = Field( - default=1, - description="Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. ", - alias="minProximity", - ) - response_fields: Optional[List[StrictStr]] = Field( - default=None, - description="Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. ", - alias="responseFields", - ) - max_facet_hits: Optional[Annotated[int, Field(le=100, strict=True)]] = Field( - default=10, - description="Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values).", - alias="maxFacetHits", - ) - max_values_per_facet: Optional[Annotated[int, Field(le=1000, strict=True)]] = Field( - default=100, - description="Maximum number of facet values to return for each facet.", - alias="maxValuesPerFacet", - ) - sort_facet_values_by: Optional[StrictStr] = Field( - default="count", - description="Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). ", - alias="sortFacetValuesBy", - ) - attribute_criteria_computed_by_min_proximity: Optional[StrictBool] = Field( - default=False, - description="Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. ", - alias="attributeCriteriaComputedByMinProximity", - ) + default=None, alias="advancedSyntaxFeatures" + ) + """ Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue \"iPhone case\"` only returns records with the exact string \"iPhone case\". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain \"search\" but not \"engine\". This setting only has an effect if `advancedSyntax` is true. """ + distinct: Optional[Distinct] = Field(default=None, alias="distinct") + replace_synonyms_in_highlight: Optional[bool] = Field( + default=None, alias="replaceSynonymsInHighlight" + ) + """ Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either \"home\" or \"house\" are included in the search results, and either \"home\" or \"house\" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of \"house\" are replaced by \"home\" in the highlighted response. """ + min_proximity: Optional[int] = Field(default=None, alias="minProximity") + """ Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. """ + response_fields: Optional[List[str]] = Field(default=None, alias="responseFields") + """ Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. """ + max_facet_hits: Optional[int] = Field(default=None, alias="maxFacetHits") + """ Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values). """ + max_values_per_facet: Optional[int] = Field(default=None, alias="maxValuesPerFacet") + """ Maximum number of facet values to return for each facet. """ + sort_facet_values_by: Optional[str] = Field(default=None, alias="sortFacetValuesBy") + """ Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). """ + attribute_criteria_computed_by_min_proximity: Optional[bool] = Field( + default=None, alias="attributeCriteriaComputedByMinProximity" + ) + """ Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. """ rendering_content: Optional[RenderingContent] = Field( default=None, alias="renderingContent" ) - enable_re_ranking: Optional[StrictBool] = Field( - default=True, - description="Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. ", - alias="enableReRanking", - ) + enable_re_ranking: Optional[bool] = Field(default=None, alias="enableReRanking") + """ Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. """ re_ranking_apply_filter: Optional[ReRankingApplyFilter] = Field( default=None, alias="reRankingApplyFilter" ) model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchParamsObject from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.facet_filters: - _dict["facetFilters"] = self.facet_filters.to_dict() - if self.optional_filters: - _dict["optionalFilters"] = self.optional_filters.to_dict() - if self.numeric_filters: - _dict["numericFilters"] = self.numeric_filters.to_dict() - if self.tag_filters: - _dict["tagFilters"] = self.tag_filters.to_dict() - if self.around_radius: - _dict["aroundRadius"] = self.around_radius.to_dict() - if self.around_precision: - _dict["aroundPrecision"] = self.around_precision.to_dict() - if self.typo_tolerance: - _dict["typoTolerance"] = self.typo_tolerance.to_dict() - if self.ignore_plurals: - _dict["ignorePlurals"] = self.ignore_plurals.to_dict() - if self.remove_stop_words: - _dict["removeStopWords"] = self.remove_stop_words.to_dict() - if self.semantic_search: - _dict["semanticSearch"] = self.semantic_search.to_dict() - if self.distinct: - _dict["distinct"] = self.distinct.to_dict() - if self.rendering_content: - _dict["renderingContent"] = self.rendering_content.to_dict() - if self.re_ranking_apply_filter: - _dict["reRankingApplyFilter"] = self.re_ranking_apply_filter.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchParamsObject from a dict""" if obj is None: return None @@ -449,142 +291,78 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "query": obj.get("query"), - "similarQuery": obj.get("similarQuery"), - "filters": obj.get("filters"), - "facetFilters": ( - FacetFilters.from_dict(obj.get("facetFilters")) - if obj.get("facetFilters") is not None - else None - ), - "optionalFilters": ( - OptionalFilters.from_dict(obj.get("optionalFilters")) - if obj.get("optionalFilters") is not None - else None - ), - "numericFilters": ( - NumericFilters.from_dict(obj.get("numericFilters")) - if obj.get("numericFilters") is not None - else None - ), - "tagFilters": ( - TagFilters.from_dict(obj.get("tagFilters")) - if obj.get("tagFilters") is not None - else None - ), - "sumOrFiltersScores": obj.get("sumOrFiltersScores"), - "restrictSearchableAttributes": obj.get("restrictSearchableAttributes"), - "facets": obj.get("facets"), - "facetingAfterDistinct": obj.get("facetingAfterDistinct"), - "page": obj.get("page"), - "offset": obj.get("offset"), - "length": obj.get("length"), - "aroundLatLng": obj.get("aroundLatLng"), - "aroundLatLngViaIP": obj.get("aroundLatLngViaIP"), - "aroundRadius": ( - AroundRadius.from_dict(obj.get("aroundRadius")) - if obj.get("aroundRadius") is not None - else None - ), - "aroundPrecision": ( - AroundPrecision.from_dict(obj.get("aroundPrecision")) - if obj.get("aroundPrecision") is not None - else None - ), - "minimumAroundRadius": obj.get("minimumAroundRadius"), - "insideBoundingBox": obj.get("insideBoundingBox"), - "insidePolygon": obj.get("insidePolygon"), - "naturalLanguages": obj.get("naturalLanguages"), - "ruleContexts": obj.get("ruleContexts"), - "personalizationImpact": obj.get("personalizationImpact"), - "userToken": obj.get("userToken"), - "getRankingInfo": obj.get("getRankingInfo"), - "synonyms": obj.get("synonyms"), - "clickAnalytics": obj.get("clickAnalytics"), - "analytics": obj.get("analytics"), - "analyticsTags": obj.get("analyticsTags"), - "percentileComputation": obj.get("percentileComputation"), - "enableABTest": obj.get("enableABTest"), - "attributesToRetrieve": obj.get("attributesToRetrieve"), - "ranking": obj.get("ranking"), - "customRanking": obj.get("customRanking"), - "relevancyStrictness": obj.get("relevancyStrictness"), - "attributesToHighlight": obj.get("attributesToHighlight"), - "attributesToSnippet": obj.get("attributesToSnippet"), - "highlightPreTag": obj.get("highlightPreTag"), - "highlightPostTag": obj.get("highlightPostTag"), - "snippetEllipsisText": obj.get("snippetEllipsisText"), - "restrictHighlightAndSnippetArrays": obj.get( - "restrictHighlightAndSnippetArrays" - ), - "hitsPerPage": obj.get("hitsPerPage"), - "minWordSizefor1Typo": obj.get("minWordSizefor1Typo"), - "minWordSizefor2Typos": obj.get("minWordSizefor2Typos"), - "typoTolerance": ( - TypoTolerance.from_dict(obj.get("typoTolerance")) - if obj.get("typoTolerance") is not None - else None - ), - "allowTyposOnNumericTokens": obj.get("allowTyposOnNumericTokens"), - "disableTypoToleranceOnAttributes": obj.get( - "disableTypoToleranceOnAttributes" - ), - "ignorePlurals": ( - IgnorePlurals.from_dict(obj.get("ignorePlurals")) - if obj.get("ignorePlurals") is not None - else None - ), - "removeStopWords": ( - RemoveStopWords.from_dict(obj.get("removeStopWords")) - if obj.get("removeStopWords") is not None - else None - ), - "keepDiacriticsOnCharacters": obj.get("keepDiacriticsOnCharacters"), - "queryLanguages": obj.get("queryLanguages"), - "decompoundQuery": obj.get("decompoundQuery"), - "enableRules": obj.get("enableRules"), - "enablePersonalization": obj.get("enablePersonalization"), - "queryType": obj.get("queryType"), - "removeWordsIfNoResults": obj.get("removeWordsIfNoResults"), - "mode": obj.get("mode"), - "semanticSearch": ( - SemanticSearch.from_dict(obj.get("semanticSearch")) - if obj.get("semanticSearch") is not None - else None - ), - "advancedSyntax": obj.get("advancedSyntax"), - "optionalWords": obj.get("optionalWords"), - "disableExactOnAttributes": obj.get("disableExactOnAttributes"), - "exactOnSingleWordQuery": obj.get("exactOnSingleWordQuery"), - "alternativesAsExact": obj.get("alternativesAsExact"), - "advancedSyntaxFeatures": obj.get("advancedSyntaxFeatures"), - "distinct": ( - Distinct.from_dict(obj.get("distinct")) - if obj.get("distinct") is not None - else None - ), - "replaceSynonymsInHighlight": obj.get("replaceSynonymsInHighlight"), - "minProximity": obj.get("minProximity"), - "responseFields": obj.get("responseFields"), - "maxFacetHits": obj.get("maxFacetHits"), - "maxValuesPerFacet": obj.get("maxValuesPerFacet"), - "sortFacetValuesBy": obj.get("sortFacetValuesBy"), - "attributeCriteriaComputedByMinProximity": obj.get( - "attributeCriteriaComputedByMinProximity" - ), - "renderingContent": ( - RenderingContent.from_dict(obj.get("renderingContent")) - if obj.get("renderingContent") is not None - else None - ), - "enableReRanking": obj.get("enableReRanking"), - "reRankingApplyFilter": ( - ReRankingApplyFilter.from_dict(obj.get("reRankingApplyFilter")) - if obj.get("reRankingApplyFilter") is not None - else None - ), - } + obj["facetFilters"] = ( + FacetFilters.from_dict(obj["facetFilters"]) + if obj.get("facetFilters") is not None + else None + ) + obj["optionalFilters"] = ( + OptionalFilters.from_dict(obj["optionalFilters"]) + if obj.get("optionalFilters") is not None + else None + ) + obj["numericFilters"] = ( + NumericFilters.from_dict(obj["numericFilters"]) + if obj.get("numericFilters") is not None + else None + ) + obj["tagFilters"] = ( + TagFilters.from_dict(obj["tagFilters"]) + if obj.get("tagFilters") is not None + else None + ) + obj["aroundRadius"] = ( + AroundRadius.from_dict(obj["aroundRadius"]) + if obj.get("aroundRadius") is not None + else None ) - return _obj + obj["aroundPrecision"] = ( + AroundPrecision.from_dict(obj["aroundPrecision"]) + if obj.get("aroundPrecision") is not None + else None + ) + obj["naturalLanguages"] = obj.get("naturalLanguages") + obj["typoTolerance"] = ( + TypoTolerance.from_dict(obj["typoTolerance"]) + if obj.get("typoTolerance") is not None + else None + ) + obj["ignorePlurals"] = ( + IgnorePlurals.from_dict(obj["ignorePlurals"]) + if obj.get("ignorePlurals") is not None + else None + ) + obj["removeStopWords"] = ( + RemoveStopWords.from_dict(obj["removeStopWords"]) + if obj.get("removeStopWords") is not None + else None + ) + obj["queryLanguages"] = obj.get("queryLanguages") + obj["queryType"] = obj.get("queryType") + obj["removeWordsIfNoResults"] = obj.get("removeWordsIfNoResults") + obj["mode"] = obj.get("mode") + obj["semanticSearch"] = ( + SemanticSearch.from_dict(obj["semanticSearch"]) + if obj.get("semanticSearch") is not None + else None + ) + obj["exactOnSingleWordQuery"] = obj.get("exactOnSingleWordQuery") + obj["alternativesAsExact"] = obj.get("alternativesAsExact") + obj["advancedSyntaxFeatures"] = obj.get("advancedSyntaxFeatures") + obj["distinct"] = ( + Distinct.from_dict(obj["distinct"]) + if obj.get("distinct") is not None + else None + ) + obj["renderingContent"] = ( + RenderingContent.from_dict(obj["renderingContent"]) + if obj.get("renderingContent") is not None + else None + ) + obj["reRankingApplyFilter"] = ( + ReRankingApplyFilter.from_dict(obj["reRankingApplyFilter"]) + if obj.get("reRankingApplyFilter") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/search_params_string.py b/algoliasearch/search/models/search_params_string.py index f9554400c..c9c258e19 100644 --- a/algoliasearch/search/models/search_params_string.py +++ b/algoliasearch/search/models/search_params_string.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,42 +23,34 @@ class SearchParamsString(BaseModel): Search parameters as query string. """ - params: Optional[StrictStr] = Field( - default="", description="Search parameters as a URL-encoded query string." - ) + params: Optional[str] = Field(default=None, alias="params") + """ Search parameters as a URL-encoded query string. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchParamsString from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchParamsString from a dict""" if obj is None: return None @@ -66,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"params": obj.get("params")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/search_query.py b/algoliasearch/search/models/search_query.py index 9a76696b5..86c6d7e28 100644 --- a/algoliasearch/search/models/search_query.py +++ b/algoliasearch/search/models/search_query.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -27,9 +27,12 @@ class SearchQuery(BaseModel): SearchQuery """ - oneof_schema_1_validator: Optional[SearchForHits] = None - oneof_schema_2_validator: Optional[SearchForFacets] = None + oneof_schema_1_validator: Optional[SearchForHits] = Field(default=None) + + oneof_schema_2_validator: Optional[SearchForFacets] = Field(default=None) + actual_instance: Optional[Union[SearchForFacets, SearchForHits]] = None + one_of_schemas: Set[str] = {"SearchForFacets", "SearchForHits"} def __init__(self, *args, **kwargs) -> None: if args: @@ -53,7 +56,8 @@ def unwrap_actual_instance(self) -> Optional[Union[SearchForFacets, SearchForHit return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of SearchQuery from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -85,17 +89,23 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[Union[Dict[str, Any], SearchForFacets, SearchForHits]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/search_response.py b/algoliasearch/search/models/search_response.py index caa0a1494..b06eeccd3 100644 --- a/algoliasearch/search/models/search_response.py +++ b/algoliasearch/search/models/search_response.py @@ -9,22 +9,14 @@ from json import loads from re import match from sys import version_info -from typing import Any, ClassVar, Dict, List, Optional +from typing import Any, Dict, List, Optional -from pydantic import ( - BaseModel, - ConfigDict, - Field, - StrictBool, - StrictInt, - StrictStr, - field_validator, -) +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.exhaustive import Exhaustive @@ -39,166 +31,75 @@ class SearchResponse(BaseModel): SearchResponse """ - ab_test_id: Optional[StrictInt] = Field( - default=None, - description="A/B test ID. This is only included in the response for indices that are part of an A/B test.", - alias="abTestID", - ) - ab_test_variant_id: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field( - default=None, - description="Variant ID. This is only included in the response for indices that are part of an A/B test.", - alias="abTestVariantID", - ) - around_lat_lng: Optional[Annotated[str, Field(strict=True)]] = Field( - default=None, - description="Computed geographical location.", - alias="aroundLatLng", - ) - automatic_radius: Optional[StrictStr] = Field( - default=None, - description="Distance from a central coordinate provided by `aroundLatLng`.", - alias="automaticRadius", - ) - exhaustive: Optional[Exhaustive] = None - exhaustive_facets_count: Optional[StrictBool] = Field( - default=None, - description="See the `facetsCount` field of the `exhaustive` object in the response.", - alias="exhaustiveFacetsCount", - ) - exhaustive_nb_hits: Optional[StrictBool] = Field( - default=None, - description="See the `nbHits` field of the `exhaustive` object in the response.", - alias="exhaustiveNbHits", - ) - exhaustive_typo: Optional[StrictBool] = Field( - default=None, - description="See the `typo` field of the `exhaustive` object in the response.", - alias="exhaustiveTypo", - ) - facets: Optional[Dict[str, Dict[str, StrictInt]]] = Field( - default=None, description="Facet counts." - ) + ab_test_id: Optional[int] = Field(default=None, alias="abTestID") + """ A/B test ID. This is only included in the response for indices that are part of an A/B test. """ + ab_test_variant_id: Optional[int] = Field(default=None, alias="abTestVariantID") + """ Variant ID. This is only included in the response for indices that are part of an A/B test. """ + around_lat_lng: Optional[str] = Field(default=None, alias="aroundLatLng") + """ Computed geographical location. """ + automatic_radius: Optional[str] = Field(default=None, alias="automaticRadius") + """ Distance from a central coordinate provided by `aroundLatLng`. """ + exhaustive: Optional[Exhaustive] = Field(default=None, alias="exhaustive") + exhaustive_facets_count: Optional[bool] = Field( + default=None, alias="exhaustiveFacetsCount" + ) + """ See the `facetsCount` field of the `exhaustive` object in the response. """ + exhaustive_nb_hits: Optional[bool] = Field(default=None, alias="exhaustiveNbHits") + """ See the `nbHits` field of the `exhaustive` object in the response. """ + exhaustive_typo: Optional[bool] = Field(default=None, alias="exhaustiveTypo") + """ See the `typo` field of the `exhaustive` object in the response. """ + facets: Optional[Dict[str, Dict[str, int]]] = Field(default=None, alias="facets") + """ Facet counts. """ facets_stats: Optional[Dict[str, FacetStats]] = Field( - default=None, description="Statistics for numerical facets." - ) - index: Optional[StrictStr] = Field( - default=None, description="Index name used for the query." - ) - index_used: Optional[StrictStr] = Field( - default=None, - description="Index name used for the query. During A/B testing, the targeted index isn't always the index used by the query.", - alias="indexUsed", - ) - message: Optional[StrictStr] = Field( - default=None, description="Warnings about the query." - ) - nb_sorted_hits: Optional[StrictInt] = Field( - default=None, - description="Number of hits selected and sorted by the relevant sort algorithm.", - alias="nbSortedHits", - ) - parsed_query: Optional[StrictStr] = Field( - default=None, - description="Post-[normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/#what-does-normalization-mean) query string that will be searched.", - alias="parsedQuery", - ) - processing_time_ms: StrictInt = Field( - description="Time the server took to process the request, in milliseconds.", - alias="processingTimeMS", - ) - processing_timings_ms: Optional[Dict[str, Any]] = Field( - default=None, - description="Experimental. List of processing steps and their times, in milliseconds. You can use this list to investigate performance issues.", - alias="processingTimingsMS", - ) - query_after_removal: Optional[StrictStr] = Field( - default=None, - description="Markup text indicating which parts of the original query have been removed to retrieve a non-empty result set.", - alias="queryAfterRemoval", - ) - redirect: Optional[Redirect] = None + default=None, alias="facets_stats" + ) + """ Statistics for numerical facets. """ + index: Optional[str] = Field(default=None, alias="index") + """ Index name used for the query. """ + index_used: Optional[str] = Field(default=None, alias="indexUsed") + """ Index name used for the query. During A/B testing, the targeted index isn't always the index used by the query. """ + message: Optional[str] = Field(default=None, alias="message") + """ Warnings about the query. """ + nb_sorted_hits: Optional[int] = Field(default=None, alias="nbSortedHits") + """ Number of hits selected and sorted by the relevant sort algorithm. """ + parsed_query: Optional[str] = Field(default=None, alias="parsedQuery") + """ Post-[normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/#what-does-normalization-mean) query string that will be searched. """ + processing_time_ms: int = Field(alias="processingTimeMS") + """ Time the server took to process the request, in milliseconds. """ + processing_timings_ms: Optional[object] = Field( + default=None, alias="processingTimingsMS" + ) + """ Experimental. List of processing steps and their times, in milliseconds. You can use this list to investigate performance issues. """ + query_after_removal: Optional[str] = Field(default=None, alias="queryAfterRemoval") + """ Markup text indicating which parts of the original query have been removed to retrieve a non-empty result set. """ + redirect: Optional[Redirect] = Field(default=None, alias="redirect") rendering_content: Optional[RenderingContent] = Field( default=None, alias="renderingContent" ) - server_time_ms: Optional[StrictInt] = Field( - default=None, - description="Time the server took to process the request, in milliseconds.", - alias="serverTimeMS", - ) - server_used: Optional[StrictStr] = Field( - default=None, - description="Host name of the server that processed the request.", - alias="serverUsed", - ) - user_data: Optional[Dict[str, Any]] = Field( - default=None, - description="An object with custom data. You can store up to 32kB as custom data. ", - alias="userData", - ) - query_id: Optional[StrictStr] = Field( - default=None, - description="Unique identifier for the query. This is used for [click analytics](https://www.algolia.com/doc/guides/analytics/click-analytics/).", - alias="queryID", - ) - automatic_insights: Optional[StrictBool] = Field( - default=None, - description="Whether automatic events collection is enabled for the application.", - alias="_automaticInsights", - ) - page: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=0, description="Page of search results to retrieve." - ) - nb_hits: Optional[StrictInt] = Field( - default=None, description="Number of results (hits).", alias="nbHits" - ) - nb_pages: Optional[StrictInt] = Field( - default=None, description="Number of pages of results.", alias="nbPages" - ) - hits_per_page: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = Field( - default=20, description="Number of hits per page.", alias="hitsPerPage" - ) - hits: List[Hit] = Field( - description="Search results (hits). Hits are records from your index that match the search criteria, augmented with additional attributes, such as, for highlighting. " - ) - query: StrictStr = Field(description="Search query.") - params: StrictStr = Field( - description="URL-encoded string of all search parameters." - ) - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = [ - "abTestID", - "abTestVariantID", - "aroundLatLng", - "automaticRadius", - "exhaustive", - "exhaustiveFacetsCount", - "exhaustiveNbHits", - "exhaustiveTypo", - "facets", - "facets_stats", - "index", - "indexUsed", - "message", - "nbSortedHits", - "parsedQuery", - "processingTimeMS", - "processingTimingsMS", - "queryAfterRemoval", - "redirect", - "renderingContent", - "serverTimeMS", - "serverUsed", - "userData", - "queryID", - "_automaticInsights", - "page", - "nbHits", - "nbPages", - "hitsPerPage", - "hits", - "query", - "params", - ] + server_time_ms: Optional[int] = Field(default=None, alias="serverTimeMS") + """ Time the server took to process the request, in milliseconds. """ + server_used: Optional[str] = Field(default=None, alias="serverUsed") + """ Host name of the server that processed the request. """ + user_data: Optional[object] = Field(default=None, alias="userData") + """ An object with custom data. You can store up to 32kB as custom data. """ + query_id: Optional[str] = Field(default=None, alias="queryID") + """ Unique identifier for the query. This is used for [click analytics](https://www.algolia.com/doc/guides/analytics/click-analytics/). """ + automatic_insights: Optional[bool] = Field(default=None, alias="_automaticInsights") + """ Whether automatic events collection is enabled for the application. """ + page: Optional[int] = Field(default=None, alias="page") + """ Page of search results to retrieve. """ + nb_hits: Optional[int] = Field(default=None, alias="nbHits") + """ Number of results (hits). """ + nb_pages: Optional[int] = Field(default=None, alias="nbPages") + """ Number of pages of results. """ + hits_per_page: Optional[int] = Field(default=None, alias="hitsPerPage") + """ Number of hits per page. """ + hits: List[Hit] = Field(alias="hits") + """ Search results (hits). Hits are records from your index that match the search criteria, augmented with additional attributes, such as, for highlighting. """ + query: str = Field(alias="query") + """ Search query. """ + params: str = Field(alias="params") + """ URL-encoded string of all search parameters. """ @field_validator("around_lat_lng") def around_lat_lng_validate_regular_expression(cls, value): @@ -213,63 +114,31 @@ def around_lat_lng_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + extra="allow", ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={ - "additional_properties", - }, exclude_none=True, exclude_unset=True, ) - if self.exhaustive: - _dict["exhaustive"] = self.exhaustive.to_dict() - _field_dict = {} - if self.facets_stats: - for _key in self.facets_stats: - if self.facets_stats[_key]: - _field_dict[_key] = self.facets_stats[_key].to_dict() - _dict["facets_stats"] = _field_dict - if self.redirect: - _dict["redirect"] = self.redirect.to_dict() - if self.rendering_content: - _dict["renderingContent"] = self.rendering_content.to_dict() - _items = [] - if self.hits: - for _item in self.hits: - if _item: - _items.append(_item.to_dict()) - _dict["hits"] = _items - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchResponse from a dict""" if obj is None: return None @@ -277,68 +146,32 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "abTestID": obj.get("abTestID"), - "abTestVariantID": obj.get("abTestVariantID"), - "aroundLatLng": obj.get("aroundLatLng"), - "automaticRadius": obj.get("automaticRadius"), - "exhaustive": ( - Exhaustive.from_dict(obj.get("exhaustive")) - if obj.get("exhaustive") is not None - else None - ), - "exhaustiveFacetsCount": obj.get("exhaustiveFacetsCount"), - "exhaustiveNbHits": obj.get("exhaustiveNbHits"), - "exhaustiveTypo": obj.get("exhaustiveTypo"), - "facets": obj.get("facets"), - "facets_stats": ( - dict( - (_k, FacetStats.from_dict(_v)) - for _k, _v in obj.get("facets_stats").items() - ) - if obj.get("facets_stats") is not None - else None - ), - "index": obj.get("index"), - "indexUsed": obj.get("indexUsed"), - "message": obj.get("message"), - "nbSortedHits": obj.get("nbSortedHits"), - "parsedQuery": obj.get("parsedQuery"), - "processingTimeMS": obj.get("processingTimeMS"), - "processingTimingsMS": obj.get("processingTimingsMS"), - "queryAfterRemoval": obj.get("queryAfterRemoval"), - "redirect": ( - Redirect.from_dict(obj.get("redirect")) - if obj.get("redirect") is not None - else None - ), - "renderingContent": ( - RenderingContent.from_dict(obj.get("renderingContent")) - if obj.get("renderingContent") is not None - else None - ), - "serverTimeMS": obj.get("serverTimeMS"), - "serverUsed": obj.get("serverUsed"), - "userData": obj.get("userData"), - "queryID": obj.get("queryID"), - "_automaticInsights": obj.get("_automaticInsights"), - "page": obj.get("page"), - "nbHits": obj.get("nbHits"), - "nbPages": obj.get("nbPages"), - "hitsPerPage": obj.get("hitsPerPage"), - "hits": ( - [Hit.from_dict(_item) for _item in obj.get("hits")] - if obj.get("hits") is not None - else None - ), - "query": obj.get("query"), - "params": obj.get("params"), - } + obj["exhaustive"] = ( + Exhaustive.from_dict(obj["exhaustive"]) + if obj.get("exhaustive") is not None + else None + ) + obj["facets_stats"] = ( + dict( + (_k, FacetStats.from_dict(_v)) for _k, _v in obj["facets_stats"].items() + ) + if obj.get("facets_stats") is not None + else None + ) + obj["redirect"] = ( + Redirect.from_dict(obj["redirect"]) + if obj.get("redirect") is not None + else None + ) + obj["renderingContent"] = ( + RenderingContent.from_dict(obj["renderingContent"]) + if obj.get("renderingContent") is not None + else None + ) + obj["hits"] = ( + [Hit.from_dict(_item) for _item in obj["hits"]] + if obj.get("hits") is not None + else None ) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/search_responses.py b/algoliasearch/search/models/search_responses.py index 746f30292..99d0d7eba 100644 --- a/algoliasearch/search/models/search_responses.py +++ b/algoliasearch/search/models/search_responses.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,46 +26,33 @@ class SearchResponses(BaseModel): SearchResponses """ - results: List[SearchResult] + results: List[SearchResult] = Field(alias="results") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchResponses from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.results: - for _item in self.results: - if _item: - _items.append(_item.to_dict()) - _dict["results"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchResponses from a dict""" if obj is None: return None @@ -73,13 +60,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "results": ( - [SearchResult.from_dict(_item) for _item in obj.get("results")] - if obj.get("results") is not None - else None - ) - } + obj["results"] = ( + [SearchResult.from_dict(_item) for _item in obj["results"]] + if obj.get("results") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/search_result.py b/algoliasearch/search/models/search_result.py index d03268097..e23536f3f 100644 --- a/algoliasearch/search/models/search_result.py +++ b/algoliasearch/search/models/search_result.py @@ -8,9 +8,9 @@ from json import dumps from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -29,11 +29,16 @@ class SearchResult(BaseModel): SearchResult """ - oneof_schema_1_validator: Optional[SearchResponse] = None - oneof_schema_2_validator: Optional[SearchForFacetValuesResponse] = None + oneof_schema_1_validator: Optional[SearchResponse] = Field(default=None) + + oneof_schema_2_validator: Optional[SearchForFacetValuesResponse] = Field( + default=None + ) + actual_instance: Optional[Union[SearchForFacetValuesResponse, SearchResponse]] = ( None ) + one_of_schemas: Set[str] = {"SearchForFacetValuesResponse", "SearchResponse"} def __init__(self, *args, **kwargs) -> None: if args: @@ -59,7 +64,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of SearchResult from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -91,17 +97,23 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[Union[Dict[str, Any], SearchForFacetValuesResponse, SearchResponse]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/search_rules_params.py b/algoliasearch/search/models/search_rules_params.py index 2e4dc6b2e..562725a88 100644 --- a/algoliasearch/search/models/search_rules_params.py +++ b/algoliasearch/search/models/search_rules_params.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.anchoring import Anchoring @@ -26,57 +26,43 @@ class SearchRulesParams(BaseModel): Rules search parameters. """ - query: Optional[StrictStr] = Field( - default="", description="Search query for rules." - ) - anchoring: Optional[Anchoring] = None - context: Optional[StrictStr] = Field( - default=None, - description="Only return rules that match the context (exact match).", - ) - page: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=None, description="Requested page of the API response." - ) - hits_per_page: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = Field( - default=20, description="Maximum number of hits per page.", alias="hitsPerPage" - ) - enabled: Optional[StrictBool] = Field( - default=None, - description="If `true`, return only enabled rules. If `false`, return only inactive rules. By default, _all_ rules are returned. ", - ) + query: Optional[str] = Field(default=None, alias="query") + """ Search query for rules. """ + anchoring: Optional[Anchoring] = Field(default=None, alias="anchoring") + context: Optional[str] = Field(default=None, alias="context") + """ Only return rules that match the context (exact match). """ + page: Optional[int] = Field(default=None, alias="page") + """ Requested page of the API response. """ + hits_per_page: Optional[int] = Field(default=None, alias="hitsPerPage") + """ Maximum number of hits per page. """ + enabled: Optional[bool] = Field(default=None, alias="enabled") + """ If `true`, return only enabled rules. If `false`, return only inactive rules. By default, _all_ rules are returned. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchRulesParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchRulesParams from a dict""" if obj is None: return None @@ -84,14 +70,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "query": obj.get("query"), - "anchoring": obj.get("anchoring"), - "context": obj.get("context"), - "page": obj.get("page"), - "hitsPerPage": obj.get("hitsPerPage"), - "enabled": obj.get("enabled"), - } - ) - return _obj + obj["anchoring"] = obj.get("anchoring") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/search_rules_response.py b/algoliasearch/search/models/search_rules_response.py index 2593e1804..debe4d6ed 100644 --- a/algoliasearch/search/models/search_rules_response.py +++ b/algoliasearch/search/models/search_rules_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,51 +26,40 @@ class SearchRulesResponse(BaseModel): SearchRulesResponse """ - hits: List[Rule] = Field(description="Rules that matched the search criteria.") - nb_hits: StrictInt = Field( - description="Number of rules that matched the search criteria.", alias="nbHits" - ) - page: StrictInt = Field(description="Current page.") - nb_pages: StrictInt = Field(description="Number of pages.", alias="nbPages") + hits: List[Rule] = Field(alias="hits") + """ Rules that matched the search criteria. """ + nb_hits: int = Field(alias="nbHits") + """ Number of rules that matched the search criteria. """ + page: int = Field(alias="page") + """ Current page. """ + nb_pages: int = Field(alias="nbPages") + """ Number of pages. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchRulesResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.hits: - for _item in self.hits: - if _item: - _items.append(_item.to_dict()) - _dict["hits"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchRulesResponse from a dict""" if obj is None: return None @@ -78,16 +67,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "hits": ( - [Rule.from_dict(_item) for _item in obj.get("hits")] - if obj.get("hits") is not None - else None - ), - "nbHits": obj.get("nbHits"), - "page": obj.get("page"), - "nbPages": obj.get("nbPages"), - } + obj["hits"] = ( + [Rule.from_dict(_item) for _item in obj["hits"]] + if obj.get("hits") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/search_strategy.py b/algoliasearch/search/models/search_strategy.py index 684e7510b..37edde9d3 100644 --- a/algoliasearch/search/models/search_strategy.py +++ b/algoliasearch/search/models/search_strategy.py @@ -25,6 +25,7 @@ class SearchStrategy(str, Enum): allowed enum values """ NONE = "none" + STOPIFENOUGHMATCHES = "stopIfEnoughMatches" @classmethod diff --git a/algoliasearch/search/models/search_synonyms_params.py b/algoliasearch/search/models/search_synonyms_params.py index b8516a234..85a5cc1cc 100644 --- a/algoliasearch/search/models/search_synonyms_params.py +++ b/algoliasearch/search/models/search_synonyms_params.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.synonym_type import SynonymType @@ -26,47 +26,39 @@ class SearchSynonymsParams(BaseModel): SearchSynonymsParams """ - query: Optional[StrictStr] = Field(default="", description="Search query.") - type: Optional[SynonymType] = None - page: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=0, description="Page of search results to retrieve." - ) - hits_per_page: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = Field( - default=20, description="Number of hits per page.", alias="hitsPerPage" - ) + query: Optional[str] = Field(default=None, alias="query") + """ Search query. """ + type: Optional[SynonymType] = Field(default=None, alias="type") + page: Optional[int] = Field(default=None, alias="page") + """ Page of search results to retrieve. """ + hits_per_page: Optional[int] = Field(default=None, alias="hitsPerPage") + """ Number of hits per page. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchSynonymsParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchSynonymsParams from a dict""" if obj is None: return None @@ -74,12 +66,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "query": obj.get("query"), - "type": obj.get("type"), - "page": obj.get("page"), - "hitsPerPage": obj.get("hitsPerPage"), - } - ) - return _obj + obj["type"] = obj.get("type") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/search_synonyms_response.py b/algoliasearch/search/models/search_synonyms_response.py index e4f0c4f5b..873f82d72 100644 --- a/algoliasearch/search/models/search_synonyms_response.py +++ b/algoliasearch/search/models/search_synonyms_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, ClassVar, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,57 +26,37 @@ class SearchSynonymsResponse(BaseModel): SearchSynonymsResponse """ - hits: List[SynonymHit] = Field(description="Matching synonyms.") - nb_hits: StrictInt = Field(description="Number of results (hits).", alias="nbHits") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["hits", "nbHits"] + hits: List[SynonymHit] = Field(alias="hits") + """ Matching synonyms. """ + nb_hits: int = Field(alias="nbHits") + """ Number of results (hits). """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + extra="allow", ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchSynonymsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={ - "additional_properties", - }, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.hits: - for _item in self.hits: - if _item: - _items.append(_item.to_dict()) - _dict["hits"] = _items - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchSynonymsResponse from a dict""" if obj is None: return None @@ -84,19 +64,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "hits": ( - [SynonymHit.from_dict(_item) for _item in obj.get("hits")] - if obj.get("hits") is not None - else None - ), - "nbHits": obj.get("nbHits"), - } + obj["hits"] = ( + [SynonymHit.from_dict(_item) for _item in obj["hits"]] + if obj.get("hits") is not None + else None ) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/search_user_ids_params.py b/algoliasearch/search/models/search_user_ids_params.py index 5a81b4307..65e3ca1b0 100644 --- a/algoliasearch/search/models/search_user_ids_params.py +++ b/algoliasearch/search/models/search_user_ids_params.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class SearchUserIdsParams(BaseModel): @@ -23,51 +23,40 @@ class SearchUserIdsParams(BaseModel): OK """ - query: StrictStr = Field( - description="Query to search. The search is a prefix search with [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/) enabled. An empty query will retrieve all users." - ) - cluster_name: Optional[StrictStr] = Field( - default=None, description="Cluster name.", alias="clusterName" - ) - page: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=0, description="Page of search results to retrieve." - ) - hits_per_page: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = Field( - default=20, description="Number of hits per page.", alias="hitsPerPage" - ) + query: str = Field(alias="query") + """ Query to search. The search is a prefix search with [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/) enabled. An empty query will retrieve all users. """ + cluster_name: Optional[str] = Field(default=None, alias="clusterName") + """ Cluster name. """ + page: Optional[int] = Field(default=None, alias="page") + """ Page of search results to retrieve. """ + hits_per_page: Optional[int] = Field(default=None, alias="hitsPerPage") + """ Number of hits per page. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchUserIdsParams from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchUserIdsParams from a dict""" if obj is None: return None @@ -75,12 +64,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "query": obj.get("query"), - "clusterName": obj.get("clusterName"), - "page": obj.get("page"), - "hitsPerPage": obj.get("hitsPerPage"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/search_user_ids_response.py b/algoliasearch/search/models/search_user_ids_response.py index d4dd54026..0cba7d6f1 100644 --- a/algoliasearch/search/models/search_user_ids_response.py +++ b/algoliasearch/search/models/search_user_ids_response.py @@ -8,14 +8,14 @@ from json import loads from sys import version_info -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.user_hit import UserHit @@ -26,57 +26,42 @@ class SearchUserIdsResponse(BaseModel): userIDs data. """ - hits: List[UserHit] = Field(description="User objects that match the query.") - nb_hits: StrictInt = Field(description="Number of results (hits).", alias="nbHits") - page: Annotated[int, Field(strict=True, ge=0)] = Field( - description="Page of search results to retrieve." - ) - hits_per_page: Annotated[int, Field(le=1000, strict=True, ge=1)] = Field( - description="Maximum number of hits per page.", alias="hitsPerPage" - ) - updated_at: StrictStr = Field( - description="Date and time when the object was updated, in RFC 3339 format.", - alias="updatedAt", - ) + hits: List[UserHit] = Field(alias="hits") + """ User objects that match the query. """ + nb_hits: int = Field(alias="nbHits") + """ Number of results (hits). """ + page: int = Field(alias="page") + """ Page of search results to retrieve. """ + hits_per_page: int = Field(alias="hitsPerPage") + """ Maximum number of hits per page. """ + updated_at: str = Field(alias="updatedAt") + """ Date and time when the object was updated, in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SearchUserIdsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - _items = [] - if self.hits: - for _item in self.hits: - if _item: - _items.append(_item.to_dict()) - _dict["hits"] = _items - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SearchUserIdsResponse from a dict""" if obj is None: return None @@ -84,17 +69,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "hits": ( - [UserHit.from_dict(_item) for _item in obj.get("hits")] - if obj.get("hits") is not None - else None - ), - "nbHits": obj.get("nbHits"), - "page": obj.get("page"), - "hitsPerPage": obj.get("hitsPerPage"), - "updatedAt": obj.get("updatedAt"), - } + obj["hits"] = ( + [UserHit.from_dict(_item) for _item in obj["hits"]] + if obj.get("hits") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/secured_api_key_restrictions.py b/algoliasearch/search/models/secured_api_key_restrictions.py index 2e33a2f8f..756acabe3 100644 --- a/algoliasearch/search/models/secured_api_key_restrictions.py +++ b/algoliasearch/search/models/secured_api_key_restrictions.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -29,65 +29,42 @@ class SecuredApiKeyRestrictions(BaseModel): search_params: Optional[SearchParamsObject] = Field( default=None, alias="searchParams" ) - filters: Optional[StrictStr] = Field( - default=None, - description="Filters that apply to every search made with the secured API key. Extra filters added at search time will be combined with `AND`. For example, if you set `group:admin` as fixed filter on your generated API key, and add `groups:visitors` to the search query, the complete set of filters will be `group:admin AND groups:visitors`. ", - ) - valid_until: Optional[StrictInt] = Field( - default=None, - description="Timestamp when the secured API key expires, measured in seconds since the Unix epoch.", - alias="validUntil", - ) - restrict_indices: Optional[List[StrictStr]] = Field( - default=None, - description='Index names or patterns that this API key can access. By default, an API key can access all indices in the same application. You can use leading and trailing wildcard characters (`*`): - `dev_*` matches all indices starting with "dev_". - `*_dev` matches all indices ending with "_dev". - `*_products_*` matches all indices containing "_products_". ', - alias="restrictIndices", - ) - restrict_sources: Optional[StrictStr] = Field( - default=None, - description="IP network that are allowed to use this key. You can only add a single source, but you can provide a range of IP addresses. Use this to protect against API key leaking and reuse. ", - alias="restrictSources", - ) - user_token: Optional[StrictStr] = Field( - default=None, - description="Pseudonymous user identifier to restrict usage of this API key to specific users. By default, rate limits are set based on IP addresses. This can be an issue if many users search from the same IP address. To avoid this, add a user token to each generated API key. ", - alias="userToken", - ) + filters: Optional[str] = Field(default=None, alias="filters") + """ Filters that apply to every search made with the secured API key. Extra filters added at search time will be combined with `AND`. For example, if you set `group:admin` as fixed filter on your generated API key, and add `groups:visitors` to the search query, the complete set of filters will be `group:admin AND groups:visitors`. """ + valid_until: Optional[int] = Field(default=None, alias="validUntil") + """ Timestamp when the secured API key expires, measured in seconds since the Unix epoch. """ + restrict_indices: Optional[List[str]] = Field(default=None, alias="restrictIndices") + """ Index names or patterns that this API key can access. By default, an API key can access all indices in the same application. You can use leading and trailing wildcard characters (`*`): - `dev_*` matches all indices starting with \"dev_\". - `*_dev` matches all indices ending with \"_dev\". - `*_products_*` matches all indices containing \"_products_\". """ + restrict_sources: Optional[str] = Field(default=None, alias="restrictSources") + """ IP network that are allowed to use this key. You can only add a single source, but you can provide a range of IP addresses. Use this to protect against API key leaking and reuse. """ + user_token: Optional[str] = Field(default=None, alias="userToken") + """ Pseudonymous user identifier to restrict usage of this API key to specific users. By default, rate limits are set based on IP addresses. This can be an issue if many users search from the same IP address. To avoid this, add a user token to each generated API key. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SecuredApiKeyRestrictions from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.search_params: - _dict["searchParams"] = self.search_params.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SecuredApiKeyRestrictions from a dict""" if obj is None: return None @@ -95,18 +72,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "searchParams": ( - SearchParamsObject.from_dict(obj.get("searchParams")) - if obj.get("searchParams") is not None - else None - ), - "filters": obj.get("filters"), - "validUntil": obj.get("validUntil"), - "restrictIndices": obj.get("restrictIndices"), - "restrictSources": obj.get("restrictSources"), - "userToken": obj.get("userToken"), - } + obj["searchParams"] = ( + SearchParamsObject.from_dict(obj["searchParams"]) + if obj.get("searchParams") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/semantic_search.py b/algoliasearch/search/models/semantic_search.py index 8a91b3662..31559fe7b 100644 --- a/algoliasearch/search/models/semantic_search.py +++ b/algoliasearch/search/models/semantic_search.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,44 +23,34 @@ class SemanticSearch(BaseModel): Settings for the semantic search part of NeuralSearch. Only used when `mode` is `neuralSearch`. """ - event_sources: Optional[List[StrictStr]] = Field( - default=None, - description="Indices from which to collect click and conversion events. If null, the current index and all its replicas are used. ", - alias="eventSources", - ) + event_sources: Optional[List[str]] = Field(default=None, alias="eventSources") + """ Indices from which to collect click and conversion events. If null, the current index and all its replicas are used. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SemanticSearch from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SemanticSearch from a dict""" if obj is None: return None @@ -68,5 +58,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"eventSources": obj.get("eventSources")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/settings_response.py b/algoliasearch/search/models/settings_response.py index 66f6eeebe..3fb9e6ed3 100644 --- a/algoliasearch/search/models/settings_response.py +++ b/algoliasearch/search/models/settings_response.py @@ -10,12 +10,12 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.advanced_syntax_features import AdvancedSyntaxFeatures @@ -43,326 +43,221 @@ class SettingsResponse(BaseModel): SettingsResponse """ - attributes_for_faceting: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes used for [faceting](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/). Facets are attributes that let you categorize search results. They can be used for filtering search results. By default, no attribute is used for faceting. Attribute names are case-sensitive. **Modifiers** - `filterOnly("ATTRIBUTE")`. Allows using this attribute as a filter, but doesn\'t evalue the facet values. - `searchable("ATTRIBUTE")`. Allows searching for facet values. - `afterDistinct("ATTRIBUTE")`. Evaluates the facet count _after_ deduplication with `distinct`. This ensures accurate facet counts. You can apply this modifier to searchable facets: `afterDistinct(searchable(ATTRIBUTE))`. ', - alias="attributesForFaceting", - ) - replicas: Optional[List[StrictStr]] = Field( - default=None, - description="Creates [replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/). Replicas are copies of a primary index with the same records but different settings, synonyms, or rules. If you want to offer a different ranking or sorting of your search results, you'll use replica indices. All index operations on a primary index are automatically forwarded to its replicas. To add a replica index, you must provide the complete set of replicas to this parameter. If you omit a replica from this list, the replica turns into a regular, standalone index that will no longer by synced with the primary index. **Modifier** - `virtual(\"REPLICA\")`. Create a virtual replica, Virtual replicas don't increase the number of records and are optimized for [Relevant sorting](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/relevant-sort/). ", - ) - pagination_limited_to: Optional[Annotated[int, Field(le=20000, strict=True)]] = ( - Field( - default=1000, - description="Maximum number of search results that can be obtained through pagination. Higher pagination limits might slow down your search. For pagination limits above 1,000, the sorting of results beyond the 1,000th hit can't be guaranteed. ", - alias="paginationLimitedTo", - ) + attributes_for_faceting: Optional[List[str]] = Field( + default=None, alias="attributesForFaceting" ) - unretrievable_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes that can't be retrieved at query time. This can be useful if you want to use an attribute for ranking or to [restrict access](https://www.algolia.com/doc/guides/security/api-keys/how-to/user-restricted-access-to-data/), but don't want to include it in the search results. Attribute names are case-sensitive. ", - alias="unretrievableAttributes", + """ Attributes used for [faceting](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/). Facets are attributes that let you categorize search results. They can be used for filtering search results. By default, no attribute is used for faceting. Attribute names are case-sensitive. **Modifiers** - `filterOnly(\"ATTRIBUTE\")`. Allows using this attribute as a filter, but doesn't evalue the facet values. - `searchable(\"ATTRIBUTE\")`. Allows searching for facet values. - `afterDistinct(\"ATTRIBUTE\")`. Evaluates the facet count _after_ deduplication with `distinct`. This ensures accurate facet counts. You can apply this modifier to searchable facets: `afterDistinct(searchable(ATTRIBUTE))`. """ + replicas: Optional[List[str]] = Field(default=None, alias="replicas") + """ Creates [replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/). Replicas are copies of a primary index with the same records but different settings, synonyms, or rules. If you want to offer a different ranking or sorting of your search results, you'll use replica indices. All index operations on a primary index are automatically forwarded to its replicas. To add a replica index, you must provide the complete set of replicas to this parameter. If you omit a replica from this list, the replica turns into a regular, standalone index that will no longer by synced with the primary index. **Modifier** - `virtual(\"REPLICA\")`. Create a virtual replica, Virtual replicas don't increase the number of records and are optimized for [Relevant sorting](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/relevant-sort/). """ + pagination_limited_to: Optional[int] = Field( + default=None, alias="paginationLimitedTo" ) - disable_typo_tolerance_on_words: Optional[List[StrictStr]] = Field( - default=None, - description="Words for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). This also turns off [word splitting and concatenation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/splitting-and-concatenation/) for the specified words. ", - alias="disableTypoToleranceOnWords", + """ Maximum number of search results that can be obtained through pagination. Higher pagination limits might slow down your search. For pagination limits above 1,000, the sorting of results beyond the 1,000th hit can't be guaranteed. """ + unretrievable_attributes: Optional[List[str]] = Field( + default=None, alias="unretrievableAttributes" ) - attributes_to_transliterate: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes, for which you want to support [Japanese transliteration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#japanese-transliteration-and-type-ahead). Transliteration supports searching in any of the Japanese writing systems. To support transliteration, you must set the indexing language to Japanese. Attribute names are case-sensitive. ", - alias="attributesToTransliterate", + """ Attributes that can't be retrieved at query time. This can be useful if you want to use an attribute for ranking or to [restrict access](https://www.algolia.com/doc/guides/security/api-keys/how-to/user-restricted-access-to-data/), but don't want to include it in the search results. Attribute names are case-sensitive. """ + disable_typo_tolerance_on_words: Optional[List[str]] = Field( + default=None, alias="disableTypoToleranceOnWords" ) - camel_case_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which to split [camel case](https://wikipedia.org/wiki/Camel_case) words. Attribute names are case-sensitive. ", - alias="camelCaseAttributes", + """ Words for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). This also turns off [word splitting and concatenation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/splitting-and-concatenation/) for the specified words. """ + attributes_to_transliterate: Optional[List[str]] = Field( + default=None, alias="attributesToTransliterate" ) - decompounded_attributes: Optional[Dict[str, Any]] = Field( - default=None, - description="Searchable attributes to which Algolia should apply [word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-segmentation/) (decompounding). Attribute names are case-sensitive. Compound words are formed by combining two or more individual words, and are particularly prevalent in Germanic languages—for example, \"firefighter\". With decompounding, the individual components are indexed separately. You can specify different lists for different languages. Decompounding is supported for these languages: Dutch (`nl`), German (`de`), Finnish (`fi`), Danish (`da`), Swedish (`sv`), and Norwegian (`no`). Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). ", - alias="decompoundedAttributes", + """ Attributes, for which you want to support [Japanese transliteration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#japanese-transliteration-and-type-ahead). Transliteration supports searching in any of the Japanese writing systems. To support transliteration, you must set the indexing language to Japanese. Attribute names are case-sensitive. """ + camel_case_attributes: Optional[List[str]] = Field( + default=None, alias="camelCaseAttributes" ) - index_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="Languages for language-specific processing steps, such as word detection and dictionary settings. **You should always specify an indexing language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). ", - alias="indexLanguages", - ) - disable_prefix_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Searchable attributes for which you want to turn off [prefix matching](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/#adjusting-prefix-search). Attribute names are case-sensitive. ", - alias="disablePrefixOnAttributes", - ) - allow_compression_of_integer_array: Optional[StrictBool] = Field( - default=False, - description="Whether arrays with exclusively non-negative integers should be compressed for better performance. If true, the compressed arrays may be reordered. ", - alias="allowCompressionOfIntegerArray", - ) - numeric_attributes_for_filtering: Optional[List[StrictStr]] = Field( - default=None, - description='Numeric attributes that can be used as [numerical filters](https://www.algolia.com/doc/guides/managing-results/rules/detecting-intent/how-to/applying-a-custom-filter-for-a-specific-query/#numerical-filters). Attribute names are case-sensitive. By default, all numeric attributes are available as numerical filters. For faster indexing, reduce the number of numeric attributes. If you want to turn off filtering for all numeric attributes, specifiy an attribute that doesn\'t exist in your index, such as `NO_NUMERIC_FILTERING`. **Modifier** - `equalOnly("ATTRIBUTE")`. Support only filtering based on equality comparisons `=` and `!=`. ', - alias="numericAttributesForFiltering", - ) - separators_to_index: Optional[StrictStr] = Field( - default="", - description="Controls which separators are indexed. Separators are all non-letter characters except spaces and currency characters, such as $€£¥. By default, separator characters aren't indexed. With `separatorsToIndex`, Algolia treats separator characters as separate words. For example, a search for `C#` would report two matches. ", - alias="separatorsToIndex", - ) - searchable_attributes: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes used for searching. Attribute names are case-sensitive. By default, all attributes are searchable and the [Attribute](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#attribute) ranking criterion is turned off. With a non-empty list, Algolia only returns results with matches in the selected attributes. In addition, the Attribute ranking criterion is turned on: matches in attributes that are higher in the list of `searchableAttributes` rank first. To make matches in two attributes rank equally, include them in a comma-separated string, such as `"title,alternate_title"`. Attributes with the same priority are always unordered. For more information, see [Searchable attributes](https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/how-to/setting-searchable-attributes/). **Modifier** - `unordered("ATTRIBUTE")`. Ignore the position of a match within the attribute. Without modifier, matches at the beginning of an attribute rank higer than matches at the end. ', - alias="searchableAttributes", - ) - user_data: Optional[Dict[str, Any]] = Field( - default=None, - description="An object with custom data. You can store up to 32kB as custom data. ", - alias="userData", - ) - custom_normalization: Optional[Dict[str, Dict[str, StrictStr]]] = Field( - default=None, - description="Characters and their normalized replacements. This overrides Algolia's default [normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/). ", - alias="customNormalization", - ) - attribute_for_distinct: Optional[StrictStr] = Field( - default=None, - description="Attribute that should be used to establish groups of results. Attribute names are case-sensitive. All records with the same value for this attribute are considered a group. You can combine `attributeForDistinct` with the `distinct` search parameter to control how many items per group are included in the search results. If you want to use the same attribute also for faceting, use the `afterDistinct` modifier of the `attributesForFaceting` setting. This applies faceting _after_ deduplication, which will result in accurate facet counts. ", - alias="attributeForDistinct", - ) - attributes_to_retrieve: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `["*", "-ATTRIBUTE"]`. - The `objectID` attribute is always included. ', - alias="attributesToRetrieve", - ) - ranking: Optional[List[StrictStr]] = Field( - default=None, - description='Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they\'re specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc("ATTRIBUTE")`. Sort the index by the values of an attribute, in ascending order. - `desc("ATTRIBUTE")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). ', - ) - custom_ranking: Optional[List[StrictStr]] = Field( - default=None, - description='Attributes to use as [custom ranking](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/). Attribute names are case-sensitive. The custom ranking attributes decide which items are shown first if the other ranking criteria are equal. Records with missing values for your selected custom ranking attributes are always sorted last. Boolean attributes are sorted based on their alphabetical order. **Modifiers** - `asc("ATTRIBUTE")`. Sort the index by the values of an attribute, in ascending order. - `desc("ATTRIBUTE")`. Sort the index by the values of an attribute, in descending order. If you use two or more custom ranking attributes, [reduce the precision](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/how-to/controlling-custom-ranking-metrics-precision/) of your first attributes, or the other attributes will never be applied. ', - alias="customRanking", - ) - relevancy_strictness: Optional[StrictInt] = Field( - default=100, - description="Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. ", - alias="relevancyStrictness", - ) - attributes_to_highlight: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). ", - alias="attributesToHighlight", - ) - attributes_to_snippet: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. ", - alias="attributesToSnippet", - ) - highlight_pre_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert before the highlighted parts in all highlighted results and snippets.", - alias="highlightPreTag", - ) - highlight_post_tag: Optional[StrictStr] = Field( - default="", - description="HTML tag to insert after the highlighted parts in all highlighted results and snippets.", - alias="highlightPostTag", - ) - snippet_ellipsis_text: Optional[StrictStr] = Field( - default="…", - description="String used as an ellipsis indicator when a snippet is truncated.", - alias="snippetEllipsisText", - ) - restrict_highlight_and_snippet_arrays: Optional[StrictBool] = Field( - default=False, - description="Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. ", - alias="restrictHighlightAndSnippetArrays", - ) - hits_per_page: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = Field( - default=20, description="Number of hits per page.", alias="hitsPerPage" - ) - min_word_sizefor1_typo: Optional[StrictInt] = Field( - default=4, - description="Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor1Typo", - ) - min_word_sizefor2_typos: Optional[StrictInt] = Field( - default=8, - description="Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - alias="minWordSizefor2Typos", + """ Attributes for which to split [camel case](https://wikipedia.org/wiki/Camel_case) words. Attribute names are case-sensitive. """ + decompounded_attributes: Optional[object] = Field( + default=None, alias="decompoundedAttributes" ) + """ Searchable attributes to which Algolia should apply [word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-segmentation/) (decompounding). Attribute names are case-sensitive. Compound words are formed by combining two or more individual words, and are particularly prevalent in Germanic languages—for example, \"firefighter\". With decompounding, the individual components are indexed separately. You can specify different lists for different languages. Decompounding is supported for these languages: Dutch (`nl`), German (`de`), Finnish (`fi`), Danish (`da`), Swedish (`sv`), and Norwegian (`no`). Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). """ + index_languages: Optional[List[SupportedLanguage]] = Field( + default=None, alias="indexLanguages" + ) + """ Languages for language-specific processing steps, such as word detection and dictionary settings. **You should always specify an indexing language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). """ + disable_prefix_on_attributes: Optional[List[str]] = Field( + default=None, alias="disablePrefixOnAttributes" + ) + """ Searchable attributes for which you want to turn off [prefix matching](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/#adjusting-prefix-search). Attribute names are case-sensitive. """ + allow_compression_of_integer_array: Optional[bool] = Field( + default=None, alias="allowCompressionOfIntegerArray" + ) + """ Whether arrays with exclusively non-negative integers should be compressed for better performance. If true, the compressed arrays may be reordered. """ + numeric_attributes_for_filtering: Optional[List[str]] = Field( + default=None, alias="numericAttributesForFiltering" + ) + """ Numeric attributes that can be used as [numerical filters](https://www.algolia.com/doc/guides/managing-results/rules/detecting-intent/how-to/applying-a-custom-filter-for-a-specific-query/#numerical-filters). Attribute names are case-sensitive. By default, all numeric attributes are available as numerical filters. For faster indexing, reduce the number of numeric attributes. If you want to turn off filtering for all numeric attributes, specifiy an attribute that doesn't exist in your index, such as `NO_NUMERIC_FILTERING`. **Modifier** - `equalOnly(\"ATTRIBUTE\")`. Support only filtering based on equality comparisons `=` and `!=`. """ + separators_to_index: Optional[str] = Field(default=None, alias="separatorsToIndex") + """ Controls which separators are indexed. Separators are all non-letter characters except spaces and currency characters, such as $€£¥. By default, separator characters aren't indexed. With `separatorsToIndex`, Algolia treats separator characters as separate words. For example, a search for `C#` would report two matches. """ + searchable_attributes: Optional[List[str]] = Field( + default=None, alias="searchableAttributes" + ) + """ Attributes used for searching. Attribute names are case-sensitive. By default, all attributes are searchable and the [Attribute](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#attribute) ranking criterion is turned off. With a non-empty list, Algolia only returns results with matches in the selected attributes. In addition, the Attribute ranking criterion is turned on: matches in attributes that are higher in the list of `searchableAttributes` rank first. To make matches in two attributes rank equally, include them in a comma-separated string, such as `\"title,alternate_title\"`. Attributes with the same priority are always unordered. For more information, see [Searchable attributes](https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/how-to/setting-searchable-attributes/). **Modifier** - `unordered(\"ATTRIBUTE\")`. Ignore the position of a match within the attribute. Without modifier, matches at the beginning of an attribute rank higer than matches at the end. """ + user_data: Optional[object] = Field(default=None, alias="userData") + """ An object with custom data. You can store up to 32kB as custom data. """ + custom_normalization: Optional[Dict[str, Dict[str, str]]] = Field( + default=None, alias="customNormalization" + ) + """ Characters and their normalized replacements. This overrides Algolia's default [normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/). """ + attribute_for_distinct: Optional[str] = Field( + default=None, alias="attributeForDistinct" + ) + """ Attribute that should be used to establish groups of results. Attribute names are case-sensitive. All records with the same value for this attribute are considered a group. You can combine `attributeForDistinct` with the `distinct` search parameter to control how many items per group are included in the search results. If you want to use the same attribute also for faceting, use the `afterDistinct` modifier of the `attributesForFaceting` setting. This applies faceting _after_ deduplication, which will result in accurate facet counts. """ + attributes_to_retrieve: Optional[List[str]] = Field( + default=None, alias="attributesToRetrieve" + ) + """ Attributes to include in the API response. To reduce the size of your response, you can retrieve only some of the attributes. Attribute names are case-sensitive. - `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings. - To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `[\"*\", \"-ATTRIBUTE\"]`. - The `objectID` attribute is always included. """ + ranking: Optional[List[str]] = Field(default=None, alias="ranking") + """ Determines the order in which Algolia returns your results. By default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/). The tie-breaking algorithm sequentially applies each criterion in the order they're specified. If you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/), you put the sorting attribute at the top of the list. **Modifiers** - `asc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in ascending order. - `desc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in descending order. Before you modify the default setting, you should test your changes in the dashboard, and by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/). """ + custom_ranking: Optional[List[str]] = Field(default=None, alias="customRanking") + """ Attributes to use as [custom ranking](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/). Attribute names are case-sensitive. The custom ranking attributes decide which items are shown first if the other ranking criteria are equal. Records with missing values for your selected custom ranking attributes are always sorted last. Boolean attributes are sorted based on their alphabetical order. **Modifiers** - `asc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in ascending order. - `desc(\"ATTRIBUTE\")`. Sort the index by the values of an attribute, in descending order. If you use two or more custom ranking attributes, [reduce the precision](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/how-to/controlling-custom-ranking-metrics-precision/) of your first attributes, or the other attributes will never be applied. """ + relevancy_strictness: Optional[int] = Field( + default=None, alias="relevancyStrictness" + ) + """ Relevancy threshold below which less relevant results aren't included in the results. You can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas). Use this setting to strike a balance between the relevance and number of returned results. """ + attributes_to_highlight: Optional[List[str]] = Field( + default=None, alias="attributesToHighlight" + ) + """ Attributes to highlight. By default, all searchable attributes are highlighted. Use `*` to highlight all attributes or use an empty array `[]` to turn off highlighting. Attribute names are case-sensitive. With highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`. You can use this to visually highlight matching parts of a search query in your UI. For more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/). """ + attributes_to_snippet: Optional[List[str]] = Field( + default=None, alias="attributesToSnippet" + ) + """ Attributes for which to enable snippets. Attribute names are case-sensitive. Snippets provide additional context to matched words. If you enable snippets, they include 10 words, including the matched word. The matched word will also be wrapped by HTML tags for highlighting. You can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`, where `NUMBER` is the number of words to be extracted. """ + highlight_pre_tag: Optional[str] = Field(default=None, alias="highlightPreTag") + """ HTML tag to insert before the highlighted parts in all highlighted results and snippets. """ + highlight_post_tag: Optional[str] = Field(default=None, alias="highlightPostTag") + """ HTML tag to insert after the highlighted parts in all highlighted results and snippets. """ + snippet_ellipsis_text: Optional[str] = Field( + default=None, alias="snippetEllipsisText" + ) + """ String used as an ellipsis indicator when a snippet is truncated. """ + restrict_highlight_and_snippet_arrays: Optional[bool] = Field( + default=None, alias="restrictHighlightAndSnippetArrays" + ) + """ Whether to restrict highlighting and snippeting to items that at least partially matched the search query. By default, all items are highlighted and snippeted. """ + hits_per_page: Optional[int] = Field(default=None, alias="hitsPerPage") + """ Number of hits per page. """ + min_word_sizefor1_typo: Optional[int] = Field( + default=None, alias="minWordSizefor1Typo" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ + min_word_sizefor2_typos: Optional[int] = Field( + default=None, alias="minWordSizefor2Typos" + ) + """ Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos). """ typo_tolerance: Optional[TypoTolerance] = Field(default=None, alias="typoTolerance") - allow_typos_on_numeric_tokens: Optional[StrictBool] = Field( - default=True, - description="Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. ", - alias="allowTyposOnNumericTokens", + allow_typos_on_numeric_tokens: Optional[bool] = Field( + default=None, alias="allowTyposOnNumericTokens" ) - disable_typo_tolerance_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. ", - alias="disableTypoToleranceOnAttributes", + """ Whether to allow typos on numbers in the search query. Turn off this setting to reduce the number of irrelevant matches when searching in large sets of similar numbers. """ + disable_typo_tolerance_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableTypoToleranceOnAttributes" ) + """ Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/). Attribute names are case-sensitive. Returning only exact matches can help when: - [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/). - Reducing the number of matches when you have too many. This can happen with attributes that are long blocks of text, such as product descriptions. Consider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos. """ ignore_plurals: Optional[IgnorePlurals] = Field(default=None, alias="ignorePlurals") remove_stop_words: Optional[RemoveStopWords] = Field( default=None, alias="removeStopWords" ) - keep_diacritics_on_characters: Optional[StrictStr] = Field( - default="", - description="Characters for which diacritics should be preserved. By default, Algolia removes diacritics from letters. For example, `é` becomes `e`. If this causes issues in your search, you can specify characters that should keep their diacritics. ", - alias="keepDiacriticsOnCharacters", + keep_diacritics_on_characters: Optional[str] = Field( + default=None, alias="keepDiacriticsOnCharacters" ) + """ Characters for which diacritics should be preserved. By default, Algolia removes diacritics from letters. For example, `é` becomes `e`. If this causes issues in your search, you can specify characters that should keep their diacritics. """ query_languages: Optional[List[SupportedLanguage]] = Field( - default=None, - description="Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). ", - alias="queryLanguages", - ) - decompound_query: Optional[StrictBool] = Field( - default=True, - description="Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). ", - alias="decompoundQuery", - ) - enable_rules: Optional[StrictBool] = Field( - default=True, description="Whether to enable rules.", alias="enableRules" + default=None, alias="queryLanguages" ) - enable_personalization: Optional[StrictBool] = Field( - default=False, - description="Whether to enable Personalization.", - alias="enablePersonalization", + """ Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries. This setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings. This setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages. To support this, you must place the CJK language **first**. **You should always specify a query language.** If you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/), or the languages you specified with the `ignorePlurals` or `removeStopWords` parameters. This can lead to unexpected search results. For more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/). """ + decompound_query: Optional[bool] = Field(default=None, alias="decompoundQuery") + """ Whether to split compound words in the query into their building blocks. For more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words). Word segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian. Decompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark). For example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308). """ + enable_rules: Optional[bool] = Field(default=None, alias="enableRules") + """ Whether to enable rules. """ + enable_personalization: Optional[bool] = Field( + default=None, alias="enablePersonalization" ) + """ Whether to enable Personalization. """ query_type: Optional[QueryType] = Field(default=None, alias="queryType") remove_words_if_no_results: Optional[RemoveWordsIfNoResults] = Field( default=None, alias="removeWordsIfNoResults" ) - mode: Optional[Mode] = None + mode: Optional[Mode] = Field(default=None, alias="mode") semantic_search: Optional[SemanticSearch] = Field( default=None, alias="semanticSearch" ) - advanced_syntax: Optional[StrictBool] = Field( - default=False, - description="Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. ", - alias="advancedSyntax", - ) - optional_words: Optional[List[StrictStr]] = Field( - default=None, - description='Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn\'t include the optional words. For example, if the search query is "action video" and "video" is an optional word, the search engine runs two queries. One for "action video" and one for "action". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). ', - alias="optionalWords", - ) - disable_exact_on_attributes: Optional[List[StrictStr]] = Field( - default=None, - description="Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. ", - alias="disableExactOnAttributes", + advanced_syntax: Optional[bool] = Field(default=None, alias="advancedSyntax") + """ Whether to support phrase matching and excluding words from search queries. Use the `advancedSyntaxFeatures` parameter to control which feature is supported. """ + optional_words: Optional[List[str]] = Field(default=None, alias="optionalWords") + """ Words that should be considered optional when found in the query. By default, records must match all words in the search query to be included in the search results. Adding optional words can help to increase the number of search results by running an additional search query that doesn't include the optional words. For example, if the search query is \"action video\" and \"video\" is an optional word, the search engine runs two queries. One for \"action video\" and one for \"action\". Records that match all words are ranked higher. For a search query with 4 or more words **and** all its words are optional, the number of matched words required for a record to be included in the search results increases for every 1,000 records: - If `optionalWords` has less than 10 words, the required number of matched words increases by 1: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words. - If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words dividied by 5 (rounded down). For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words. For more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words). """ + disable_exact_on_attributes: Optional[List[str]] = Field( + default=None, alias="disableExactOnAttributes" ) + """ Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes). Attribute names are case-sensitive. This can be useful for attributes with long values, where the likelyhood of an exact match is high, such as product descriptions. Turning off the Exact ranking criterion for these attributes favors exact matching on other attributes. This reduces the impact of individual attributes with a lot of content on ranking. """ exact_on_single_word_query: Optional[ExactOnSingleWordQuery] = Field( default=None, alias="exactOnSingleWordQuery" ) alternatives_as_exact: Optional[List[AlternativesAsExact]] = Field( - default=None, - description='Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as "NY/NYC" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as "NY/New York" are considered exact matches. ', - alias="alternativesAsExact", + default=None, alias="alternativesAsExact" ) + """ Alternatives of query words that should be considered as exact matches by the Exact ranking criterion. - `ignorePlurals`. Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches. - `singleWordSynonym`. Single-word synonyms, such as \"NY/NYC\" are considered exact matches. - `multiWordsSynonym`. Multi-word synonyms, such as \"NY/New York\" are considered exact matches. """ advanced_syntax_features: Optional[List[AdvancedSyntaxFeatures]] = Field( - default=None, - description='Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue "iPhone case"` only returns records with the exact string "iPhone case". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain "search" but not "engine". This setting only has an effect if `advancedSyntax` is true. ', - alias="advancedSyntaxFeatures", - ) - distinct: Optional[Distinct] = None - replace_synonyms_in_highlight: Optional[StrictBool] = Field( - default=False, - description='Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either "home" or "house" are included in the search results, and either "home" or "house" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of "house" are replaced by "home" in the highlighted response. ', - alias="replaceSynonymsInHighlight", - ) - min_proximity: Optional[Annotated[int, Field(le=7, strict=True, ge=1)]] = Field( - default=1, - description="Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. ", - alias="minProximity", - ) - response_fields: Optional[List[StrictStr]] = Field( - default=None, - description="Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. ", - alias="responseFields", - ) - max_facet_hits: Optional[Annotated[int, Field(le=100, strict=True)]] = Field( - default=10, - description="Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values).", - alias="maxFacetHits", - ) - max_values_per_facet: Optional[Annotated[int, Field(le=1000, strict=True)]] = Field( - default=100, - description="Maximum number of facet values to return for each facet.", - alias="maxValuesPerFacet", - ) - sort_facet_values_by: Optional[StrictStr] = Field( - default="count", - description="Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). ", - alias="sortFacetValuesBy", - ) - attribute_criteria_computed_by_min_proximity: Optional[StrictBool] = Field( - default=False, - description="Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. ", - alias="attributeCriteriaComputedByMinProximity", - ) + default=None, alias="advancedSyntaxFeatures" + ) + """ Advanced search syntax features you want to support. - `exactPhrase`. Phrases in quotes must match exactly. For example, `sparkly blue \"iPhone case\"` only returns records with the exact string \"iPhone case\". - `excludeWords`. Query words prefixed with a `-` must not occur in a record. For example, `search -engine` matches records that contain \"search\" but not \"engine\". This setting only has an effect if `advancedSyntax` is true. """ + distinct: Optional[Distinct] = Field(default=None, alias="distinct") + replace_synonyms_in_highlight: Optional[bool] = Field( + default=None, alias="replaceSynonymsInHighlight" + ) + """ Whether to replace a highlighted word with the matched synonym. By default, the original words are highlighted even if a synonym matches. For example, with `home` as a synonym for `house` and a search for `home`, records matching either \"home\" or \"house\" are included in the search results, and either \"home\" or \"house\" are highlighted. With `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records, but all occurences of \"house\" are replaced by \"home\" in the highlighted response. """ + min_proximity: Optional[int] = Field(default=None, alias="minProximity") + """ Minimum proximity score for two matching words. This adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity) by equally scoring matches that are farther apart. For example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score. """ + response_fields: Optional[List[str]] = Field(default=None, alias="responseFields") + """ Properties to include in the API response of `search` and `browse` requests. By default, all response properties are included. To reduce the response size, you can select, which attributes should be included. You can't exclude these properties: `message`, `warning`, `cursor`, `serverUsed`, `indexUsed`, `abTestVariantID`, `parsedQuery`, or any property triggered by the `getRankingInfo` parameter. Don't exclude properties that you might need in your search UI. """ + max_facet_hits: Optional[int] = Field(default=None, alias="maxFacetHits") + """ Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values). """ + max_values_per_facet: Optional[int] = Field(default=None, alias="maxValuesPerFacet") + """ Maximum number of facet values to return for each facet. """ + sort_facet_values_by: Optional[str] = Field(default=None, alias="sortFacetValuesBy") + """ Order in which to retrieve facet values. - `count`. Facet values are retrieved by decreasing count. The count is the number of matching records containing this facet value. - `alpha`. Retrieve facet values alphabetically. This setting doesn't influence how facet values are displayed in your UI (see `renderingContent`). For more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/). """ + attribute_criteria_computed_by_min_proximity: Optional[bool] = Field( + default=None, alias="attributeCriteriaComputedByMinProximity" + ) + """ Whether the best matching attribute should be determined by minimum proximity. This setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting. If true, the best matching attribute is selected based on the minimum proximity of multiple matches. Otherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting. """ rendering_content: Optional[RenderingContent] = Field( default=None, alias="renderingContent" ) - enable_re_ranking: Optional[StrictBool] = Field( - default=True, - description="Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. ", - alias="enableReRanking", - ) + enable_re_ranking: Optional[bool] = Field(default=None, alias="enableReRanking") + """ Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/). This setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard. """ re_ranking_apply_filter: Optional[ReRankingApplyFilter] = Field( default=None, alias="reRankingApplyFilter" ) - primary: Optional[StrictStr] = Field( - default=None, - description="Replica indices only: the name of the primary index for this replica. ", - ) + primary: Optional[str] = Field(default=None, alias="primary") + """ Replica indices only: the name of the primary index for this replica. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SettingsResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.typo_tolerance: - _dict["typoTolerance"] = self.typo_tolerance.to_dict() - if self.ignore_plurals: - _dict["ignorePlurals"] = self.ignore_plurals.to_dict() - if self.remove_stop_words: - _dict["removeStopWords"] = self.remove_stop_words.to_dict() - if self.semantic_search: - _dict["semanticSearch"] = self.semantic_search.to_dict() - if self.distinct: - _dict["distinct"] = self.distinct.to_dict() - if self.rendering_content: - _dict["renderingContent"] = self.rendering_content.to_dict() - if self.re_ranking_apply_filter: - _dict["reRankingApplyFilter"] = self.re_ranking_apply_filter.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SettingsResponse from a dict""" if obj is None: return None @@ -370,108 +265,48 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "attributesForFaceting": obj.get("attributesForFaceting"), - "replicas": obj.get("replicas"), - "paginationLimitedTo": obj.get("paginationLimitedTo"), - "unretrievableAttributes": obj.get("unretrievableAttributes"), - "disableTypoToleranceOnWords": obj.get("disableTypoToleranceOnWords"), - "attributesToTransliterate": obj.get("attributesToTransliterate"), - "camelCaseAttributes": obj.get("camelCaseAttributes"), - "decompoundedAttributes": obj.get("decompoundedAttributes"), - "indexLanguages": obj.get("indexLanguages"), - "disablePrefixOnAttributes": obj.get("disablePrefixOnAttributes"), - "allowCompressionOfIntegerArray": obj.get( - "allowCompressionOfIntegerArray" - ), - "numericAttributesForFiltering": obj.get( - "numericAttributesForFiltering" - ), - "separatorsToIndex": obj.get("separatorsToIndex"), - "searchableAttributes": obj.get("searchableAttributes"), - "userData": obj.get("userData"), - "customNormalization": obj.get("customNormalization"), - "attributeForDistinct": obj.get("attributeForDistinct"), - "attributesToRetrieve": obj.get("attributesToRetrieve"), - "ranking": obj.get("ranking"), - "customRanking": obj.get("customRanking"), - "relevancyStrictness": obj.get("relevancyStrictness"), - "attributesToHighlight": obj.get("attributesToHighlight"), - "attributesToSnippet": obj.get("attributesToSnippet"), - "highlightPreTag": obj.get("highlightPreTag"), - "highlightPostTag": obj.get("highlightPostTag"), - "snippetEllipsisText": obj.get("snippetEllipsisText"), - "restrictHighlightAndSnippetArrays": obj.get( - "restrictHighlightAndSnippetArrays" - ), - "hitsPerPage": obj.get("hitsPerPage"), - "minWordSizefor1Typo": obj.get("minWordSizefor1Typo"), - "minWordSizefor2Typos": obj.get("minWordSizefor2Typos"), - "typoTolerance": ( - TypoTolerance.from_dict(obj.get("typoTolerance")) - if obj.get("typoTolerance") is not None - else None - ), - "allowTyposOnNumericTokens": obj.get("allowTyposOnNumericTokens"), - "disableTypoToleranceOnAttributes": obj.get( - "disableTypoToleranceOnAttributes" - ), - "ignorePlurals": ( - IgnorePlurals.from_dict(obj.get("ignorePlurals")) - if obj.get("ignorePlurals") is not None - else None - ), - "removeStopWords": ( - RemoveStopWords.from_dict(obj.get("removeStopWords")) - if obj.get("removeStopWords") is not None - else None - ), - "keepDiacriticsOnCharacters": obj.get("keepDiacriticsOnCharacters"), - "queryLanguages": obj.get("queryLanguages"), - "decompoundQuery": obj.get("decompoundQuery"), - "enableRules": obj.get("enableRules"), - "enablePersonalization": obj.get("enablePersonalization"), - "queryType": obj.get("queryType"), - "removeWordsIfNoResults": obj.get("removeWordsIfNoResults"), - "mode": obj.get("mode"), - "semanticSearch": ( - SemanticSearch.from_dict(obj.get("semanticSearch")) - if obj.get("semanticSearch") is not None - else None - ), - "advancedSyntax": obj.get("advancedSyntax"), - "optionalWords": obj.get("optionalWords"), - "disableExactOnAttributes": obj.get("disableExactOnAttributes"), - "exactOnSingleWordQuery": obj.get("exactOnSingleWordQuery"), - "alternativesAsExact": obj.get("alternativesAsExact"), - "advancedSyntaxFeatures": obj.get("advancedSyntaxFeatures"), - "distinct": ( - Distinct.from_dict(obj.get("distinct")) - if obj.get("distinct") is not None - else None - ), - "replaceSynonymsInHighlight": obj.get("replaceSynonymsInHighlight"), - "minProximity": obj.get("minProximity"), - "responseFields": obj.get("responseFields"), - "maxFacetHits": obj.get("maxFacetHits"), - "maxValuesPerFacet": obj.get("maxValuesPerFacet"), - "sortFacetValuesBy": obj.get("sortFacetValuesBy"), - "attributeCriteriaComputedByMinProximity": obj.get( - "attributeCriteriaComputedByMinProximity" - ), - "renderingContent": ( - RenderingContent.from_dict(obj.get("renderingContent")) - if obj.get("renderingContent") is not None - else None - ), - "enableReRanking": obj.get("enableReRanking"), - "reRankingApplyFilter": ( - ReRankingApplyFilter.from_dict(obj.get("reRankingApplyFilter")) - if obj.get("reRankingApplyFilter") is not None - else None - ), - "primary": obj.get("primary"), - } + obj["indexLanguages"] = obj.get("indexLanguages") + obj["typoTolerance"] = ( + TypoTolerance.from_dict(obj["typoTolerance"]) + if obj.get("typoTolerance") is not None + else None + ) + obj["ignorePlurals"] = ( + IgnorePlurals.from_dict(obj["ignorePlurals"]) + if obj.get("ignorePlurals") is not None + else None + ) + obj["removeStopWords"] = ( + RemoveStopWords.from_dict(obj["removeStopWords"]) + if obj.get("removeStopWords") is not None + else None + ) + obj["queryLanguages"] = obj.get("queryLanguages") + obj["queryType"] = obj.get("queryType") + obj["removeWordsIfNoResults"] = obj.get("removeWordsIfNoResults") + obj["mode"] = obj.get("mode") + obj["semanticSearch"] = ( + SemanticSearch.from_dict(obj["semanticSearch"]) + if obj.get("semanticSearch") is not None + else None ) - return _obj + obj["exactOnSingleWordQuery"] = obj.get("exactOnSingleWordQuery") + obj["alternativesAsExact"] = obj.get("alternativesAsExact") + obj["advancedSyntaxFeatures"] = obj.get("advancedSyntaxFeatures") + obj["distinct"] = ( + Distinct.from_dict(obj["distinct"]) + if obj.get("distinct") is not None + else None + ) + obj["renderingContent"] = ( + RenderingContent.from_dict(obj["renderingContent"]) + if obj.get("renderingContent") is not None + else None + ) + obj["reRankingApplyFilter"] = ( + ReRankingApplyFilter.from_dict(obj["reRankingApplyFilter"]) + if obj.get("reRankingApplyFilter") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/snippet_result.py b/algoliasearch/search/models/snippet_result.py index 5c9146b48..e1a42415f 100644 --- a/algoliasearch/search/models/snippet_result.py +++ b/algoliasearch/search/models/snippet_result.py @@ -8,7 +8,7 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union from pydantic import BaseModel, Field, ValidationError, model_serializer @@ -26,18 +26,20 @@ class SnippetResult(BaseModel): SnippetResult """ - oneof_schema_1_validator: Optional[SnippetResultOption] = None - oneof_schema_2_validator: Optional[Dict[str, SnippetResult]] = Field( - default=None, - description="Snippets that show the context around a matching search query.", - ) - oneof_schema_3_validator: Optional[List[SnippetResult]] = Field( - default=None, - description="Snippets that show the context around a matching search query.", - ) + oneof_schema_1_validator: Optional[SnippetResultOption] = Field(default=None) + + oneof_schema_2_validator: Optional[Dict[str, SnippetResult]] = Field(default=None) + """ Snippets that show the context around a matching search query. """ + oneof_schema_3_validator: Optional[List[SnippetResult]] = Field(default=None) + """ Snippets that show the context around a matching search query. """ actual_instance: Optional[ Union[Dict[str, SnippetResult], List[SnippetResult], SnippetResultOption] ] = None + one_of_schemas: Set[str] = { + "Dict[str, SnippetResult]", + "List[SnippetResult]", + "SnippetResultOption", + } def __init__(self, *args, **kwargs) -> None: if args: @@ -65,7 +67,8 @@ def unwrap_actual_instance( return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of SnippetResult from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -105,17 +108,30 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict( + self, + ) -> Optional[ + Union[ + Dict[str, Any], + Dict[str, SnippetResult], + List[SnippetResult], + SnippetResultOption, + ] + ]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/snippet_result_option.py b/algoliasearch/search/models/snippet_result_option.py index 580984d30..2e35f7f79 100644 --- a/algoliasearch/search/models/snippet_result_option.py +++ b/algoliasearch/search/models/snippet_result_option.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,43 +26,35 @@ class SnippetResultOption(BaseModel): Snippets that show the context around a matching search query. """ - value: StrictStr = Field( - description="Highlighted attribute value, including HTML tags." - ) + value: str = Field(alias="value") + """ Highlighted attribute value, including HTML tags. """ match_level: MatchLevel = Field(alias="matchLevel") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SnippetResultOption from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SnippetResultOption from a dict""" if obj is None: return None @@ -70,7 +62,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"value": obj.get("value"), "matchLevel": obj.get("matchLevel")} - ) - return _obj + obj["matchLevel"] = obj.get("matchLevel") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/sort_remaining_by.py b/algoliasearch/search/models/sort_remaining_by.py index c156c883e..57cab8ebd 100644 --- a/algoliasearch/search/models/sort_remaining_by.py +++ b/algoliasearch/search/models/sort_remaining_by.py @@ -25,7 +25,9 @@ class SortRemainingBy(str, Enum): allowed enum values """ COUNT = "count" + ALPHA = "alpha" + HIDDEN = "hidden" @classmethod diff --git a/algoliasearch/search/models/source.py b/algoliasearch/search/models/source.py index ddf446d11..1389545a9 100644 --- a/algoliasearch/search/models/source.py +++ b/algoliasearch/search/models/source.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,43 +23,36 @@ class Source(BaseModel): Source. """ - source: StrictStr = Field(description="IP address range of the source.") - description: Optional[StrictStr] = Field( - default=None, description="Source description." - ) + source: str = Field(alias="source") + """ IP address range of the source. """ + description: Optional[str] = Field(default=None, alias="description") + """ Source description. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Source from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Source from a dict""" if obj is None: return None @@ -67,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"source": obj.get("source"), "description": obj.get("description")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/standard_entries.py b/algoliasearch/search/models/standard_entries.py index 5e25c5944..88327d8bc 100644 --- a/algoliasearch/search/models/standard_entries.py +++ b/algoliasearch/search/models/standard_entries.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictBool +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,51 +23,38 @@ class StandardEntries(BaseModel): Key-value pairs of [supported language ISO codes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/) and boolean values. """ - plurals: Optional[Dict[str, StrictBool]] = Field( - default=None, - description="Key-value pair of a language ISO code and a boolean value.", - ) - stopwords: Optional[Dict[str, StrictBool]] = Field( - default=None, - description="Key-value pair of a language ISO code and a boolean value.", - ) - compounds: Optional[Dict[str, StrictBool]] = Field( - default=None, - description="Key-value pair of a language ISO code and a boolean value.", - ) + plurals: Optional[Dict[str, bool]] = Field(default=None, alias="plurals") + """ Key-value pair of a language ISO code and a boolean value. """ + stopwords: Optional[Dict[str, bool]] = Field(default=None, alias="stopwords") + """ Key-value pair of a language ISO code and a boolean value. """ + compounds: Optional[Dict[str, bool]] = Field(default=None, alias="compounds") + """ Key-value pair of a language ISO code and a boolean value. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of StandardEntries from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of StandardEntries from a dict""" if obj is None: return None @@ -75,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "plurals": obj.get("plurals"), - "stopwords": obj.get("stopwords"), - "compounds": obj.get("compounds"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/supported_language.py b/algoliasearch/search/models/supported_language.py index 1c82c4faa..bbac80c88 100644 --- a/algoliasearch/search/models/supported_language.py +++ b/algoliasearch/search/models/supported_language.py @@ -25,72 +25,139 @@ class SupportedLanguage(str, Enum): allowed enum values """ AF = "af" + AR = "ar" + AZ = "az" + BG = "bg" + BN = "bn" + CA = "ca" + CS = "cs" + CY = "cy" + DA = "da" + DE = "de" + EL = "el" + EN = "en" + EO = "eo" + ES = "es" + ET = "et" + EU = "eu" + FA = "fa" + FI = "fi" + FO = "fo" + FR = "fr" + GA = "ga" + GL = "gl" + HE = "he" + HI = "hi" + HU = "hu" + HY = "hy" + ID = "id" + IS = "is" + IT = "it" + JA = "ja" + KA = "ka" + KK = "kk" + KO = "ko" + KU = "ku" + KY = "ky" + LT = "lt" + LV = "lv" + MI = "mi" + MN = "mn" + MR = "mr" + MS = "ms" + MT = "mt" + NB = "nb" + NL = "nl" + NO = "no" + NS = "ns" + PL = "pl" + PS = "ps" + PT = "pt" + PT_MINUS_BR = "pt-br" + QU = "qu" + RO = "ro" + RU = "ru" + SK = "sk" + SQ = "sq" + SV = "sv" + SW = "sw" + TA = "ta" + TE = "te" + TH = "th" + TL = "tl" + TN = "tn" + TR = "tr" + TT = "tt" + UK = "uk" + UR = "ur" + UZ = "uz" + ZH = "zh" @classmethod diff --git a/algoliasearch/search/models/synonym_hit.py b/algoliasearch/search/models/synonym_hit.py index b7d253592..a53896094 100644 --- a/algoliasearch/search/models/synonym_hit.py +++ b/algoliasearch/search/models/synonym_hit.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,65 +26,47 @@ class SynonymHit(BaseModel): Synonym object. """ - object_id: StrictStr = Field( - description="Unique identifier of a synonym object.", alias="objectID" - ) - type: SynonymType - synonyms: Optional[List[StrictStr]] = Field( - default=None, description="Words or phrases considered equivalent." - ) - input: Optional[StrictStr] = Field( - default=None, - description="Word or phrase to appear in query strings (for [`onewaysynonym`s](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/in-depth/one-way-synonyms/)).", - ) - word: Optional[StrictStr] = Field( - default=None, - description="Word or phrase to appear in query strings (for [`altcorrection1` and `altcorrection2`](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/in-depth/synonyms-alternative-corrections/)).", - ) - corrections: Optional[List[StrictStr]] = Field( - default=None, description="Words to be matched in records." - ) - placeholder: Optional[StrictStr] = Field( - default=None, - description="[Placeholder token](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/in-depth/synonyms-placeholders/) to be put inside records. ", - ) - replacements: Optional[List[StrictStr]] = Field( - default=None, - description="Query words that will match the [placeholder token](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/in-depth/synonyms-placeholders/).", - ) + object_id: str = Field(alias="objectID") + """ Unique identifier of a synonym object. """ + type: SynonymType = Field(alias="type") + synonyms: Optional[List[str]] = Field(default=None, alias="synonyms") + """ Words or phrases considered equivalent. """ + input: Optional[str] = Field(default=None, alias="input") + """ Word or phrase to appear in query strings (for [`onewaysynonym`s](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/in-depth/one-way-synonyms/)). """ + word: Optional[str] = Field(default=None, alias="word") + """ Word or phrase to appear in query strings (for [`altcorrection1` and `altcorrection2`](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/in-depth/synonyms-alternative-corrections/)). """ + corrections: Optional[List[str]] = Field(default=None, alias="corrections") + """ Words to be matched in records. """ + placeholder: Optional[str] = Field(default=None, alias="placeholder") + """ [Placeholder token](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/in-depth/synonyms-placeholders/) to be put inside records. """ + replacements: Optional[List[str]] = Field(default=None, alias="replacements") + """ Query words that will match the [placeholder token](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/in-depth/synonyms-placeholders/). """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of SynonymHit from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of SynonymHit from a dict""" if obj is None: return None @@ -92,16 +74,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "objectID": obj.get("objectID"), - "type": obj.get("type"), - "synonyms": obj.get("synonyms"), - "input": obj.get("input"), - "word": obj.get("word"), - "corrections": obj.get("corrections"), - "placeholder": obj.get("placeholder"), - "replacements": obj.get("replacements"), - } - ) - return _obj + obj["type"] = obj.get("type") + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/synonym_type.py b/algoliasearch/search/models/synonym_type.py index 12580cc90..babd3e069 100644 --- a/algoliasearch/search/models/synonym_type.py +++ b/algoliasearch/search/models/synonym_type.py @@ -25,9 +25,13 @@ class SynonymType(str, Enum): allowed enum values """ SYNONYM = "synonym" + ONEWAYSYNONYM = "onewaysynonym" + ALTCORRECTION1 = "altcorrection1" + ALTCORRECTION2 = "altcorrection2" + PLACEHOLDER = "placeholder" @classmethod diff --git a/algoliasearch/search/models/tag_filters.py b/algoliasearch/search/models/tag_filters.py index 415d360e9..eb88ff91e 100644 --- a/algoliasearch/search/models/tag_filters.py +++ b/algoliasearch/search/models/tag_filters.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union -from pydantic import BaseModel, StrictStr, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -23,9 +23,12 @@ class TagFilters(BaseModel): Filter the search by values of the special `_tags` attribute. **Prefer using the `filters` parameter, which supports all filter types and combinations with boolean operators.** Different from regular facets, `_tags` can only be used for filtering (including or excluding records). You won't get a facet count. The same combination and escaping rules apply as for `facetFilters`. """ - oneof_schema_1_validator: Optional[List[TagFilters]] = None - oneof_schema_2_validator: Optional[StrictStr] = None + oneof_schema_1_validator: Optional[List[TagFilters]] = Field(default=None) + + oneof_schema_2_validator: Optional[str] = Field(default=None) + actual_instance: Optional[Union[List[TagFilters], str]] = None + one_of_schemas: Set[str] = {"List[TagFilters]", "str"} def __init__(self, *args, **kwargs) -> None: if args: @@ -49,7 +52,8 @@ def unwrap_actual_instance(self) -> Optional[Union[List[TagFilters], str]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of TagFilters from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -83,17 +87,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], List[TagFilters], str]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/task_status.py b/algoliasearch/search/models/task_status.py index d8b6799fb..4ee4bdde7 100644 --- a/algoliasearch/search/models/task_status.py +++ b/algoliasearch/search/models/task_status.py @@ -25,6 +25,7 @@ class TaskStatus(str, Enum): allowed enum values """ PUBLISHED = "published" + NOTPUBLISHED = "notPublished" @classmethod diff --git a/algoliasearch/search/models/time_range.py b/algoliasearch/search/models/time_range.py index f6c5643cb..d0bfe155b 100644 --- a/algoliasearch/search/models/time_range.py +++ b/algoliasearch/search/models/time_range.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,46 +23,36 @@ class TimeRange(BaseModel): TimeRange """ - var_from: StrictInt = Field( - description="When the rule should start to be active, in Unix epoch time.", - alias="from", - ) - until: StrictInt = Field( - description="When the rule should stop to be active, in Unix epoch time." - ) + var_from: int = Field(alias="from") + """ When the rule should start to be active, in Unix epoch time. """ + until: int = Field(alias="until") + """ When the rule should stop to be active, in Unix epoch time. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TimeRange from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TimeRange from a dict""" if obj is None: return None @@ -70,5 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"from": obj.get("from"), "until": obj.get("until")}) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/typo_tolerance.py b/algoliasearch/search/models/typo_tolerance.py index addb70fbb..7de8f11bd 100644 --- a/algoliasearch/search/models/typo_tolerance.py +++ b/algoliasearch/search/models/typo_tolerance.py @@ -8,9 +8,9 @@ from json import dumps, loads from sys import version_info -from typing import Dict, Optional, Union +from typing import Any, Dict, Optional, Set, Union -from pydantic import BaseModel, Field, StrictBool, ValidationError, model_serializer +from pydantic import BaseModel, Field, ValidationError, model_serializer if version_info >= (3, 11): from typing import Self @@ -26,12 +26,12 @@ class TypoTolerance(BaseModel): Whether [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/) is enabled and how it is applied. If typo tolerance is true, `min`, or `strict`, [word splitting and concetenation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/splitting-and-concatenation/) is also active. """ - oneof_schema_1_validator: Optional[StrictBool] = Field( - default=True, - description="Whether typo tolerance is active. If true, matches with typos are included in the search results and rank after exact matches.", - ) - oneof_schema_2_validator: Optional[TypoToleranceEnum] = None + oneof_schema_1_validator: Optional[bool] = Field(default=None) + """ Whether typo tolerance is active. If true, matches with typos are included in the search results and rank after exact matches. """ + oneof_schema_2_validator: Optional[TypoToleranceEnum] = Field(default=None) + actual_instance: Optional[Union[TypoToleranceEnum, bool]] = None + one_of_schemas: Set[str] = {"TypoToleranceEnum", "bool"} def __init__(self, *args, **kwargs) -> None: if args: @@ -55,7 +55,8 @@ def unwrap_actual_instance(self) -> Optional[Union[TypoToleranceEnum, bool]]: return self.actual_instance if hasattr(self, "actual_instance") else self @classmethod - def from_dict(cls, obj: dict) -> Self: + def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self: + """Create an instance of TypoTolerance from a JSON string""" return cls.from_json(dumps(obj)) @classmethod @@ -88,17 +89,21 @@ def to_json(self) -> str: if self.actual_instance is None: return "null" - if hasattr(self.actual_instance, "to_json"): + if hasattr(self.actual_instance, "to_json") and callable( + self.actual_instance.to_json + ): return self.actual_instance.to_json() else: return dumps(self.actual_instance) - def to_dict(self) -> Dict: + def to_dict(self) -> Optional[Union[Dict[str, Any], TypoToleranceEnum, bool]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, "to_dict"): + if hasattr(self.actual_instance, "to_dict") and callable( + self.actual_instance.to_dict + ): return self.actual_instance.to_dict() else: return self.actual_instance diff --git a/algoliasearch/search/models/typo_tolerance_enum.py b/algoliasearch/search/models/typo_tolerance_enum.py index 932d1aabd..89fb2234b 100644 --- a/algoliasearch/search/models/typo_tolerance_enum.py +++ b/algoliasearch/search/models/typo_tolerance_enum.py @@ -25,6 +25,7 @@ class TypoToleranceEnum(str, Enum): allowed enum values """ MIN = "min" + STRICT = "strict" @classmethod diff --git a/algoliasearch/search/models/update_api_key_response.py b/algoliasearch/search/models/update_api_key_response.py index fc0f05f51..14a3ade0f 100644 --- a/algoliasearch/search/models/update_api_key_response.py +++ b/algoliasearch/search/models/update_api_key_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,44 +23,36 @@ class UpdateApiKeyResponse(BaseModel): UpdateApiKeyResponse """ - key: StrictStr = Field(description="API key.") - updated_at: StrictStr = Field( - description="Date and time when the object was updated, in RFC 3339 format.", - alias="updatedAt", - ) + key: str = Field(alias="key") + """ API key. """ + updated_at: str = Field(alias="updatedAt") + """ Date and time when the object was updated, in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of UpdateApiKeyResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of UpdateApiKeyResponse from a dict""" if obj is None: return None @@ -68,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"key": obj.get("key"), "updatedAt": obj.get("updatedAt")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/updated_at_response.py b/algoliasearch/search/models/updated_at_response.py index eb53f329c..a9a66cb96 100644 --- a/algoliasearch/search/models/updated_at_response.py +++ b/algoliasearch/search/models/updated_at_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,47 +23,36 @@ class UpdatedAtResponse(BaseModel): Response, taskID, and update timestamp. """ - task_id: StrictInt = Field( - description="Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. ", - alias="taskID", - ) - updated_at: StrictStr = Field( - description="Date and time when the object was updated, in RFC 3339 format.", - alias="updatedAt", - ) + task_id: int = Field(alias="taskID") + """ Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. """ + updated_at: str = Field(alias="updatedAt") + """ Date and time when the object was updated, in RFC 3339 format. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of UpdatedAtResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of UpdatedAtResponse from a dict""" if obj is None: return None @@ -71,7 +60,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {"taskID": obj.get("taskID"), "updatedAt": obj.get("updatedAt")} - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/updated_at_with_object_id_response.py b/algoliasearch/search/models/updated_at_with_object_id_response.py index 51ffde629..e376610e8 100644 --- a/algoliasearch/search/models/updated_at_with_object_id_response.py +++ b/algoliasearch/search/models/updated_at_with_object_id_response.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,52 +23,38 @@ class UpdatedAtWithObjectIdResponse(BaseModel): Response, taskID, unique object identifier, and an update timestamp. """ - task_id: Optional[StrictInt] = Field( - default=None, - description="Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. ", - alias="taskID", - ) - updated_at: Optional[StrictStr] = Field( - default=None, - description="Date and time when the object was updated, in RFC 3339 format.", - alias="updatedAt", - ) - object_id: Optional[StrictStr] = Field( - default=None, description="Unique record identifier.", alias="objectID" - ) + task_id: Optional[int] = Field(default=None, alias="taskID") + """ Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. """ + updated_at: Optional[str] = Field(default=None, alias="updatedAt") + """ Date and time when the object was updated, in RFC 3339 format. """ + object_id: Optional[str] = Field(default=None, alias="objectID") + """ Unique record identifier. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of UpdatedAtWithObjectIdResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of UpdatedAtWithObjectIdResponse from a dict""" if obj is None: return None @@ -76,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "taskID": obj.get("taskID"), - "updatedAt": obj.get("updatedAt"), - "objectID": obj.get("objectID"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/updated_rule_response.py b/algoliasearch/search/models/updated_rule_response.py index afc339110..fa0a245c1 100644 --- a/algoliasearch/search/models/updated_rule_response.py +++ b/algoliasearch/search/models/updated_rule_response.py @@ -8,9 +8,9 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -23,50 +23,38 @@ class UpdatedRuleResponse(BaseModel): UpdatedRuleResponse """ - object_id: StrictStr = Field( - description="Unique identifier of a rule object.", alias="objectID" - ) - updated_at: StrictStr = Field( - description="Date and time when the object was updated, in RFC 3339 format.", - alias="updatedAt", - ) - task_id: StrictInt = Field( - description="Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. ", - alias="taskID", - ) + object_id: str = Field(alias="objectID") + """ Unique identifier of a rule object. """ + updated_at: str = Field(alias="updatedAt") + """ Date and time when the object was updated, in RFC 3339 format. """ + task_id: int = Field(alias="taskID") + """ Unique identifier of a task. A successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of UpdatedRuleResponse from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of UpdatedRuleResponse from a dict""" if obj is None: return None @@ -74,11 +62,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "objectID": obj.get("objectID"), - "updatedAt": obj.get("updatedAt"), - "taskID": obj.get("taskID"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/user_highlight_result.py b/algoliasearch/search/models/user_highlight_result.py index a699d4373..531f9b87f 100644 --- a/algoliasearch/search/models/user_highlight_result.py +++ b/algoliasearch/search/models/user_highlight_result.py @@ -8,7 +8,7 @@ from json import loads from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional from pydantic import BaseModel, ConfigDict, Field @@ -30,41 +30,30 @@ class UserHighlightResult(BaseModel): cluster_name: HighlightResult = Field(alias="clusterName") model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of UserHighlightResult from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.user_id: - _dict["userID"] = self.user_id.to_dict() - if self.cluster_name: - _dict["clusterName"] = self.cluster_name.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of UserHighlightResult from a dict""" if obj is None: return None @@ -72,18 +61,15 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "userID": ( - HighlightResult.from_dict(obj.get("userID")) - if obj.get("userID") is not None - else None - ), - "clusterName": ( - HighlightResult.from_dict(obj.get("clusterName")) - if obj.get("clusterName") is not None - else None - ), - } + obj["userID"] = ( + HighlightResult.from_dict(obj["userID"]) + if obj.get("userID") is not None + else None ) - return _obj + obj["clusterName"] = ( + HighlightResult.from_dict(obj["clusterName"]) + if obj.get("clusterName") is not None + else None + ) + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/user_hit.py b/algoliasearch/search/models/user_hit.py index d612e223b..4bd3a3f34 100644 --- a/algoliasearch/search/models/user_hit.py +++ b/algoliasearch/search/models/user_hit.py @@ -9,14 +9,14 @@ from json import loads from re import match from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self from algoliasearch.search.models.user_highlight_result import UserHighlightResult @@ -27,21 +27,16 @@ class UserHit(BaseModel): UserHit """ - user_id: Annotated[str, Field(strict=True)] = Field( - description="Unique identifier of the user who makes the search request.", - alias="userID", - ) - cluster_name: StrictStr = Field(description="Cluster name.", alias="clusterName") - nb_records: StrictInt = Field( - description="Number of records in the cluster.", alias="nbRecords" - ) - data_size: StrictInt = Field( - description="Data size taken by all the users assigned to the cluster.", - alias="dataSize", - ) - object_id: StrictStr = Field( - description="userID of the requested user. Same as userID.", alias="objectID" - ) + user_id: str = Field(alias="userID") + """ Unique identifier of the user who makes the search request. """ + cluster_name: str = Field(alias="clusterName") + """ Cluster name. """ + nb_records: int = Field(alias="nbRecords") + """ Number of records in the cluster. """ + data_size: int = Field(alias="dataSize") + """ Data size taken by all the users assigned to the cluster. """ + object_id: str = Field(alias="objectID") + """ userID of the requested user. Same as userID. """ highlight_result: UserHighlightResult = Field(alias="_highlightResult") @field_validator("user_id") @@ -54,39 +49,30 @@ def user_id_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of UserHit from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - if self.highlight_result: - _dict["_highlightResult"] = self.highlight_result.to_dict() - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of UserHit from a dict""" if obj is None: return None @@ -94,18 +80,10 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "userID": obj.get("userID"), - "clusterName": obj.get("clusterName"), - "nbRecords": obj.get("nbRecords"), - "dataSize": obj.get("dataSize"), - "objectID": obj.get("objectID"), - "_highlightResult": ( - UserHighlightResult.from_dict(obj.get("_highlightResult")) - if obj.get("_highlightResult") is not None - else None - ), - } + obj["_highlightResult"] = ( + UserHighlightResult.from_dict(obj["_highlightResult"]) + if obj.get("_highlightResult") is not None + else None ) - return _obj + + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/user_id.py b/algoliasearch/search/models/user_id.py index 5631d8a57..a72df793e 100644 --- a/algoliasearch/search/models/user_id.py +++ b/algoliasearch/search/models/user_id.py @@ -9,14 +9,14 @@ from json import loads from re import match from sys import version_info -from typing import Any, Dict +from typing import Any, Dict, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator if version_info >= (3, 11): - from typing import Annotated, Self + from typing import Self else: - from typing_extensions import Annotated, Self + from typing_extensions import Self class UserId(BaseModel): @@ -24,19 +24,14 @@ class UserId(BaseModel): Unique user ID. """ - user_id: Annotated[str, Field(strict=True)] = Field( - description="Unique identifier of the user who makes the search request.", - alias="userID", - ) - cluster_name: StrictStr = Field( - description="Cluster to which the user is assigned.", alias="clusterName" - ) - nb_records: StrictInt = Field( - description="Number of records belonging to the user.", alias="nbRecords" - ) - data_size: StrictInt = Field( - description="Data size used by the user.", alias="dataSize" - ) + user_id: str = Field(alias="userID") + """ Unique identifier of the user who makes the search request. """ + cluster_name: str = Field(alias="clusterName") + """ Cluster to which the user is assigned. """ + nb_records: int = Field(alias="nbRecords") + """ Number of records belonging to the user. """ + data_size: int = Field(alias="dataSize") + """ Data size used by the user. """ @field_validator("user_id") def user_id_validate_regular_expression(cls, value): @@ -48,37 +43,30 @@ def user_id_validate_regular_expression(cls, value): return value model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of UserId from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of UserId from a dict""" if obj is None: return None @@ -86,12 +74,4 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "userID": obj.get("userID"), - "clusterName": obj.get("clusterName"), - "nbRecords": obj.get("nbRecords"), - "dataSize": obj.get("dataSize"), - } - ) - return _obj + return cls.model_validate(obj) diff --git a/algoliasearch/search/models/value.py b/algoliasearch/search/models/value.py index 0c214a8fb..b20208d21 100644 --- a/algoliasearch/search/models/value.py +++ b/algoliasearch/search/models/value.py @@ -10,7 +10,7 @@ from sys import version_info from typing import Any, Dict, List, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field if version_info >= (3, 11): from typing import Self @@ -26,49 +26,39 @@ class Value(BaseModel): Value """ - order: Optional[List[StrictStr]] = Field( - default=None, - description="Explicit order of facets or facet values. This setting lets you always show specific facets or facet values at the top of the list. ", - ) + order: Optional[List[str]] = Field(default=None, alias="order") + """ Explicit order of facets or facet values. This setting lets you always show specific facets or facet values at the top of the list. """ sort_remaining_by: Optional[SortRemainingBy] = Field( default=None, alias="sortRemainingBy" ) - hide: Optional[List[StrictStr]] = Field( - default=None, description="Hide facet values." - ) + hide: Optional[List[str]] = Field(default=None, alias="hide") + """ Hide facet values. """ model_config = ConfigDict( - use_enum_values=True, populate_by_name=True, validate_assignment=True + use_enum_values=True, + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), ) def to_json(self) -> str: return self.model_dump_json(by_alias=True, exclude_unset=True) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of Value from a JSON string""" return cls.from_dict(loads(json_str)) def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - _dict = self.model_dump( + """Return the dictionary representation of the model using alias.""" + return self.model_dump( by_alias=True, - exclude={}, exclude_none=True, exclude_unset=True, ) - return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of Value from a dict""" if obj is None: return None @@ -76,11 +66,6 @@ def from_dict(cls, obj: Dict) -> Self: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "order": obj.get("order"), - "sortRemainingBy": obj.get("sortRemainingBy"), - "hide": obj.get("hide"), - } - ) - return _obj + obj["sortRemainingBy"] = obj.get("sortRemainingBy") + + return cls.model_validate(obj)