# coding: utf-8

"""
Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
"""
from __future__ import annotations

from json import dumps
from typing import Annotated, Any, Callable, Dict, List, Optional, Self, Tuple, Union
from urllib.parse import quote

from pydantic import Field, StrictBool, StrictInt, StrictStr

from algoliasearch.http.api_response import ApiResponse
from algoliasearch.http.exceptions import RequestException
from algoliasearch.http.helpers import RetryTimeout, create_iterable
from algoliasearch.http.request_options import RequestOptions
from algoliasearch.http.serializer import bodySerializer
from algoliasearch.http.transporter import Transporter
from algoliasearch.http.verb import Verb
from algoliasearch.search.config import SearchConfig
from algoliasearch.search.models.add_api_key_response import AddApiKeyResponse
from algoliasearch.search.models.api_key import ApiKey
from algoliasearch.search.models.assign_user_id_params import AssignUserIdParams
from algoliasearch.search.models.attribute_to_update import AttributeToUpdate
from algoliasearch.search.models.batch_assign_user_ids_params import (
    BatchAssignUserIdsParams,
)
from algoliasearch.search.models.batch_dictionary_entries_params import (
    BatchDictionaryEntriesParams,
)
from algoliasearch.search.models.batch_params import BatchParams
from algoliasearch.search.models.batch_response import BatchResponse
from algoliasearch.search.models.batch_write_params import BatchWriteParams
from algoliasearch.search.models.browse_params import BrowseParams
from algoliasearch.search.models.browse_response import BrowseResponse
from algoliasearch.search.models.created_at_response import CreatedAtResponse
from algoliasearch.search.models.delete_api_key_response import DeleteApiKeyResponse
from algoliasearch.search.models.delete_by_params import DeleteByParams
from algoliasearch.search.models.delete_source_response import DeleteSourceResponse
from algoliasearch.search.models.deleted_at_response import DeletedAtResponse
from algoliasearch.search.models.dictionary_settings_params import (
    DictionarySettingsParams,
)
from algoliasearch.search.models.dictionary_type import DictionaryType
from algoliasearch.search.models.get_api_key_response import GetApiKeyResponse
from algoliasearch.search.models.get_dictionary_settings_response import (
    GetDictionarySettingsResponse,
)
from algoliasearch.search.models.get_logs_response import GetLogsResponse
from algoliasearch.search.models.get_objects_params import GetObjectsParams
from algoliasearch.search.models.get_objects_response import GetObjectsResponse
from algoliasearch.search.models.get_task_response import GetTaskResponse
from algoliasearch.search.models.get_top_user_ids_response import GetTopUserIdsResponse
from algoliasearch.search.models.has_pending_mappings_response import (
    HasPendingMappingsResponse,
)
from algoliasearch.search.models.index_settings import IndexSettings
from algoliasearch.search.models.languages import Languages
from algoliasearch.search.models.list_api_keys_response import ListApiKeysResponse
from algoliasearch.search.models.list_clusters_response import ListClustersResponse
from algoliasearch.search.models.list_indices_response import ListIndicesResponse
from algoliasearch.search.models.list_user_ids_response import ListUserIdsResponse
from algoliasearch.search.models.log_type import LogType
from algoliasearch.search.models.multiple_batch_response import MultipleBatchResponse
from algoliasearch.search.models.operation_index_params import OperationIndexParams
from algoliasearch.search.models.remove_user_id_response import RemoveUserIdResponse
from algoliasearch.search.models.replace_source_response import ReplaceSourceResponse
from algoliasearch.search.models.rule import Rule
from algoliasearch.search.models.save_object_response import SaveObjectResponse
from algoliasearch.search.models.save_synonym_response import SaveSynonymResponse
from algoliasearch.search.models.search_dictionary_entries_params import (
    SearchDictionaryEntriesParams,
)
from algoliasearch.search.models.search_for_facet_values_request import (
    SearchForFacetValuesRequest,
)
from algoliasearch.search.models.search_for_facet_values_response import (
    SearchForFacetValuesResponse,
)
from algoliasearch.search.models.search_method_params import SearchMethodParams
from algoliasearch.search.models.search_params import SearchParams
from algoliasearch.search.models.search_response import SearchResponse
from algoliasearch.search.models.search_responses import SearchResponses
from algoliasearch.search.models.search_rules_params import SearchRulesParams
from algoliasearch.search.models.search_rules_response import SearchRulesResponse
from algoliasearch.search.models.search_synonyms_params import SearchSynonymsParams
from algoliasearch.search.models.search_synonyms_response import SearchSynonymsResponse
from algoliasearch.search.models.search_user_ids_params import SearchUserIdsParams
from algoliasearch.search.models.search_user_ids_response import SearchUserIdsResponse
from algoliasearch.search.models.source import Source
from algoliasearch.search.models.synonym_hit import SynonymHit
from algoliasearch.search.models.synonym_type import SynonymType
from algoliasearch.search.models.update_api_key_response import UpdateApiKeyResponse
from algoliasearch.search.models.updated_at_response import UpdatedAtResponse
from algoliasearch.search.models.updated_at_with_object_id_response import (
    UpdatedAtWithObjectIdResponse,
)
from algoliasearch.search.models.updated_rule_response import UpdatedRuleResponse
from algoliasearch.search.models.user_id import UserId


class SearchClient:
    """The Algolia 'SearchClient' class.

    Args:
    app_id (str): The Algolia application ID to retrieve information from.
    api_key (str): The Algolia api key bound to the given `app_id`.


    Returns:
    The initialized API client.

    Example:
    _client = SearchClient("YOUR_ALGOLIA_APP_ID", "YOUR_ALGOLIA_API_KEY")
    _client_with_named_args = SearchClient(app_id="YOUR_ALGOLIA_APP_ID", api_key="YOUR_ALGOLIA_API_KEY")

    See `SearchClient.create_with_config` for advanced configuration.
    """

    _transporter: Transporter
    _config: SearchConfig
    _request_options: RequestOptions

    def __init__(
        self,
        app_id: Optional[str] = None,
        api_key: Optional[str] = None,
        transporter: Optional[Transporter] = None,
        config: Optional[SearchConfig] = None,
    ) -> None:
        if transporter is not None and config is None:
            config = transporter._config

        if config is None:
            config = SearchConfig(app_id, api_key)
        self._config = config
        self._request_options = RequestOptions(config)

        if transporter is None:
            transporter = Transporter(config)
        self._transporter = transporter

    def create_with_config(
        config: SearchConfig, transporter: Optional[Transporter] = None
    ) -> Self:
        """Allows creating a client with a customized `SearchConfig` and `Transporter`. If `transporter` is not provided, the default one will be initialized from the given `config`.

        Args:
        config (SearchConfig): The config of the API client.
        transporter (Transporter): The HTTP transporter, see `http/transporter.py` for implementation details.

        Returns:
        The initialized API client.

        Example:
        _client_with_custom_config = SearchClient.create_with_config(config=SearchConfig(...))
        _client_with_custom_config_and_transporter = SearchClient.create_with_config(config=SearchConfig(...), transporter=Transporter(...))
        """
        if transporter is None:
            transporter = Transporter(config)

        return SearchClient(
            app_id=config.app_id,
            api_key=config.api_key,
            transporter=transporter,
            config=config,
        )

    async def __aenter__(self) -> None:
        return self

    async def __aexit__(self, exc_type, exc_value, traceback) -> None:
        """Closes the underlying `transporter` of the API client."""
        await self.close()

    async def close(self) -> None:
        """Closes the underlying `transporter` of the API client."""
        return await self._transporter.close()

    async def wait_for_task(
        self,
        index_name: str,
        task_id: str,
        timeout: RetryTimeout = RetryTimeout(),
        max_retries: int = 50,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> GetTaskResponse:
        """
        Helper: Wait for a task to be published (completed) for a given `indexName` and `taskID`.
        """
        self._retry_count = 0

        async def _func(_: GetTaskResponse) -> GetTaskResponse:
            return await self.get_task(index_name, task_id, request_options)

        def _aggregator(_: GetTaskResponse) -> None:
            self._retry_count += 1

        return await create_iterable(
            func=_func,
            aggregator=_aggregator,
            validate=lambda _resp: _resp.status == "published",
            timeout=lambda: timeout(self._retry_count),
            error_validate=lambda: self._retry_count >= max_retries,
            error_message=lambda: f"The maximum number of retries exceeded. (${self._retry_count}/${max_retries})",
        )

    async def wait_for_api_key(
        self,
        operation: str,
        key: str,
        api_key: Optional[ApiKey] = None,
        max_retries: int = 50,
        timeout: RetryTimeout = RetryTimeout(),
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> GetApiKeyResponse:
        """
        Helper: Wait for an API key to be added, updated or deleted based on a given `operation`.
        """
        self._retry_count = 0

        if operation == "update" and api_key is None:
            raise ValueError(
                "`apiKey` is required when waiting for an `update` operation."
            )

        async def _func(_prev: GetApiKeyResponse) -> GetApiKeyResponse:
            try:
                return await self.get_api_key(key=key, request_options=request_options)
            except RequestException as e:
                if e.status_code == 404 and (
                    operation == "delete" or operation == "add"
                ):
                    return None
                raise e

        def _aggregator(_: GetApiKeyResponse) -> None:
            self._retry_count += 1

        def _validate(_resp: GetApiKeyResponse) -> bool:
            if operation == "update":
                for field in api_key:
                    if isinstance(api_key[field], list) and isinstance(
                        _resp[field], list
                    ):
                        if len(api_key[field]) != len(_resp[field]) or any(
                            v != _resp[field][i] for i, v in enumerate(api_key[field])
                        ):
                            return False
                    elif api_key[field] != _resp[field]:
                        return False
                return True
            elif operation == "add":
                return _resp is not None
            return _resp is None

        return await create_iterable(
            func=_func,
            validate=_validate,
            aggregator=_aggregator,
            timeout=lambda: timeout(self._retry_count),
            error_validate=lambda _: self._retry_count >= max_retries,
            error_message=lambda _: f"The maximum number of retries exceeded. (${self._retry_count}/${max_retries})",
        )

    async def browse_objects(
        self,
        index_name: str,
        aggregator: Optional[Callable[[BrowseResponse], None]],
        browse_params: Optional[BrowseParams] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> BrowseResponse:
        """
        Helper: Iterate on the `browse` method of the client to allow aggregating objects of an index.
        """

        async def _func(_prev: BrowseResponse) -> BrowseResponse:
            if _prev is not None and _prev.cursor is not None:
                browse_params.cursor = _prev.cursor
            return await self.browse(
                index_name=index_name,
                browse_params=browse_params,
                request_options=request_options,
            )

        return await create_iterable(
            func=_func,
            validate=lambda _resp: _resp.cursor is None,
            aggregator=aggregator,
        )

    async def browse_rules(
        self,
        index_name: str,
        aggregator: Optional[Callable[[SearchRulesResponse], None]],
        search_rules_params: Optional[SearchRulesParams] = SearchRulesParams(
            hits_per_page=1000
        ),
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> SearchRulesResponse:
        """
        Helper: Iterate on the `search_rules` method of the client to allow aggregating rules of an index.
        """
        if search_rules_params is not None:
            search_rules_params.hits_per_page = 1000

        async def _func(_prev: SearchRulesResponse) -> SearchRulesResponse:
            if _prev is not None:
                search_rules_params.page = _prev.page + 1
            return await self.search_rules(
                index_name=index_name,
                search_rules_params=search_rules_params,
                request_options=request_options,
            )

        return await create_iterable(
            func=_func,
            validate=lambda _resp: _resp.nb_hits < search_rules_params.hits_per_page,
            aggregator=aggregator,
        )

    async def browse_synonyms(
        self,
        index_name: str,
        aggregator: Optional[Callable[[SearchSynonymsResponse], None]],
        synonym_type: Optional[SynonymType] = None,
        page: Optional[int] = 0,
        hits_per_page: Optional[int] = 1000,
        search_synonyms_params: Optional[SearchSynonymsParams] = SearchSynonymsParams(),
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> SearchSynonymsResponse:
        """
        Helper: Iterate on the `search_synonyms` method of the client to allow aggregating synonyms of an index.
        """

        async def _func(_prev: SearchRulesResponse) -> SearchRulesResponse:
            if _prev is not None:
                search_synonyms_params.page = _prev.page + 1
            return await self.search_synonyms(
                index_name=index_name,
                type=synonym_type,
                page=page,
                hits_per_page=hits_per_page,
                search_synonyms_params=search_synonyms_params,
                request_options=request_options,
            )

        return await create_iterable(
            func=_func,
            validate=lambda _resp: _resp.nb_hits < hits_per_page,
            aggregator=aggregator,
        )

    async def add_api_key_with_http_info(
        self,
        api_key: ApiKey,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Add API key.

        Add a new API key with specific permissions and restrictions. The request must be authenticated with the admin API key. The response returns an API key string.

        :param api_key: (required)
        :type api_key: ApiKey
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if api_key is None:
            raise ValueError(
                "Parameter `api_key` is required when calling `add_api_key`."
            )

        _body = {}
        if api_key is not None:
            _body = api_key

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/keys",
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def add_api_key(
        self,
        api_key: ApiKey,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> AddApiKeyResponse:
        """
        Add API key.

        Add a new API key with specific permissions and restrictions. The request must be authenticated with the admin API key. The response returns an API key string.

        :param api_key: (required)
        :type api_key: ApiKey
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'AddApiKeyResponse' result object.
        """
        return (
            await self.add_api_key_with_http_info(api_key, request_options)
        ).deserialize(AddApiKeyResponse)

    async def add_or_update_object_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique record (object) identifier.")
        ],
        body: Annotated[Dict[str, Any], Field(description="Algolia record.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Add or update a record (using objectID).

        If you use an existing `objectID`, the existing record will be replaced with the new one.  To update only some attributes of an existing record, use the [`partial` operation](#tag/Records/operation/partialUpdateObject) instead.  To add multiple records to your index in a single API request, use the [`batch` operation](#tag/Records/operation/batch).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique record (object) identifier. (required)
        :type object_id: str
        :param body: Algolia record. (required)
        :type body: object
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `add_or_update_object`."
            )

        if object_id is None:
            raise ValueError(
                "Parameter `object_id` is required when calling `add_or_update_object`."
            )

        if body is None:
            raise ValueError(
                "Parameter `body` is required when calling `add_or_update_object`."
            )

        _body = {}
        if body is not None:
            _body = body

        return await self._transporter.request(
            verb=Verb.PUT,
            path="/1/indexes/{indexName}/{objectID}".replace(
                "{indexName}", quote(str(index_name), safe="")
            ).replace("{objectID}", quote(str(object_id), safe="")),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def add_or_update_object(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique record (object) identifier.")
        ],
        body: Annotated[Dict[str, Any], Field(description="Algolia record.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> UpdatedAtWithObjectIdResponse:
        """
        Add or update a record (using objectID).

        If you use an existing `objectID`, the existing record will be replaced with the new one.  To update only some attributes of an existing record, use the [`partial` operation](#tag/Records/operation/partialUpdateObject) instead.  To add multiple records to your index in a single API request, use the [`batch` operation](#tag/Records/operation/batch).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique record (object) identifier. (required)
        :type object_id: str
        :param body: Algolia record. (required)
        :type body: object
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'UpdatedAtWithObjectIdResponse' result object.
        """
        return (
            await self.add_or_update_object_with_http_info(
                index_name, object_id, body, request_options
            )
        ).deserialize(UpdatedAtWithObjectIdResponse)

    async def append_source_with_http_info(
        self,
        source: Annotated[Source, Field(description="Source to add.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Add a source.

        Add a source to the list of allowed sources.

        :param source: Source to add. (required)
        :type source: Source
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if source is None:
            raise ValueError(
                "Parameter `source` is required when calling `append_source`."
            )

        _body = {}
        if source is not None:
            _body = source

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/security/sources/append",
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def append_source(
        self,
        source: Annotated[Source, Field(description="Source to add.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> CreatedAtResponse:
        """
        Add a source.

        Add a source to the list of allowed sources.

        :param source: Source to add. (required)
        :type source: Source
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'CreatedAtResponse' result object.
        """
        return (
            await self.append_source_with_http_info(source, request_options)
        ).deserialize(CreatedAtResponse)

    async def assign_user_id_with_http_info(
        self,
        x_algolia_user_id: Annotated[
            str, Field(strict=True, description="userID to assign.")
        ],
        assign_user_id_params: AssignUserIdParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Assign or move a user ID.

        Assign or move a user ID to a cluster. The time it takes to move a user is proportional to the amount of data linked to the user ID.

        :param x_algolia_user_id: userID to assign. (required)
        :type x_algolia_user_id: str
        :param assign_user_id_params: (required)
        :type assign_user_id_params: AssignUserIdParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if x_algolia_user_id is None:
            raise ValueError(
                "Parameter `x_algolia_user_id` is required when calling `assign_user_id`."
            )

        if assign_user_id_params is None:
            raise ValueError(
                "Parameter `assign_user_id_params` is required when calling `assign_user_id`."
            )

        _headers: Dict[str, Optional[str]] = {}

        if x_algolia_user_id is not None:
            _headers["x-algolia-user-id"] = x_algolia_user_id

        _body = {}
        if assign_user_id_params is not None:
            _body = assign_user_id_params

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/clusters/mapping",
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                headers=_headers,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def assign_user_id(
        self,
        x_algolia_user_id: Annotated[
            str, Field(strict=True, description="userID to assign.")
        ],
        assign_user_id_params: AssignUserIdParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> CreatedAtResponse:
        """
        Assign or move a user ID.

        Assign or move a user ID to a cluster. The time it takes to move a user is proportional to the amount of data linked to the user ID.

        :param x_algolia_user_id: userID to assign. (required)
        :type x_algolia_user_id: str
        :param assign_user_id_params: (required)
        :type assign_user_id_params: AssignUserIdParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'CreatedAtResponse' result object.
        """
        return (
            await self.assign_user_id_with_http_info(
                x_algolia_user_id, assign_user_id_params, request_options
            )
        ).deserialize(CreatedAtResponse)

    async def batch_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        batch_write_params: BatchWriteParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Batch write operations on one index.

        To reduce the time spent on network round trips, you can perform several write actions in a single API call. Actions are applied in the order they are specified. The supported `action`s are equivalent to the individual operations of the same name.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param batch_write_params: (required)
        :type batch_write_params: BatchWriteParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError("Parameter `index_name` is required when calling `batch`.")

        if batch_write_params is None:
            raise ValueError(
                "Parameter `batch_write_params` is required when calling `batch`."
            )

        _body = {}
        if batch_write_params is not None:
            _body = batch_write_params

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/{indexName}/batch".replace(
                "{indexName}", quote(str(index_name), safe="")
            ),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def batch(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        batch_write_params: BatchWriteParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> BatchResponse:
        """
        Batch write operations on one index.

        To reduce the time spent on network round trips, you can perform several write actions in a single API call. Actions are applied in the order they are specified. The supported `action`s are equivalent to the individual operations of the same name.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param batch_write_params: (required)
        :type batch_write_params: BatchWriteParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'BatchResponse' result object.
        """
        return (
            await self.batch_with_http_info(
                index_name, batch_write_params, request_options
            )
        ).deserialize(BatchResponse)

    async def batch_assign_user_ids_with_http_info(
        self,
        x_algolia_user_id: Annotated[
            str, Field(strict=True, description="userID to assign.")
        ],
        batch_assign_user_ids_params: BatchAssignUserIdsParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Batch assign userIDs.

        Assign multiple user IDs to a cluster. **You can't _move_ users with this operation.**.

        :param x_algolia_user_id: userID to assign. (required)
        :type x_algolia_user_id: str
        :param batch_assign_user_ids_params: (required)
        :type batch_assign_user_ids_params: BatchAssignUserIdsParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if x_algolia_user_id is None:
            raise ValueError(
                "Parameter `x_algolia_user_id` is required when calling `batch_assign_user_ids`."
            )

        if batch_assign_user_ids_params is None:
            raise ValueError(
                "Parameter `batch_assign_user_ids_params` is required when calling `batch_assign_user_ids`."
            )

        _headers: Dict[str, Optional[str]] = {}

        if x_algolia_user_id is not None:
            _headers["x-algolia-user-id"] = x_algolia_user_id

        _body = {}
        if batch_assign_user_ids_params is not None:
            _body = batch_assign_user_ids_params

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/clusters/mapping/batch",
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                headers=_headers,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def batch_assign_user_ids(
        self,
        x_algolia_user_id: Annotated[
            str, Field(strict=True, description="userID to assign.")
        ],
        batch_assign_user_ids_params: BatchAssignUserIdsParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> CreatedAtResponse:
        """
        Batch assign userIDs.

        Assign multiple user IDs to a cluster. **You can't _move_ users with this operation.**.

        :param x_algolia_user_id: userID to assign. (required)
        :type x_algolia_user_id: str
        :param batch_assign_user_ids_params: (required)
        :type batch_assign_user_ids_params: BatchAssignUserIdsParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'CreatedAtResponse' result object.
        """
        return (
            await self.batch_assign_user_ids_with_http_info(
                x_algolia_user_id, batch_assign_user_ids_params, request_options
            )
        ).deserialize(CreatedAtResponse)

    async def batch_dictionary_entries_with_http_info(
        self,
        dictionary_name: Annotated[
            DictionaryType, Field(description="Dictionary to search in.")
        ],
        batch_dictionary_entries_params: BatchDictionaryEntriesParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Batch dictionary entries.

        Add or remove a batch of dictionary entries.

        :param dictionary_name: Dictionary to search in. (required)
        :type dictionary_name: DictionaryType
        :param batch_dictionary_entries_params: (required)
        :type batch_dictionary_entries_params: BatchDictionaryEntriesParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if dictionary_name is None:
            raise ValueError(
                "Parameter `dictionary_name` is required when calling `batch_dictionary_entries`."
            )

        if batch_dictionary_entries_params is None:
            raise ValueError(
                "Parameter `batch_dictionary_entries_params` is required when calling `batch_dictionary_entries`."
            )

        _body = {}
        if batch_dictionary_entries_params is not None:
            _body = batch_dictionary_entries_params

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/dictionaries/{dictionaryName}/batch".replace(
                "{dictionaryName}", quote(str(dictionary_name), safe="")
            ),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def batch_dictionary_entries(
        self,
        dictionary_name: Annotated[
            DictionaryType, Field(description="Dictionary to search in.")
        ],
        batch_dictionary_entries_params: BatchDictionaryEntriesParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> UpdatedAtResponse:
        """
        Batch dictionary entries.

        Add or remove a batch of dictionary entries.

        :param dictionary_name: Dictionary to search in. (required)
        :type dictionary_name: DictionaryType
        :param batch_dictionary_entries_params: (required)
        :type batch_dictionary_entries_params: BatchDictionaryEntriesParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'UpdatedAtResponse' result object.
        """
        return (
            await self.batch_dictionary_entries_with_http_info(
                dictionary_name, batch_dictionary_entries_params, request_options
            )
        ).deserialize(UpdatedAtResponse)

    async def browse_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        browse_params: Optional[BrowseParams] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Get all records from an index.

        Retrieve up to 1,000 records per call. Supports full-text search and filters. For better performance, it doesn't support: - The `distinct` query parameter - Sorting by typos, proximity, words, or geographical distance.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param browse_params:
        :type browse_params: BrowseParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `browse`."
            )

        _body = {}
        if browse_params is not None:
            _body = browse_params

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/{indexName}/browse".replace(
                "{indexName}", quote(str(index_name), safe="")
            ),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def browse(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        browse_params: Optional[BrowseParams] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> BrowseResponse:
        """
        Get all records from an index.

        Retrieve up to 1,000 records per call. Supports full-text search and filters. For better performance, it doesn't support: - The `distinct` query parameter - Sorting by typos, proximity, words, or geographical distance.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param browse_params:
        :type browse_params: BrowseParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'BrowseResponse' result object.
        """
        return (
            await self.browse_with_http_info(index_name, browse_params, request_options)
        ).deserialize(BrowseResponse)

    async def clear_all_synonyms_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Delete all synonyms.

        Delete all synonyms in the index.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `clear_all_synonyms`."
            )

        _query_parameters: List[Tuple[str, str]] = []

        if forward_to_replicas is not None:
            _query_parameters.append(("forwardToReplicas", forward_to_replicas))

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/{indexName}/synonyms/clear".replace(
                "{indexName}", quote(str(index_name), safe="")
            ),
            data=None,
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def clear_all_synonyms(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> UpdatedAtResponse:
        """
        Delete all synonyms.

        Delete all synonyms in the index.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'UpdatedAtResponse' result object.
        """
        return (
            await self.clear_all_synonyms_with_http_info(
                index_name, forward_to_replicas, request_options
            )
        ).deserialize(UpdatedAtResponse)

    async def clear_objects_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Delete all records from an index.

        Delete the records but leave settings and index-specific API keys untouched.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `clear_objects`."
            )

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/{indexName}/clear".replace(
                "{indexName}", quote(str(index_name), safe="")
            ),
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def clear_objects(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> UpdatedAtResponse:
        """
        Delete all records from an index.

        Delete the records but leave settings and index-specific API keys untouched.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'UpdatedAtResponse' result object.
        """
        return (
            await self.clear_objects_with_http_info(index_name, request_options)
        ).deserialize(UpdatedAtResponse)

    async def clear_rules_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Delete all rules.

        Delete all rules in the index.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `clear_rules`."
            )

        _query_parameters: List[Tuple[str, str]] = []

        if forward_to_replicas is not None:
            _query_parameters.append(("forwardToReplicas", forward_to_replicas))

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/{indexName}/rules/clear".replace(
                "{indexName}", quote(str(index_name), safe="")
            ),
            data=None,
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def clear_rules(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> UpdatedAtResponse:
        """
        Delete all rules.

        Delete all rules in the index.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'UpdatedAtResponse' result object.
        """
        return (
            await self.clear_rules_with_http_info(
                index_name, forward_to_replicas, request_options
            )
        ).deserialize(UpdatedAtResponse)

    async def custom_delete_with_http_info(
        self,
        path: Annotated[
            StrictStr,
            Field(
                description='Path of the endpoint, anything after "/1" must be specified.'
            ),
        ],
        parameters: Annotated[
            Optional[Dict[str, Any]],
            Field(description="Query parameters to apply to the current query."),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Send requests to the Algolia REST API.

        This method allow you to send requests to the Algolia REST API.

        :param path: Path of the endpoint, anything after \"/1\" must be specified. (required)
        :type path: str
        :param parameters: Query parameters to apply to the current query.
        :type parameters: Dict[str, object]
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if path is None:
            raise ValueError(
                "Parameter `path` is required when calling `custom_delete`."
            )

        _query_parameters: List[Tuple[str, str]] = []

        if parameters is not None:
            for _qpkey, _qpvalue in parameters.items():
                _query_parameters.append((_qpkey, _qpvalue))

        return await self._transporter.request(
            verb=Verb.DELETE,
            path="/1{path}".replace("{path}", path),
            data=None,
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def custom_delete(
        self,
        path: Annotated[
            StrictStr,
            Field(
                description='Path of the endpoint, anything after "/1" must be specified.'
            ),
        ],
        parameters: Annotated[
            Optional[Dict[str, Any]],
            Field(description="Query parameters to apply to the current query."),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> object:
        """
        Send requests to the Algolia REST API.

        This method allow you to send requests to the Algolia REST API.

        :param path: Path of the endpoint, anything after \"/1\" must be specified. (required)
        :type path: str
        :param parameters: Query parameters to apply to the current query.
        :type parameters: Dict[str, object]
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'object' result object.
        """
        return (
            await self.custom_delete_with_http_info(path, parameters, request_options)
        ).deserialize(object)

    async def custom_get_with_http_info(
        self,
        path: Annotated[
            StrictStr,
            Field(
                description='Path of the endpoint, anything after "/1" must be specified.'
            ),
        ],
        parameters: Annotated[
            Optional[Dict[str, Any]],
            Field(description="Query parameters to apply to the current query."),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Send requests to the Algolia REST API.

        This method allow you to send requests to the Algolia REST API.

        :param path: Path of the endpoint, anything after \"/1\" must be specified. (required)
        :type path: str
        :param parameters: Query parameters to apply to the current query.
        :type parameters: Dict[str, object]
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if path is None:
            raise ValueError("Parameter `path` is required when calling `custom_get`.")

        _query_parameters: List[Tuple[str, str]] = []

        if parameters is not None:
            for _qpkey, _qpvalue in parameters.items():
                _query_parameters.append((_qpkey, _qpvalue))

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1{path}".replace("{path}", path),
            data=None,
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def custom_get(
        self,
        path: Annotated[
            StrictStr,
            Field(
                description='Path of the endpoint, anything after "/1" must be specified.'
            ),
        ],
        parameters: Annotated[
            Optional[Dict[str, Any]],
            Field(description="Query parameters to apply to the current query."),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> object:
        """
        Send requests to the Algolia REST API.

        This method allow you to send requests to the Algolia REST API.

        :param path: Path of the endpoint, anything after \"/1\" must be specified. (required)
        :type path: str
        :param parameters: Query parameters to apply to the current query.
        :type parameters: Dict[str, object]
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'object' result object.
        """
        return (
            await self.custom_get_with_http_info(path, parameters, request_options)
        ).deserialize(object)

    async def custom_post_with_http_info(
        self,
        path: Annotated[
            StrictStr,
            Field(
                description='Path of the endpoint, anything after "/1" must be specified.'
            ),
        ],
        parameters: Annotated[
            Optional[Dict[str, Any]],
            Field(description="Query parameters to apply to the current query."),
        ] = None,
        body: Annotated[
            Optional[Dict[str, Any]],
            Field(description="Parameters to send with the custom request."),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Send requests to the Algolia REST API.

        This method allow you to send requests to the Algolia REST API.

        :param path: Path of the endpoint, anything after \"/1\" must be specified. (required)
        :type path: str
        :param parameters: Query parameters to apply to the current query.
        :type parameters: Dict[str, object]
        :param body: Parameters to send with the custom request.
        :type body: object
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if path is None:
            raise ValueError("Parameter `path` is required when calling `custom_post`.")

        _query_parameters: List[Tuple[str, str]] = []

        if parameters is not None:
            for _qpkey, _qpvalue in parameters.items():
                _query_parameters.append((_qpkey, _qpvalue))

        _body = {}
        if body is not None:
            _body = body

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1{path}".replace("{path}", path),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def custom_post(
        self,
        path: Annotated[
            StrictStr,
            Field(
                description='Path of the endpoint, anything after "/1" must be specified.'
            ),
        ],
        parameters: Annotated[
            Optional[Dict[str, Any]],
            Field(description="Query parameters to apply to the current query."),
        ] = None,
        body: Annotated[
            Optional[Dict[str, Any]],
            Field(description="Parameters to send with the custom request."),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> object:
        """
        Send requests to the Algolia REST API.

        This method allow you to send requests to the Algolia REST API.

        :param path: Path of the endpoint, anything after \"/1\" must be specified. (required)
        :type path: str
        :param parameters: Query parameters to apply to the current query.
        :type parameters: Dict[str, object]
        :param body: Parameters to send with the custom request.
        :type body: object
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'object' result object.
        """
        return (
            await self.custom_post_with_http_info(
                path, parameters, body, request_options
            )
        ).deserialize(object)

    async def custom_put_with_http_info(
        self,
        path: Annotated[
            StrictStr,
            Field(
                description='Path of the endpoint, anything after "/1" must be specified.'
            ),
        ],
        parameters: Annotated[
            Optional[Dict[str, Any]],
            Field(description="Query parameters to apply to the current query."),
        ] = None,
        body: Annotated[
            Optional[Dict[str, Any]],
            Field(description="Parameters to send with the custom request."),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Send requests to the Algolia REST API.

        This method allow you to send requests to the Algolia REST API.

        :param path: Path of the endpoint, anything after \"/1\" must be specified. (required)
        :type path: str
        :param parameters: Query parameters to apply to the current query.
        :type parameters: Dict[str, object]
        :param body: Parameters to send with the custom request.
        :type body: object
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if path is None:
            raise ValueError("Parameter `path` is required when calling `custom_put`.")

        _query_parameters: List[Tuple[str, str]] = []

        if parameters is not None:
            for _qpkey, _qpvalue in parameters.items():
                _query_parameters.append((_qpkey, _qpvalue))

        _body = {}
        if body is not None:
            _body = body

        return await self._transporter.request(
            verb=Verb.PUT,
            path="/1{path}".replace("{path}", path),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def custom_put(
        self,
        path: Annotated[
            StrictStr,
            Field(
                description='Path of the endpoint, anything after "/1" must be specified.'
            ),
        ],
        parameters: Annotated[
            Optional[Dict[str, Any]],
            Field(description="Query parameters to apply to the current query."),
        ] = None,
        body: Annotated[
            Optional[Dict[str, Any]],
            Field(description="Parameters to send with the custom request."),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> object:
        """
        Send requests to the Algolia REST API.

        This method allow you to send requests to the Algolia REST API.

        :param path: Path of the endpoint, anything after \"/1\" must be specified. (required)
        :type path: str
        :param parameters: Query parameters to apply to the current query.
        :type parameters: Dict[str, object]
        :param body: Parameters to send with the custom request.
        :type body: object
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'object' result object.
        """
        return (
            await self.custom_put_with_http_info(
                path, parameters, body, request_options
            )
        ).deserialize(object)

    async def delete_api_key_with_http_info(
        self,
        key: Annotated[StrictStr, Field(description="API key.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Delete API key.

        Delete an existing API key. The request must be authenticated with the admin API key.

        :param key: API key. (required)
        :type key: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if key is None:
            raise ValueError(
                "Parameter `key` is required when calling `delete_api_key`."
            )

        return await self._transporter.request(
            verb=Verb.DELETE,
            path="/1/keys/{key}".replace("{key}", quote(str(key), safe="")),
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def delete_api_key(
        self,
        key: Annotated[StrictStr, Field(description="API key.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> DeleteApiKeyResponse:
        """
        Delete API key.

        Delete an existing API key. The request must be authenticated with the admin API key.

        :param key: API key. (required)
        :type key: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'DeleteApiKeyResponse' result object.
        """
        return (
            await self.delete_api_key_with_http_info(key, request_options)
        ).deserialize(DeleteApiKeyResponse)

    async def delete_by_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        delete_by_params: DeleteByParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Delete all records matching a query.

        This operation doesn't support all the query options, only its filters (numeric, facet, or tag) and geo queries. It doesn't accept empty filters or queries.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param delete_by_params: (required)
        :type delete_by_params: DeleteByParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `delete_by`."
            )

        if delete_by_params is None:
            raise ValueError(
                "Parameter `delete_by_params` is required when calling `delete_by`."
            )

        _body = {}
        if delete_by_params is not None:
            _body = delete_by_params

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/{indexName}/deleteByQuery".replace(
                "{indexName}", quote(str(index_name), safe="")
            ),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def delete_by(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        delete_by_params: DeleteByParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> DeletedAtResponse:
        """
        Delete all records matching a query.

        This operation doesn't support all the query options, only its filters (numeric, facet, or tag) and geo queries. It doesn't accept empty filters or queries.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param delete_by_params: (required)
        :type delete_by_params: DeleteByParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'DeletedAtResponse' result object.
        """
        return (
            await self.delete_by_with_http_info(
                index_name, delete_by_params, request_options
            )
        ).deserialize(DeletedAtResponse)

    async def delete_index_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Delete index.

        Delete an existing index.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `delete_index`."
            )

        return await self._transporter.request(
            verb=Verb.DELETE,
            path="/1/indexes/{indexName}".replace(
                "{indexName}", quote(str(index_name), safe="")
            ),
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def delete_index(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> DeletedAtResponse:
        """
        Delete index.

        Delete an existing index.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'DeletedAtResponse' result object.
        """
        return (
            await self.delete_index_with_http_info(index_name, request_options)
        ).deserialize(DeletedAtResponse)

    async def delete_object_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique record (object) identifier.")
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Delete a record.

        To delete a set of records matching a query, use the [`deleteByQuery` operation](#tag/Records/operation/deleteBy) instead.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique record (object) identifier. (required)
        :type object_id: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `delete_object`."
            )

        if object_id is None:
            raise ValueError(
                "Parameter `object_id` is required when calling `delete_object`."
            )

        return await self._transporter.request(
            verb=Verb.DELETE,
            path="/1/indexes/{indexName}/{objectID}".replace(
                "{indexName}", quote(str(index_name), safe="")
            ).replace("{objectID}", quote(str(object_id), safe="")),
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def delete_object(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique record (object) identifier.")
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> DeletedAtResponse:
        """
        Delete a record.

        To delete a set of records matching a query, use the [`deleteByQuery` operation](#tag/Records/operation/deleteBy) instead.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique record (object) identifier. (required)
        :type object_id: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'DeletedAtResponse' result object.
        """
        return (
            await self.delete_object_with_http_info(
                index_name, object_id, request_options
            )
        ).deserialize(DeletedAtResponse)

    async def delete_rule_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique identifier of a rule object.")
        ],
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Delete a rule.

        Delete a rule by its `objectID`. To find the `objectID` for rules, use the [`search` operation](#tag/Rules/operation/searchRules).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique identifier of a rule object. (required)
        :type object_id: str
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `delete_rule`."
            )

        if object_id is None:
            raise ValueError(
                "Parameter `object_id` is required when calling `delete_rule`."
            )

        _query_parameters: List[Tuple[str, str]] = []

        if forward_to_replicas is not None:
            _query_parameters.append(("forwardToReplicas", forward_to_replicas))

        return await self._transporter.request(
            verb=Verb.DELETE,
            path="/1/indexes/{indexName}/rules/{objectID}".replace(
                "{indexName}", quote(str(index_name), safe="")
            ).replace("{objectID}", quote(str(object_id), safe="")),
            data=None,
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def delete_rule(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique identifier of a rule object.")
        ],
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> UpdatedAtResponse:
        """
        Delete a rule.

        Delete a rule by its `objectID`. To find the `objectID` for rules, use the [`search` operation](#tag/Rules/operation/searchRules).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique identifier of a rule object. (required)
        :type object_id: str
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'UpdatedAtResponse' result object.
        """
        return (
            await self.delete_rule_with_http_info(
                index_name, object_id, forward_to_replicas, request_options
            )
        ).deserialize(UpdatedAtResponse)

    async def delete_source_with_http_info(
        self,
        source: Annotated[
            StrictStr, Field(description="IP address range of the source.")
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Remove a source.

        Remove a source from the list of allowed sources.

        :param source: IP address range of the source. (required)
        :type source: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if source is None:
            raise ValueError(
                "Parameter `source` is required when calling `delete_source`."
            )

        return await self._transporter.request(
            verb=Verb.DELETE,
            path="/1/security/sources/{source}".replace(
                "{source}", quote(str(source), safe="")
            ),
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def delete_source(
        self,
        source: Annotated[
            StrictStr, Field(description="IP address range of the source.")
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> DeleteSourceResponse:
        """
        Remove a source.

        Remove a source from the list of allowed sources.

        :param source: IP address range of the source. (required)
        :type source: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'DeleteSourceResponse' result object.
        """
        return (
            await self.delete_source_with_http_info(source, request_options)
        ).deserialize(DeleteSourceResponse)

    async def delete_synonym_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique identifier of a synonym object.")
        ],
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Delete a synonym.

        Delete a synonym by its `objectID`. To find the object IDs of your synonyms, use the [`search` operation](#tag/Synonyms/operation/searchSynonyms).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique identifier of a synonym object. (required)
        :type object_id: str
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `delete_synonym`."
            )

        if object_id is None:
            raise ValueError(
                "Parameter `object_id` is required when calling `delete_synonym`."
            )

        _query_parameters: List[Tuple[str, str]] = []

        if forward_to_replicas is not None:
            _query_parameters.append(("forwardToReplicas", forward_to_replicas))

        return await self._transporter.request(
            verb=Verb.DELETE,
            path="/1/indexes/{indexName}/synonyms/{objectID}".replace(
                "{indexName}", quote(str(index_name), safe="")
            ).replace("{objectID}", quote(str(object_id), safe="")),
            data=None,
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def delete_synonym(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique identifier of a synonym object.")
        ],
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> DeletedAtResponse:
        """
        Delete a synonym.

        Delete a synonym by its `objectID`. To find the object IDs of your synonyms, use the [`search` operation](#tag/Synonyms/operation/searchSynonyms).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique identifier of a synonym object. (required)
        :type object_id: str
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'DeletedAtResponse' result object.
        """
        return (
            await self.delete_synonym_with_http_info(
                index_name, object_id, forward_to_replicas, request_options
            )
        ).deserialize(DeletedAtResponse)

    async def get_api_key_with_http_info(
        self,
        key: Annotated[StrictStr, Field(description="API key.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Get API key permissions.

        Get the permissions and restrictions of a specific API key. When authenticating with the admin API key, you can request information for any of your application's keys. When authenticating with other API keys, you can only retrieve information for that key.

        :param key: API key. (required)
        :type key: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if key is None:
            raise ValueError("Parameter `key` is required when calling `get_api_key`.")

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/keys/{key}".replace("{key}", quote(str(key), safe="")),
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def get_api_key(
        self,
        key: Annotated[StrictStr, Field(description="API key.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> GetApiKeyResponse:
        """
        Get API key permissions.

        Get the permissions and restrictions of a specific API key. When authenticating with the admin API key, you can request information for any of your application's keys. When authenticating with other API keys, you can only retrieve information for that key.

        :param key: API key. (required)
        :type key: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'GetApiKeyResponse' result object.
        """
        return (
            await self.get_api_key_with_http_info(key, request_options)
        ).deserialize(GetApiKeyResponse)

    async def get_dictionary_languages_with_http_info(
        self, request_options: Optional[Union[dict, RequestOptions]] = None
    ) -> ApiResponse[str]:
        """
        List available languages.

        Lists Algolia's [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/) and any customizations applied to each language's [stop word](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-stop-words/), [plural](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-plurals-and-other-declensions/), and [segmentation (compound)](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-segmentation/) features.

        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/dictionaries/*/languages",
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def get_dictionary_languages(
        self, request_options: Optional[Union[dict, RequestOptions]] = None
    ) -> Dict[str, Languages]:
        """
        List available languages.

        Lists Algolia's [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/) and any customizations applied to each language's [stop word](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-stop-words/), [plural](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-plurals-and-other-declensions/), and [segmentation (compound)](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-segmentation/) features.

        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'Dict[str, Languages]' result object.
        """
        return (
            await self.get_dictionary_languages_with_http_info(request_options)
        ).deserialize(Dict[str, Languages])

    async def get_dictionary_settings_with_http_info(
        self, request_options: Optional[Union[dict, RequestOptions]] = None
    ) -> ApiResponse[str]:
        """
        Get stop word settings.

        Get the languages for which [stop words are turned off](#tag/Dictionaries/operation/setDictionarySettings).

        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/dictionaries/*/settings",
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def get_dictionary_settings(
        self, request_options: Optional[Union[dict, RequestOptions]] = None
    ) -> GetDictionarySettingsResponse:
        """
        Get stop word settings.

        Get the languages for which [stop words are turned off](#tag/Dictionaries/operation/setDictionarySettings).

        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'GetDictionarySettingsResponse' result object.
        """
        return (
            await self.get_dictionary_settings_with_http_info(request_options)
        ).deserialize(GetDictionarySettingsResponse)

    async def get_logs_with_http_info(
        self,
        offset: Annotated[
            Optional[StrictInt],
            Field(
                description="First log entry to retrieve. Sorted by decreasing date with 0 being the most recent."
            ),
        ] = None,
        length: Annotated[
            Optional[Annotated[int, Field(le=1000, strict=True)]],
            Field(description="Maximum number of entries to retrieve."),
        ] = None,
        index_name: Annotated[
            Optional[StrictStr],
            Field(
                description="Index for which log entries should be retrieved. When omitted, log entries are retrieved for all indices."
            ),
        ] = None,
        type: Annotated[
            Optional[LogType],
            Field(
                description="Type of log entries to retrieve. When omitted, all log entries are retrieved."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Return the latest log entries.

        The request must be authenticated by an API key with the [`logs` ACL](https://www.algolia.com/doc/guides/security/api-keys/#access-control-list-acl). Logs are held for the last seven days. There's also a logging limit of 1,000 API calls per server. This request counts towards your [operations quota](https://support.algolia.com/hc/en-us/articles/4406981829777-How-does-Algolia-count-records-and-operations-) but doesn't appear in the logs itself. > **Note**: To fetch the logs for a Distributed Search Network (DSN) cluster, target the [DSN's endpoint](https://www.algolia.com/doc/guides/scaling/distributed-search-network-dsn/#accessing-dsn-servers).

        :param offset: First log entry to retrieve. Sorted by decreasing date with 0 being the most recent.
        :type offset: int
        :param length: Maximum number of entries to retrieve.
        :type length: int
        :param index_name: Index for which log entries should be retrieved. When omitted, log entries are retrieved for all indices.
        :type index_name: str
        :param type: Type of log entries to retrieve. When omitted, all log entries are retrieved.
        :type type: LogType
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        _query_parameters: List[Tuple[str, str]] = []

        if offset is not None:
            _query_parameters.append(("offset", offset))
        if length is not None:
            _query_parameters.append(("length", length))
        if index_name is not None:
            _query_parameters.append(("indexName", index_name))
        if type is not None:
            _query_parameters.append(("type", type))

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/logs",
            data=None,
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def get_logs(
        self,
        offset: Annotated[
            Optional[StrictInt],
            Field(
                description="First log entry to retrieve. Sorted by decreasing date with 0 being the most recent."
            ),
        ] = None,
        length: Annotated[
            Optional[Annotated[int, Field(le=1000, strict=True)]],
            Field(description="Maximum number of entries to retrieve."),
        ] = None,
        index_name: Annotated[
            Optional[StrictStr],
            Field(
                description="Index for which log entries should be retrieved. When omitted, log entries are retrieved for all indices."
            ),
        ] = None,
        type: Annotated[
            Optional[LogType],
            Field(
                description="Type of log entries to retrieve. When omitted, all log entries are retrieved."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> GetLogsResponse:
        """
        Return the latest log entries.

        The request must be authenticated by an API key with the [`logs` ACL](https://www.algolia.com/doc/guides/security/api-keys/#access-control-list-acl). Logs are held for the last seven days. There's also a logging limit of 1,000 API calls per server. This request counts towards your [operations quota](https://support.algolia.com/hc/en-us/articles/4406981829777-How-does-Algolia-count-records-and-operations-) but doesn't appear in the logs itself. > **Note**: To fetch the logs for a Distributed Search Network (DSN) cluster, target the [DSN's endpoint](https://www.algolia.com/doc/guides/scaling/distributed-search-network-dsn/#accessing-dsn-servers).

        :param offset: First log entry to retrieve. Sorted by decreasing date with 0 being the most recent.
        :type offset: int
        :param length: Maximum number of entries to retrieve.
        :type length: int
        :param index_name: Index for which log entries should be retrieved. When omitted, log entries are retrieved for all indices.
        :type index_name: str
        :param type: Type of log entries to retrieve. When omitted, all log entries are retrieved.
        :type type: LogType
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'GetLogsResponse' result object.
        """
        return (
            await self.get_logs_with_http_info(
                offset, length, index_name, type, request_options
            )
        ).deserialize(GetLogsResponse)

    async def get_object_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique record (object) identifier.")
        ],
        attributes_to_retrieve: Annotated[
            Optional[List[StrictStr]],
            Field(
                description="Attributes to include with the records in the response. This is useful to reduce the size of the API response. By default, all retrievable attributes are returned. `objectID` is always retrieved, even when not specified. [`unretrievableAttributes`](https://www.algolia.com/doc/api-reference/api-parameters/unretrievableAttributes/) won't be retrieved unless the request is authenticated with the admin API key. "
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Get a record.

        To get more than one record, use the [`objects` operation](#tag/Records/operation/getObjects).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique record (object) identifier. (required)
        :type object_id: str
        :param attributes_to_retrieve: Attributes to include with the records in the response. This is useful to reduce the size of the API response. By default, all retrievable attributes are returned. `objectID` is always retrieved, even when not specified. [`unretrievableAttributes`](https://www.algolia.com/doc/api-reference/api-parameters/unretrievableAttributes/) won't be retrieved unless the request is authenticated with the admin API key.
        :type attributes_to_retrieve: List[str]
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `get_object`."
            )

        if object_id is None:
            raise ValueError(
                "Parameter `object_id` is required when calling `get_object`."
            )

        _query_parameters: List[Tuple[str, str]] = []

        if attributes_to_retrieve is not None:
            _query_parameters.append(("attributesToRetrieve", attributes_to_retrieve))

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/indexes/{indexName}/{objectID}".replace(
                "{indexName}", quote(str(index_name), safe="")
            ).replace("{objectID}", quote(str(object_id), safe="")),
            data=None,
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def get_object(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique record (object) identifier.")
        ],
        attributes_to_retrieve: Annotated[
            Optional[List[StrictStr]],
            Field(
                description="Attributes to include with the records in the response. This is useful to reduce the size of the API response. By default, all retrievable attributes are returned. `objectID` is always retrieved, even when not specified. [`unretrievableAttributes`](https://www.algolia.com/doc/api-reference/api-parameters/unretrievableAttributes/) won't be retrieved unless the request is authenticated with the admin API key. "
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> Dict[str, str]:
        """
        Get a record.

        To get more than one record, use the [`objects` operation](#tag/Records/operation/getObjects).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique record (object) identifier. (required)
        :type object_id: str
        :param attributes_to_retrieve: Attributes to include with the records in the response. This is useful to reduce the size of the API response. By default, all retrievable attributes are returned. `objectID` is always retrieved, even when not specified. [`unretrievableAttributes`](https://www.algolia.com/doc/api-reference/api-parameters/unretrievableAttributes/) won't be retrieved unless the request is authenticated with the admin API key.
        :type attributes_to_retrieve: List[str]
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'Dict[str, str]' result object.
        """
        return (
            await self.get_object_with_http_info(
                index_name, object_id, attributes_to_retrieve, request_options
            )
        ).deserialize(Dict[str, str])

    async def get_objects_with_http_info(
        self,
        get_objects_params: Annotated[
            GetObjectsParams, Field(description="Request object.")
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Get multiple records.

        Retrieve one or more records, potentially from different indices, in a single API operation. Results will be received in the same order as the requests.

        :param get_objects_params: Request object. (required)
        :type get_objects_params: GetObjectsParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if get_objects_params is None:
            raise ValueError(
                "Parameter `get_objects_params` is required when calling `get_objects`."
            )

        _body = {}
        if get_objects_params is not None:
            _body = get_objects_params

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/*/objects",
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=True,
        )

    async def get_objects(
        self,
        get_objects_params: Annotated[
            GetObjectsParams, Field(description="Request object.")
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> GetObjectsResponse:
        """
        Get multiple records.

        Retrieve one or more records, potentially from different indices, in a single API operation. Results will be received in the same order as the requests.

        :param get_objects_params: Request object. (required)
        :type get_objects_params: GetObjectsParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'GetObjectsResponse' result object.
        """
        return (
            await self.get_objects_with_http_info(get_objects_params, request_options)
        ).deserialize(GetObjectsResponse)

    async def get_rule_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique identifier of a rule object.")
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Get a rule.

        Get a rule by its `objectID`. To find the `objectID` for rules, use the [`search` operation](#tag/Rules/operation/searchRules).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique identifier of a rule object. (required)
        :type object_id: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `get_rule`."
            )

        if object_id is None:
            raise ValueError(
                "Parameter `object_id` is required when calling `get_rule`."
            )

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/indexes/{indexName}/rules/{objectID}".replace(
                "{indexName}", quote(str(index_name), safe="")
            ).replace("{objectID}", quote(str(object_id), safe="")),
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def get_rule(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique identifier of a rule object.")
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> Rule:
        """
        Get a rule.

        Get a rule by its `objectID`. To find the `objectID` for rules, use the [`search` operation](#tag/Rules/operation/searchRules).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique identifier of a rule object. (required)
        :type object_id: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'Rule' result object.
        """
        return (
            await self.get_rule_with_http_info(index_name, object_id, request_options)
        ).deserialize(Rule)

    async def get_settings_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Get index settings.

        Return an object containing an index's [configuration settings](https://www.algolia.com/doc/api-reference/settings-api-parameters/).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `get_settings`."
            )

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/indexes/{indexName}/settings".replace(
                "{indexName}", quote(str(index_name), safe="")
            ),
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def get_settings(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> IndexSettings:
        """
        Get index settings.

        Return an object containing an index's [configuration settings](https://www.algolia.com/doc/api-reference/settings-api-parameters/).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'IndexSettings' result object.
        """
        return (
            await self.get_settings_with_http_info(index_name, request_options)
        ).deserialize(IndexSettings)

    async def get_sources_with_http_info(
        self, request_options: Optional[Union[dict, RequestOptions]] = None
    ) -> ApiResponse[str]:
        """
        Get all allowed IP addresses.

        Get all allowed sources (IP addresses).

        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/security/sources",
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def get_sources(
        self, request_options: Optional[Union[dict, RequestOptions]] = None
    ) -> List[Source]:
        """
        Get all allowed IP addresses.

        Get all allowed sources (IP addresses).

        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'List[Source]' result object.
        """
        return (await self.get_sources_with_http_info(request_options)).deserialize(
            List[Source]
        )

    async def get_synonym_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique identifier of a synonym object.")
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Get a synonym object.

        Get a syonym by its `objectID`. To find the object IDs for your synonyms, use the [`search` operation](#tag/Synonyms/operation/searchSynonyms).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique identifier of a synonym object. (required)
        :type object_id: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `get_synonym`."
            )

        if object_id is None:
            raise ValueError(
                "Parameter `object_id` is required when calling `get_synonym`."
            )

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/indexes/{indexName}/synonyms/{objectID}".replace(
                "{indexName}", quote(str(index_name), safe="")
            ).replace("{objectID}", quote(str(object_id), safe="")),
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def get_synonym(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique identifier of a synonym object.")
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> SynonymHit:
        """
        Get a synonym object.

        Get a syonym by its `objectID`. To find the object IDs for your synonyms, use the [`search` operation](#tag/Synonyms/operation/searchSynonyms).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique identifier of a synonym object. (required)
        :type object_id: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'SynonymHit' result object.
        """
        return (
            await self.get_synonym_with_http_info(
                index_name, object_id, request_options
            )
        ).deserialize(SynonymHit)

    async def get_task_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        task_id: Annotated[StrictInt, Field(description="Unique task identifier.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Check a task's status.

        Some operations, such as copying an index, will respond with a `taskID` value. Use this value here to check the status of that task.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param task_id: Unique task identifier. (required)
        :type task_id: int
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `get_task`."
            )

        if task_id is None:
            raise ValueError("Parameter `task_id` is required when calling `get_task`.")

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/indexes/{indexName}/task/{taskID}".replace(
                "{indexName}", quote(str(index_name), safe="")
            ).replace("{taskID}", quote(str(task_id), safe="")),
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def get_task(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        task_id: Annotated[StrictInt, Field(description="Unique task identifier.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> GetTaskResponse:
        """
        Check a task's status.

        Some operations, such as copying an index, will respond with a `taskID` value. Use this value here to check the status of that task.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param task_id: Unique task identifier. (required)
        :type task_id: int
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'GetTaskResponse' result object.
        """
        return (
            await self.get_task_with_http_info(index_name, task_id, request_options)
        ).deserialize(GetTaskResponse)

    async def get_top_user_ids_with_http_info(
        self, request_options: Optional[Union[dict, RequestOptions]] = None
    ) -> ApiResponse[str]:
        """
        Get top userID.

        Get the IDs of the 10 users with the highest number of records per cluster. Since it can take up to a few seconds to get the data from the different clusters, the response isn't real-time.

        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/clusters/mapping/top",
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def get_top_user_ids(
        self, request_options: Optional[Union[dict, RequestOptions]] = None
    ) -> GetTopUserIdsResponse:
        """
        Get top userID.

        Get the IDs of the 10 users with the highest number of records per cluster. Since it can take up to a few seconds to get the data from the different clusters, the response isn't real-time.

        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'GetTopUserIdsResponse' result object.
        """
        return (
            await self.get_top_user_ids_with_http_info(request_options)
        ).deserialize(GetTopUserIdsResponse)

    async def get_user_id_with_http_info(
        self,
        user_id: Annotated[str, Field(strict=True, description="userID to assign.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Get userID.

        Returns the userID data stored in the mapping. Since it can take up to a few seconds to get the data from the different clusters, the response isn't real-time.

        :param user_id: userID to assign. (required)
        :type user_id: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if user_id is None:
            raise ValueError(
                "Parameter `user_id` is required when calling `get_user_id`."
            )

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/clusters/mapping/{userID}".replace(
                "{userID}", quote(str(user_id), safe="")
            ),
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def get_user_id(
        self,
        user_id: Annotated[str, Field(strict=True, description="userID to assign.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> UserId:
        """
        Get userID.

        Returns the userID data stored in the mapping. Since it can take up to a few seconds to get the data from the different clusters, the response isn't real-time.

        :param user_id: userID to assign. (required)
        :type user_id: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'UserId' result object.
        """
        return (
            await self.get_user_id_with_http_info(user_id, request_options)
        ).deserialize(UserId)

    async def has_pending_mappings_with_http_info(
        self,
        get_clusters: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether to include the cluster's pending mapping state in the response."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Get migration and user mapping status.

        To determine when the time-consuming process of creating a large batch of users or migrating users from one cluster to another is complete, this operation retrieves the status of the process.

        :param get_clusters: Indicates whether to include the cluster's pending mapping state in the response.
        :type get_clusters: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        _query_parameters: List[Tuple[str, str]] = []

        if get_clusters is not None:
            _query_parameters.append(("getClusters", get_clusters))

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/clusters/mapping/pending",
            data=None,
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def has_pending_mappings(
        self,
        get_clusters: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether to include the cluster's pending mapping state in the response."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> HasPendingMappingsResponse:
        """
        Get migration and user mapping status.

        To determine when the time-consuming process of creating a large batch of users or migrating users from one cluster to another is complete, this operation retrieves the status of the process.

        :param get_clusters: Indicates whether to include the cluster's pending mapping state in the response.
        :type get_clusters: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'HasPendingMappingsResponse' result object.
        """
        return (
            await self.has_pending_mappings_with_http_info(
                get_clusters, request_options
            )
        ).deserialize(HasPendingMappingsResponse)

    async def list_api_keys_with_http_info(
        self, request_options: Optional[Union[dict, RequestOptions]] = None
    ) -> ApiResponse[str]:
        """
        List API keys.

        List all API keys associated with your Algolia application, including their permissions and restrictions.

        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/keys",
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def list_api_keys(
        self, request_options: Optional[Union[dict, RequestOptions]] = None
    ) -> ListApiKeysResponse:
        """
        List API keys.

        List all API keys associated with your Algolia application, including their permissions and restrictions.

        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'ListApiKeysResponse' result object.
        """
        return (await self.list_api_keys_with_http_info(request_options)).deserialize(
            ListApiKeysResponse
        )

    async def list_clusters_with_http_info(
        self, request_options: Optional[Union[dict, RequestOptions]] = None
    ) -> ApiResponse[str]:
        """
        List clusters.

        List the available clusters in a multi-cluster setup.

        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/clusters",
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def list_clusters(
        self, request_options: Optional[Union[dict, RequestOptions]] = None
    ) -> ListClustersResponse:
        """
        List clusters.

        List the available clusters in a multi-cluster setup.

        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'ListClustersResponse' result object.
        """
        return (await self.list_clusters_with_http_info(request_options)).deserialize(
            ListClustersResponse
        )

    async def list_indices_with_http_info(
        self,
        page: Annotated[
            Optional[Annotated[int, Field(strict=True, ge=0)]],
            Field(
                description="Returns the requested page number. The page size is determined by the `hitsPerPage` parameter. You can see the number of available pages in the `nbPages` response attribute. When `page` is null, the API response is not paginated. "
            ),
        ] = None,
        hits_per_page: Annotated[
            Optional[StrictInt], Field(description="Maximum number of hits per page.")
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        List indices.

        List indices in an Algolia application.

        :param page: Returns the requested page number. The page size is determined by the `hitsPerPage` parameter. You can see the number of available pages in the `nbPages` response attribute. When `page` is null, the API response is not paginated.
        :type page: int
        :param hits_per_page: Maximum number of hits per page.
        :type hits_per_page: int
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        _query_parameters: List[Tuple[str, str]] = []

        if page is not None:
            _query_parameters.append(("page", page))
        if hits_per_page is not None:
            _query_parameters.append(("hitsPerPage", hits_per_page))

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/indexes",
            data=None,
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def list_indices(
        self,
        page: Annotated[
            Optional[Annotated[int, Field(strict=True, ge=0)]],
            Field(
                description="Returns the requested page number. The page size is determined by the `hitsPerPage` parameter. You can see the number of available pages in the `nbPages` response attribute. When `page` is null, the API response is not paginated. "
            ),
        ] = None,
        hits_per_page: Annotated[
            Optional[StrictInt], Field(description="Maximum number of hits per page.")
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ListIndicesResponse:
        """
        List indices.

        List indices in an Algolia application.

        :param page: Returns the requested page number. The page size is determined by the `hitsPerPage` parameter. You can see the number of available pages in the `nbPages` response attribute. When `page` is null, the API response is not paginated.
        :type page: int
        :param hits_per_page: Maximum number of hits per page.
        :type hits_per_page: int
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'ListIndicesResponse' result object.
        """
        return (
            await self.list_indices_with_http_info(page, hits_per_page, request_options)
        ).deserialize(ListIndicesResponse)

    async def list_user_ids_with_http_info(
        self,
        page: Annotated[
            Optional[Annotated[int, Field(strict=True, ge=0)]],
            Field(
                description="Returns the requested page number. The page size is determined by the `hitsPerPage` parameter. You can see the number of available pages in the `nbPages` response attribute. When `page` is null, the API response is not paginated. "
            ),
        ] = None,
        hits_per_page: Annotated[
            Optional[StrictInt], Field(description="Maximum number of hits per page.")
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        List userIDs.

        List the userIDs assigned to a multi-cluster application. Since it can take up to a few seconds to get the data from the different clusters, the response isn't real-time.

        :param page: Returns the requested page number. The page size is determined by the `hitsPerPage` parameter. You can see the number of available pages in the `nbPages` response attribute. When `page` is null, the API response is not paginated.
        :type page: int
        :param hits_per_page: Maximum number of hits per page.
        :type hits_per_page: int
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        _query_parameters: List[Tuple[str, str]] = []

        if page is not None:
            _query_parameters.append(("page", page))
        if hits_per_page is not None:
            _query_parameters.append(("hitsPerPage", hits_per_page))

        return await self._transporter.request(
            verb=Verb.GET,
            path="/1/clusters/mapping",
            data=None,
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def list_user_ids(
        self,
        page: Annotated[
            Optional[Annotated[int, Field(strict=True, ge=0)]],
            Field(
                description="Returns the requested page number. The page size is determined by the `hitsPerPage` parameter. You can see the number of available pages in the `nbPages` response attribute. When `page` is null, the API response is not paginated. "
            ),
        ] = None,
        hits_per_page: Annotated[
            Optional[StrictInt], Field(description="Maximum number of hits per page.")
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ListUserIdsResponse:
        """
        List userIDs.

        List the userIDs assigned to a multi-cluster application. Since it can take up to a few seconds to get the data from the different clusters, the response isn't real-time.

        :param page: Returns the requested page number. The page size is determined by the `hitsPerPage` parameter. You can see the number of available pages in the `nbPages` response attribute. When `page` is null, the API response is not paginated.
        :type page: int
        :param hits_per_page: Maximum number of hits per page.
        :type hits_per_page: int
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'ListUserIdsResponse' result object.
        """
        return (
            await self.list_user_ids_with_http_info(
                page, hits_per_page, request_options
            )
        ).deserialize(ListUserIdsResponse)

    async def multiple_batch_with_http_info(
        self,
        batch_params: BatchParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Batch write operations on multiple indices.

        To reduce the time spent on network round trips, you can perform several write actions in a single request. It's a multi-index version of the [`batch` operation](#tag/Records/operation/batch). Actions are applied in the order they are specified. The supported actions are equivalent to the individual operations of the same name.

        :param batch_params: (required)
        :type batch_params: BatchParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if batch_params is None:
            raise ValueError(
                "Parameter `batch_params` is required when calling `multiple_batch`."
            )

        _body = {}
        if batch_params is not None:
            _body = batch_params

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/*/batch",
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def multiple_batch(
        self,
        batch_params: BatchParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> MultipleBatchResponse:
        """
        Batch write operations on multiple indices.

        To reduce the time spent on network round trips, you can perform several write actions in a single request. It's a multi-index version of the [`batch` operation](#tag/Records/operation/batch). Actions are applied in the order they are specified. The supported actions are equivalent to the individual operations of the same name.

        :param batch_params: (required)
        :type batch_params: BatchParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'MultipleBatchResponse' result object.
        """
        return (
            await self.multiple_batch_with_http_info(batch_params, request_options)
        ).deserialize(MultipleBatchResponse)

    async def operation_index_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        operation_index_params: OperationIndexParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Copy, move, or rename an index.

        This `operation`, _copy_ or _move_, will copy or move a source index's (`IndexName`) records, settings, synonyms, and rules to a `destination` index. If the destination index exists, it will be replaced, except for index-specific API keys and analytics data. If the destination index doesn't exist, it will be created.  The choice between moving or copying an index depends on your needs. Choose:  - **Move** to rename an index. - **Copy** to create a new index with the same records and configuration as an existing one.  > **Note**: When considering copying or moving, be aware of the [rate limitations](https://www.algolia.com/doc/guides/scaling/algolia-service-limits/#application-record-and-index-limits) on these processes and the [impact on your analytics data](https://www.algolia.com/doc/guides/sending-and-managing-data/manage-indices-and-apps/manage-indices/concepts/indices-analytics/).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param operation_index_params: (required)
        :type operation_index_params: OperationIndexParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `operation_index`."
            )

        if operation_index_params is None:
            raise ValueError(
                "Parameter `operation_index_params` is required when calling `operation_index`."
            )

        _body = {}
        if operation_index_params is not None:
            _body = operation_index_params

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/{indexName}/operation".replace(
                "{indexName}", quote(str(index_name), safe="")
            ),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def operation_index(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        operation_index_params: OperationIndexParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> UpdatedAtResponse:
        """
        Copy, move, or rename an index.

        This `operation`, _copy_ or _move_, will copy or move a source index's (`IndexName`) records, settings, synonyms, and rules to a `destination` index. If the destination index exists, it will be replaced, except for index-specific API keys and analytics data. If the destination index doesn't exist, it will be created.  The choice between moving or copying an index depends on your needs. Choose:  - **Move** to rename an index. - **Copy** to create a new index with the same records and configuration as an existing one.  > **Note**: When considering copying or moving, be aware of the [rate limitations](https://www.algolia.com/doc/guides/scaling/algolia-service-limits/#application-record-and-index-limits) on these processes and the [impact on your analytics data](https://www.algolia.com/doc/guides/sending-and-managing-data/manage-indices-and-apps/manage-indices/concepts/indices-analytics/).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param operation_index_params: (required)
        :type operation_index_params: OperationIndexParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'UpdatedAtResponse' result object.
        """
        return (
            await self.operation_index_with_http_info(
                index_name, operation_index_params, request_options
            )
        ).deserialize(UpdatedAtResponse)

    async def partial_update_object_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique record (object) identifier.")
        ],
        attributes_to_update: Annotated[
            Dict[str, AttributeToUpdate],
            Field(description="Object with attributes to update."),
        ],
        create_if_not_exists: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether to create a new record if it doesn't exist yet. "
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Update record attributes.

        Add new attributes or update current ones in an existing record. You can use any first-level attribute but not nested attributes. If you specify a [nested attribute](https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/how-to/creating-and-using-nested-attributes/), the engine treats it as a replacement for its first-level ancestor.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique record (object) identifier. (required)
        :type object_id: str
        :param attributes_to_update: Object with attributes to update. (required)
        :type attributes_to_update: Dict[str, AttributeToUpdate]
        :param create_if_not_exists: Indicates whether to create a new record if it doesn't exist yet.
        :type create_if_not_exists: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `partial_update_object`."
            )

        if object_id is None:
            raise ValueError(
                "Parameter `object_id` is required when calling `partial_update_object`."
            )

        if attributes_to_update is None:
            raise ValueError(
                "Parameter `attributes_to_update` is required when calling `partial_update_object`."
            )

        _query_parameters: List[Tuple[str, str]] = []

        if create_if_not_exists is not None:
            _query_parameters.append(("createIfNotExists", create_if_not_exists))

        _body = {}
        if attributes_to_update is not None:
            _body = attributes_to_update

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/{indexName}/{objectID}/partial".replace(
                "{indexName}", quote(str(index_name), safe="")
            ).replace("{objectID}", quote(str(object_id), safe="")),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def partial_update_object(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique record (object) identifier.")
        ],
        attributes_to_update: Annotated[
            Dict[str, AttributeToUpdate],
            Field(description="Object with attributes to update."),
        ],
        create_if_not_exists: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether to create a new record if it doesn't exist yet. "
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> UpdatedAtWithObjectIdResponse:
        """
        Update record attributes.

        Add new attributes or update current ones in an existing record. You can use any first-level attribute but not nested attributes. If you specify a [nested attribute](https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/how-to/creating-and-using-nested-attributes/), the engine treats it as a replacement for its first-level ancestor.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique record (object) identifier. (required)
        :type object_id: str
        :param attributes_to_update: Object with attributes to update. (required)
        :type attributes_to_update: Dict[str, AttributeToUpdate]
        :param create_if_not_exists: Indicates whether to create a new record if it doesn't exist yet.
        :type create_if_not_exists: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'UpdatedAtWithObjectIdResponse' result object.
        """
        return (
            await self.partial_update_object_with_http_info(
                index_name,
                object_id,
                attributes_to_update,
                create_if_not_exists,
                request_options,
            )
        ).deserialize(UpdatedAtWithObjectIdResponse)

    async def remove_user_id_with_http_info(
        self,
        user_id: Annotated[str, Field(strict=True, description="userID to assign.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Remove userID.

        Remove a userID and its associated data from the multi-clusters.

        :param user_id: userID to assign. (required)
        :type user_id: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if user_id is None:
            raise ValueError(
                "Parameter `user_id` is required when calling `remove_user_id`."
            )

        return await self._transporter.request(
            verb=Verb.DELETE,
            path="/1/clusters/mapping/{userID}".replace(
                "{userID}", quote(str(user_id), safe="")
            ),
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def remove_user_id(
        self,
        user_id: Annotated[str, Field(strict=True, description="userID to assign.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> RemoveUserIdResponse:
        """
        Remove userID.

        Remove a userID and its associated data from the multi-clusters.

        :param user_id: userID to assign. (required)
        :type user_id: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'RemoveUserIdResponse' result object.
        """
        return (
            await self.remove_user_id_with_http_info(user_id, request_options)
        ).deserialize(RemoveUserIdResponse)

    async def replace_sources_with_http_info(
        self,
        source: Annotated[List[Source], Field(description="Allowed sources.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Replace all sources.

        Replace all allowed sources.

        :param source: Allowed sources. (required)
        :type source: List[Source]
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if source is None:
            raise ValueError(
                "Parameter `source` is required when calling `replace_sources`."
            )

        _body = {}
        if source is not None:
            _body = source

        return await self._transporter.request(
            verb=Verb.PUT,
            path="/1/security/sources",
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def replace_sources(
        self,
        source: Annotated[List[Source], Field(description="Allowed sources.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ReplaceSourceResponse:
        """
        Replace all sources.

        Replace all allowed sources.

        :param source: Allowed sources. (required)
        :type source: List[Source]
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'ReplaceSourceResponse' result object.
        """
        return (
            await self.replace_sources_with_http_info(source, request_options)
        ).deserialize(ReplaceSourceResponse)

    async def restore_api_key_with_http_info(
        self,
        key: Annotated[StrictStr, Field(description="API key.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Restore API key.

        Restore a deleted API key, along with its associated permissions. The request must be authenticated with the admin API key.

        :param key: API key. (required)
        :type key: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if key is None:
            raise ValueError(
                "Parameter `key` is required when calling `restore_api_key`."
            )

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/keys/{key}/restore".replace("{key}", quote(str(key), safe="")),
            data=None,
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def restore_api_key(
        self,
        key: Annotated[StrictStr, Field(description="API key.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> AddApiKeyResponse:
        """
        Restore API key.

        Restore a deleted API key, along with its associated permissions. The request must be authenticated with the admin API key.

        :param key: API key. (required)
        :type key: str
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'AddApiKeyResponse' result object.
        """
        return (
            await self.restore_api_key_with_http_info(key, request_options)
        ).deserialize(AddApiKeyResponse)

    async def save_object_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        body: Annotated[Dict[str, Any], Field(description="The Algolia record.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Add or update a record.

        Add a record (object) to an index or replace it. If the record doesn't contain an `objectID`, Algolia automatically adds it. If you use an existing `objectID`, the existing record is replaced with the new one. To add multiple records to your index in a single API request, use the [`batch` operation](#tag/Records/operation/batch).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param body: The Algolia record. (required)
        :type body: object
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `save_object`."
            )

        if body is None:
            raise ValueError("Parameter `body` is required when calling `save_object`.")

        _body = {}
        if body is not None:
            _body = body

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/{indexName}".replace(
                "{indexName}", quote(str(index_name), safe="")
            ),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def save_object(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        body: Annotated[Dict[str, Any], Field(description="The Algolia record.")],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> SaveObjectResponse:
        """
        Add or update a record.

        Add a record (object) to an index or replace it. If the record doesn't contain an `objectID`, Algolia automatically adds it. If you use an existing `objectID`, the existing record is replaced with the new one. To add multiple records to your index in a single API request, use the [`batch` operation](#tag/Records/operation/batch).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param body: The Algolia record. (required)
        :type body: object
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'SaveObjectResponse' result object.
        """
        return (
            await self.save_object_with_http_info(index_name, body, request_options)
        ).deserialize(SaveObjectResponse)

    async def save_rule_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique identifier of a rule object.")
        ],
        rule: Rule,
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Create or update a rule.

        To create or update more than one rule, use the [`batch` operation](#tag/Rules/operation/saveRules).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique identifier of a rule object. (required)
        :type object_id: str
        :param rule: (required)
        :type rule: Rule
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `save_rule`."
            )

        if object_id is None:
            raise ValueError(
                "Parameter `object_id` is required when calling `save_rule`."
            )

        if rule is None:
            raise ValueError("Parameter `rule` is required when calling `save_rule`.")

        _query_parameters: List[Tuple[str, str]] = []

        if forward_to_replicas is not None:
            _query_parameters.append(("forwardToReplicas", forward_to_replicas))

        _body = {}
        if rule is not None:
            _body = rule

        return await self._transporter.request(
            verb=Verb.PUT,
            path="/1/indexes/{indexName}/rules/{objectID}".replace(
                "{indexName}", quote(str(index_name), safe="")
            ).replace("{objectID}", quote(str(object_id), safe="")),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def save_rule(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique identifier of a rule object.")
        ],
        rule: Rule,
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> UpdatedRuleResponse:
        """
        Create or update a rule.

        To create or update more than one rule, use the [`batch` operation](#tag/Rules/operation/saveRules).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique identifier of a rule object. (required)
        :type object_id: str
        :param rule: (required)
        :type rule: Rule
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'UpdatedRuleResponse' result object.
        """
        return (
            await self.save_rule_with_http_info(
                index_name, object_id, rule, forward_to_replicas, request_options
            )
        ).deserialize(UpdatedRuleResponse)

    async def save_rules_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        rules: List[Rule],
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        clear_existing_rules: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether existing rules should be deleted before adding this batch."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Save a batch of rules.

        Create or update multiple rules.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param rules: (required)
        :type rules: List[Rule]
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param clear_existing_rules: Indicates whether existing rules should be deleted before adding this batch.
        :type clear_existing_rules: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `save_rules`."
            )

        if rules is None:
            raise ValueError("Parameter `rules` is required when calling `save_rules`.")

        _query_parameters: List[Tuple[str, str]] = []

        if forward_to_replicas is not None:
            _query_parameters.append(("forwardToReplicas", forward_to_replicas))
        if clear_existing_rules is not None:
            _query_parameters.append(("clearExistingRules", clear_existing_rules))

        _body = {}
        if rules is not None:
            _body = rules

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/{indexName}/rules/batch".replace(
                "{indexName}", quote(str(index_name), safe="")
            ),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def save_rules(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        rules: List[Rule],
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        clear_existing_rules: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether existing rules should be deleted before adding this batch."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> UpdatedAtResponse:
        """
        Save a batch of rules.

        Create or update multiple rules.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param rules: (required)
        :type rules: List[Rule]
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param clear_existing_rules: Indicates whether existing rules should be deleted before adding this batch.
        :type clear_existing_rules: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'UpdatedAtResponse' result object.
        """
        return (
            await self.save_rules_with_http_info(
                index_name,
                rules,
                forward_to_replicas,
                clear_existing_rules,
                request_options,
            )
        ).deserialize(UpdatedAtResponse)

    async def save_synonym_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique identifier of a synonym object.")
        ],
        synonym_hit: SynonymHit,
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Save a synonym.

        Add a [synonym](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/#the-different-types-of-synonyms) to an index or replace it. If the synonym `objectID` doesn't exist, Algolia adds a new one. If you use an existing synonym `objectID`, the existing synonym is replaced with the new one. To add multiple synonyms in a single API request, use the [`batch` operation](#tag/Synonyms/operation/saveSynonyms).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique identifier of a synonym object. (required)
        :type object_id: str
        :param synonym_hit: (required)
        :type synonym_hit: SynonymHit
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `save_synonym`."
            )

        if object_id is None:
            raise ValueError(
                "Parameter `object_id` is required when calling `save_synonym`."
            )

        if synonym_hit is None:
            raise ValueError(
                "Parameter `synonym_hit` is required when calling `save_synonym`."
            )

        _query_parameters: List[Tuple[str, str]] = []

        if forward_to_replicas is not None:
            _query_parameters.append(("forwardToReplicas", forward_to_replicas))

        _body = {}
        if synonym_hit is not None:
            _body = synonym_hit

        return await self._transporter.request(
            verb=Verb.PUT,
            path="/1/indexes/{indexName}/synonyms/{objectID}".replace(
                "{indexName}", quote(str(index_name), safe="")
            ).replace("{objectID}", quote(str(object_id), safe="")),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def save_synonym(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        object_id: Annotated[
            StrictStr, Field(description="Unique identifier of a synonym object.")
        ],
        synonym_hit: SynonymHit,
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> SaveSynonymResponse:
        """
        Save a synonym.

        Add a [synonym](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/#the-different-types-of-synonyms) to an index or replace it. If the synonym `objectID` doesn't exist, Algolia adds a new one. If you use an existing synonym `objectID`, the existing synonym is replaced with the new one. To add multiple synonyms in a single API request, use the [`batch` operation](#tag/Synonyms/operation/saveSynonyms).

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param object_id: Unique identifier of a synonym object. (required)
        :type object_id: str
        :param synonym_hit: (required)
        :type synonym_hit: SynonymHit
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'SaveSynonymResponse' result object.
        """
        return (
            await self.save_synonym_with_http_info(
                index_name, object_id, synonym_hit, forward_to_replicas, request_options
            )
        ).deserialize(SaveSynonymResponse)

    async def save_synonyms_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        synonym_hit: List[SynonymHit],
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        replace_existing_synonyms: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether to replace all synonyms in the index with the ones sent with this request."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Save a batch of synonyms.

        Create or update multiple synonyms.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param synonym_hit: (required)
        :type synonym_hit: List[SynonymHit]
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param replace_existing_synonyms: Indicates whether to replace all synonyms in the index with the ones sent with this request.
        :type replace_existing_synonyms: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `save_synonyms`."
            )

        if synonym_hit is None:
            raise ValueError(
                "Parameter `synonym_hit` is required when calling `save_synonyms`."
            )

        _query_parameters: List[Tuple[str, str]] = []

        if forward_to_replicas is not None:
            _query_parameters.append(("forwardToReplicas", forward_to_replicas))
        if replace_existing_synonyms is not None:
            _query_parameters.append(
                ("replaceExistingSynonyms", replace_existing_synonyms)
            )

        _body = {}
        if synonym_hit is not None:
            _body = synonym_hit

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/{indexName}/synonyms/batch".replace(
                "{indexName}", quote(str(index_name), safe="")
            ),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def save_synonyms(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        synonym_hit: List[SynonymHit],
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        replace_existing_synonyms: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether to replace all synonyms in the index with the ones sent with this request."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> UpdatedAtResponse:
        """
        Save a batch of synonyms.

        Create or update multiple synonyms.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param synonym_hit: (required)
        :type synonym_hit: List[SynonymHit]
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param replace_existing_synonyms: Indicates whether to replace all synonyms in the index with the ones sent with this request.
        :type replace_existing_synonyms: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'UpdatedAtResponse' result object.
        """
        return (
            await self.save_synonyms_with_http_info(
                index_name,
                synonym_hit,
                forward_to_replicas,
                replace_existing_synonyms,
                request_options,
            )
        ).deserialize(UpdatedAtResponse)

    async def search_with_http_info(
        self,
        search_method_params: Annotated[
            SearchMethodParams,
            Field(
                description="Query requests and strategies. Results will be received in the same order as the queries."
            ),
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Search multiple indices.

        Send multiple search queries to one or more indices.

        :param search_method_params: Query requests and strategies. Results will be received in the same order as the queries. (required)
        :type search_method_params: SearchMethodParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if search_method_params is None:
            raise ValueError(
                "Parameter `search_method_params` is required when calling `search`."
            )

        _body = {}
        if search_method_params is not None:
            _body = search_method_params

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/*/queries",
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=True,
        )

    async def search(
        self,
        search_method_params: Annotated[
            SearchMethodParams,
            Field(
                description="Query requests and strategies. Results will be received in the same order as the queries."
            ),
        ],
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> SearchResponses:
        """
        Search multiple indices.

        Send multiple search queries to one or more indices.

        :param search_method_params: Query requests and strategies. Results will be received in the same order as the queries. (required)
        :type search_method_params: SearchMethodParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'SearchResponses' result object.
        """
        return (
            await self.search_with_http_info(search_method_params, request_options)
        ).deserialize(SearchResponses)

    async def search_dictionary_entries_with_http_info(
        self,
        dictionary_name: Annotated[
            DictionaryType, Field(description="Dictionary to search in.")
        ],
        search_dictionary_entries_params: SearchDictionaryEntriesParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Search dictionary entries.

        Search for standard and [custom](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-stop-words/) entries in the [stop words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-stop-words/), [plurals](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-plurals-and-other-declensions/), or [segmentation (compounds)](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-segmentation/) dictionaries.

        :param dictionary_name: Dictionary to search in. (required)
        :type dictionary_name: DictionaryType
        :param search_dictionary_entries_params: (required)
        :type search_dictionary_entries_params: SearchDictionaryEntriesParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if dictionary_name is None:
            raise ValueError(
                "Parameter `dictionary_name` is required when calling `search_dictionary_entries`."
            )

        if search_dictionary_entries_params is None:
            raise ValueError(
                "Parameter `search_dictionary_entries_params` is required when calling `search_dictionary_entries`."
            )

        _body = {}
        if search_dictionary_entries_params is not None:
            _body = search_dictionary_entries_params

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/dictionaries/{dictionaryName}/search".replace(
                "{dictionaryName}", quote(str(dictionary_name), safe="")
            ),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=True,
        )

    async def search_dictionary_entries(
        self,
        dictionary_name: Annotated[
            DictionaryType, Field(description="Dictionary to search in.")
        ],
        search_dictionary_entries_params: SearchDictionaryEntriesParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> UpdatedAtResponse:
        """
        Search dictionary entries.

        Search for standard and [custom](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-stop-words/) entries in the [stop words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-stop-words/), [plurals](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-plurals-and-other-declensions/), or [segmentation (compounds)](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-segmentation/) dictionaries.

        :param dictionary_name: Dictionary to search in. (required)
        :type dictionary_name: DictionaryType
        :param search_dictionary_entries_params: (required)
        :type search_dictionary_entries_params: SearchDictionaryEntriesParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'UpdatedAtResponse' result object.
        """
        return (
            await self.search_dictionary_entries_with_http_info(
                dictionary_name, search_dictionary_entries_params, request_options
            )
        ).deserialize(UpdatedAtResponse)

    async def search_for_facet_values_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        facet_name: Annotated[StrictStr, Field(description="Facet name.")],
        search_for_facet_values_request: Optional[SearchForFacetValuesRequest] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Search for facet values.

        [Search for a facet's values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values), optionally restricting the returned values to those contained in records matching other search criteria. > **Note**: Pagination isn't supported (`page` and `hitsPerPage` are ignored). By default, the engine returns a maximum of 10 values but you can adjust this with `maxFacetHits`.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param facet_name: Facet name. (required)
        :type facet_name: str
        :param search_for_facet_values_request:
        :type search_for_facet_values_request: SearchForFacetValuesRequest
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `search_for_facet_values`."
            )

        if facet_name is None:
            raise ValueError(
                "Parameter `facet_name` is required when calling `search_for_facet_values`."
            )

        _body = {}
        if search_for_facet_values_request is not None:
            _body = search_for_facet_values_request

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/{indexName}/facets/{facetName}/query".replace(
                "{indexName}", quote(str(index_name), safe="")
            ).replace("{facetName}", quote(str(facet_name), safe="")),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=True,
        )

    async def search_for_facet_values(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        facet_name: Annotated[StrictStr, Field(description="Facet name.")],
        search_for_facet_values_request: Optional[SearchForFacetValuesRequest] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> SearchForFacetValuesResponse:
        """
        Search for facet values.

        [Search for a facet's values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values), optionally restricting the returned values to those contained in records matching other search criteria. > **Note**: Pagination isn't supported (`page` and `hitsPerPage` are ignored). By default, the engine returns a maximum of 10 values but you can adjust this with `maxFacetHits`.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param facet_name: Facet name. (required)
        :type facet_name: str
        :param search_for_facet_values_request:
        :type search_for_facet_values_request: SearchForFacetValuesRequest
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'SearchForFacetValuesResponse' result object.
        """
        return (
            await self.search_for_facet_values_with_http_info(
                index_name, facet_name, search_for_facet_values_request, request_options
            )
        ).deserialize(SearchForFacetValuesResponse)

    async def search_rules_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        search_rules_params: Optional[SearchRulesParams] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Search for rules.

        Search for rules in your index. You can control the search with parameters. To list all rules, send an empty request body.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param search_rules_params:
        :type search_rules_params: SearchRulesParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `search_rules`."
            )

        _body = {}
        if search_rules_params is not None:
            _body = search_rules_params

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/{indexName}/rules/search".replace(
                "{indexName}", quote(str(index_name), safe="")
            ),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=True,
        )

    async def search_rules(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        search_rules_params: Optional[SearchRulesParams] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> SearchRulesResponse:
        """
        Search for rules.

        Search for rules in your index. You can control the search with parameters. To list all rules, send an empty request body.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param search_rules_params:
        :type search_rules_params: SearchRulesParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'SearchRulesResponse' result object.
        """
        return (
            await self.search_rules_with_http_info(
                index_name, search_rules_params, request_options
            )
        ).deserialize(SearchRulesResponse)

    async def search_single_index_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        search_params: Optional[SearchParams] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Search an index.

        Return records that match the query.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param search_params:
        :type search_params: SearchParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `search_single_index`."
            )

        _body = {}
        if search_params is not None:
            _body = search_params

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/{indexName}/query".replace(
                "{indexName}", quote(str(index_name), safe="")
            ),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=True,
        )

    async def search_single_index(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        search_params: Optional[SearchParams] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> SearchResponse:
        """
        Search an index.

        Return records that match the query.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param search_params:
        :type search_params: SearchParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'SearchResponse' result object.
        """
        return (
            await self.search_single_index_with_http_info(
                index_name, search_params, request_options
            )
        ).deserialize(SearchResponse)

    async def search_synonyms_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        type: Annotated[
            Optional[SynonymType],
            Field(
                description="Search for specific [types of synonyms](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/#the-different-types-of-synonyms)."
            ),
        ] = None,
        page: Annotated[
            Optional[Annotated[int, Field(strict=True, ge=0)]],
            Field(
                description="Returns the requested page number (the first page is 0). Page size is set by `hitsPerPage`. When null, there's no pagination. "
            ),
        ] = None,
        hits_per_page: Annotated[
            Optional[StrictInt], Field(description="Maximum number of hits per page.")
        ] = None,
        search_synonyms_params: Annotated[
            Optional[SearchSynonymsParams],
            Field(description="Body of the `searchSynonyms` operation."),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Search for synonyms.

        Search for synonyms in your index. You can control and filter the search with parameters. To get all synonyms, send an empty request body.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param type: Search for specific [types of synonyms](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/#the-different-types-of-synonyms).
        :type type: SynonymType
        :param page: Returns the requested page number (the first page is 0). Page size is set by `hitsPerPage`. When null, there's no pagination.
        :type page: int
        :param hits_per_page: Maximum number of hits per page.
        :type hits_per_page: int
        :param search_synonyms_params: Body of the `searchSynonyms` operation.
        :type search_synonyms_params: SearchSynonymsParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `search_synonyms`."
            )

        _query_parameters: List[Tuple[str, str]] = []

        if type is not None:
            _query_parameters.append(("type", type))
        if page is not None:
            _query_parameters.append(("page", page))
        if hits_per_page is not None:
            _query_parameters.append(("hitsPerPage", hits_per_page))

        _body = {}
        if search_synonyms_params is not None:
            _body = search_synonyms_params

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/indexes/{indexName}/synonyms/search".replace(
                "{indexName}", quote(str(index_name), safe="")
            ),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=True,
        )

    async def search_synonyms(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        type: Annotated[
            Optional[SynonymType],
            Field(
                description="Search for specific [types of synonyms](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/#the-different-types-of-synonyms)."
            ),
        ] = None,
        page: Annotated[
            Optional[Annotated[int, Field(strict=True, ge=0)]],
            Field(
                description="Returns the requested page number (the first page is 0). Page size is set by `hitsPerPage`. When null, there's no pagination. "
            ),
        ] = None,
        hits_per_page: Annotated[
            Optional[StrictInt], Field(description="Maximum number of hits per page.")
        ] = None,
        search_synonyms_params: Annotated[
            Optional[SearchSynonymsParams],
            Field(description="Body of the `searchSynonyms` operation."),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> SearchSynonymsResponse:
        """
        Search for synonyms.

        Search for synonyms in your index. You can control and filter the search with parameters. To get all synonyms, send an empty request body.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param type: Search for specific [types of synonyms](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/#the-different-types-of-synonyms).
        :type type: SynonymType
        :param page: Returns the requested page number (the first page is 0). Page size is set by `hitsPerPage`. When null, there's no pagination.
        :type page: int
        :param hits_per_page: Maximum number of hits per page.
        :type hits_per_page: int
        :param search_synonyms_params: Body of the `searchSynonyms` operation.
        :type search_synonyms_params: SearchSynonymsParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'SearchSynonymsResponse' result object.
        """
        return (
            await self.search_synonyms_with_http_info(
                index_name,
                type,
                page,
                hits_per_page,
                search_synonyms_params,
                request_options,
            )
        ).deserialize(SearchSynonymsResponse)

    async def search_user_ids_with_http_info(
        self,
        search_user_ids_params: SearchUserIdsParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Search for a user ID.

        Since it can take up to a few seconds to get the data from the different clusters, the response isn't real-time. To ensure rapid updates, the user IDs index isn't built at the same time as the mapping. Instead, it's built every 12 hours, at the same time as the update of user ID usage. For example, if you add or move a user ID, the search will show an old value until the next time the mapping is rebuilt (every 12 hours).

        :param search_user_ids_params: (required)
        :type search_user_ids_params: SearchUserIdsParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if search_user_ids_params is None:
            raise ValueError(
                "Parameter `search_user_ids_params` is required when calling `search_user_ids`."
            )

        _body = {}
        if search_user_ids_params is not None:
            _body = search_user_ids_params

        return await self._transporter.request(
            verb=Verb.POST,
            path="/1/clusters/mapping/search",
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=True,
        )

    async def search_user_ids(
        self,
        search_user_ids_params: SearchUserIdsParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> SearchUserIdsResponse:
        """
        Search for a user ID.

        Since it can take up to a few seconds to get the data from the different clusters, the response isn't real-time. To ensure rapid updates, the user IDs index isn't built at the same time as the mapping. Instead, it's built every 12 hours, at the same time as the update of user ID usage. For example, if you add or move a user ID, the search will show an old value until the next time the mapping is rebuilt (every 12 hours).

        :param search_user_ids_params: (required)
        :type search_user_ids_params: SearchUserIdsParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'SearchUserIdsResponse' result object.
        """
        return (
            await self.search_user_ids_with_http_info(
                search_user_ids_params, request_options
            )
        ).deserialize(SearchUserIdsResponse)

    async def set_dictionary_settings_with_http_info(
        self,
        dictionary_settings_params: DictionarySettingsParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Set stop word settings.

        Set stop word settings for a specific language.

        :param dictionary_settings_params: (required)
        :type dictionary_settings_params: DictionarySettingsParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if dictionary_settings_params is None:
            raise ValueError(
                "Parameter `dictionary_settings_params` is required when calling `set_dictionary_settings`."
            )

        _body = {}
        if dictionary_settings_params is not None:
            _body = dictionary_settings_params

        return await self._transporter.request(
            verb=Verb.PUT,
            path="/1/dictionaries/*/settings",
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def set_dictionary_settings(
        self,
        dictionary_settings_params: DictionarySettingsParams,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> UpdatedAtResponse:
        """
        Set stop word settings.

        Set stop word settings for a specific language.

        :param dictionary_settings_params: (required)
        :type dictionary_settings_params: DictionarySettingsParams
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'UpdatedAtResponse' result object.
        """
        return (
            await self.set_dictionary_settings_with_http_info(
                dictionary_settings_params, request_options
            )
        ).deserialize(UpdatedAtResponse)

    async def set_settings_with_http_info(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        index_settings: IndexSettings,
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Update index settings.

        Update the specified [index settings](https://www.algolia.com/doc/api-reference/settings-api-parameters/). Specifying null for a setting resets it to its default value.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param index_settings: (required)
        :type index_settings: IndexSettings
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if index_name is None:
            raise ValueError(
                "Parameter `index_name` is required when calling `set_settings`."
            )

        if index_settings is None:
            raise ValueError(
                "Parameter `index_settings` is required when calling `set_settings`."
            )

        _query_parameters: List[Tuple[str, str]] = []

        if forward_to_replicas is not None:
            _query_parameters.append(("forwardToReplicas", forward_to_replicas))

        _body = {}
        if index_settings is not None:
            _body = index_settings

        return await self._transporter.request(
            verb=Verb.PUT,
            path="/1/indexes/{indexName}/settings".replace(
                "{indexName}", quote(str(index_name), safe="")
            ),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                query_parameters=_query_parameters,
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def set_settings(
        self,
        index_name: Annotated[
            StrictStr, Field(description="Index on which to perform the request.")
        ],
        index_settings: IndexSettings,
        forward_to_replicas: Annotated[
            Optional[StrictBool],
            Field(
                description="Indicates whether changed index settings are forwarded to the replica indices."
            ),
        ] = None,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> UpdatedAtResponse:
        """
        Update index settings.

        Update the specified [index settings](https://www.algolia.com/doc/api-reference/settings-api-parameters/). Specifying null for a setting resets it to its default value.

        :param index_name: Index on which to perform the request. (required)
        :type index_name: str
        :param index_settings: (required)
        :type index_settings: IndexSettings
        :param forward_to_replicas: Indicates whether changed index settings are forwarded to the replica indices.
        :type forward_to_replicas: bool
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'UpdatedAtResponse' result object.
        """
        return (
            await self.set_settings_with_http_info(
                index_name, index_settings, forward_to_replicas, request_options
            )
        ).deserialize(UpdatedAtResponse)

    async def update_api_key_with_http_info(
        self,
        key: Annotated[StrictStr, Field(description="API key.")],
        api_key: ApiKey,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> ApiResponse[str]:
        """
        Update an API key.

        Replace the permissions of an existing API key. Any unspecified parameter resets that permission to its default value. The request must be authenticated with the admin API key.

        :param key: API key. (required)
        :type key: str
        :param api_key: (required)
        :type api_key: ApiKey
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the raw algoliasearch 'APIResponse' object.
        """

        if key is None:
            raise ValueError(
                "Parameter `key` is required when calling `update_api_key`."
            )

        if api_key is None:
            raise ValueError(
                "Parameter `api_key` is required when calling `update_api_key`."
            )

        _body = {}
        if api_key is not None:
            _body = api_key

        return await self._transporter.request(
            verb=Verb.PUT,
            path="/1/keys/{key}".replace("{key}", quote(str(key), safe="")),
            data=dumps(bodySerializer(_body)),
            request_options=self._request_options.merge(
                user_request_options=request_options,
            ),
            use_read_transporter=False,
        )

    async def update_api_key(
        self,
        key: Annotated[StrictStr, Field(description="API key.")],
        api_key: ApiKey,
        request_options: Optional[Union[dict, RequestOptions]] = None,
    ) -> UpdateApiKeyResponse:
        """
        Update an API key.

        Replace the permissions of an existing API key. Any unspecified parameter resets that permission to its default value. The request must be authenticated with the admin API key.

        :param key: API key. (required)
        :type key: str
        :param api_key: (required)
        :type api_key: ApiKey
        :param request_options: The request options to send along with the query, they will be merged with the transporter base parameters (headers, query params, timeouts, etc.). (optional)
        :return: Returns the deserialized response in a 'UpdateApiKeyResponse' result object.
        """
        return (
            await self.update_api_key_with_http_info(key, api_key, request_options)
        ).deserialize(UpdateApiKeyResponse)
