# pylint: disable=line-too-long,useless-suppression,too-many-lines
# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# Code generated by Microsoft (R) Python Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------
from collections.abc import MutableMapping
from io import IOBase
import json
from typing import Any, AsyncIterable, Callable, Dict, IO, List, Optional, TypeVar, Union, overload
import urllib.parse

from azure.core import AsyncPipelineClient
from azure.core.async_paging import AsyncItemPaged, AsyncList
from azure.core.exceptions import (
    ClientAuthenticationError,
    HttpResponseError,
    ResourceExistsError,
    ResourceNotFoundError,
    ResourceNotModifiedError,
    StreamClosedError,
    StreamConsumedError,
    map_error,
)
from azure.core.pipeline import PipelineResponse
from azure.core.rest import AsyncHttpResponse, HttpRequest
from azure.core.tracing.decorator import distributed_trace
from azure.core.tracing.decorator_async import distributed_trace_async
from azure.core.utils import case_insensitive_dict

from ... import models as _models
from ..._operations._operations import (
    build_key_vault_backup_key_request,
    build_key_vault_create_key_request,
    build_key_vault_decrypt_request,
    build_key_vault_delete_key_request,
    build_key_vault_encrypt_request,
    build_key_vault_get_deleted_key_request,
    build_key_vault_get_deleted_keys_request,
    build_key_vault_get_key_attestation_request,
    build_key_vault_get_key_request,
    build_key_vault_get_key_rotation_policy_request,
    build_key_vault_get_key_versions_request,
    build_key_vault_get_keys_request,
    build_key_vault_get_random_bytes_request,
    build_key_vault_import_key_request,
    build_key_vault_purge_deleted_key_request,
    build_key_vault_recover_deleted_key_request,
    build_key_vault_release_request,
    build_key_vault_restore_key_request,
    build_key_vault_rotate_key_request,
    build_key_vault_sign_request,
    build_key_vault_unwrap_key_request,
    build_key_vault_update_key_request,
    build_key_vault_update_key_rotation_policy_request,
    build_key_vault_verify_request,
    build_key_vault_wrap_key_request,
)
from ..._utils.model_base import SdkJSONEncoder, _deserialize, _failsafe_deserialize
from ..._utils.utils import ClientMixinABC
from ..._validation import api_version_validation
from .._configuration import KeyVaultClientConfiguration

JSON = MutableMapping[str, Any]
T = TypeVar("T")
ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]]


class KeyVaultClientOperationsMixin(  # pylint: disable=too-many-public-methods
    ClientMixinABC[AsyncPipelineClient[HttpRequest, AsyncHttpResponse], KeyVaultClientConfiguration]
):

    @overload
    async def create_key(
        self,
        key_name: str,
        parameters: _models.KeyCreateParameters,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyBundle:
        """Creates a new key, stores it, then returns key parameters and attributes to the client.

        The create key operation can be used to create any key type in Azure Key Vault. If the named
        key already exists, Azure Key Vault creates a new version of the key. It requires the
        keys/create permission.

        :param key_name: The name for the new key. The system will generate the version name for the
         new key. The value you provide may be copied globally for the purpose of running the service.
         The value provided should not include personally identifiable or sensitive information.
         Required.
        :type key_name: str
        :param parameters: The parameters to create a key. Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyCreateParameters
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def create_key(
        self, key_name: str, parameters: JSON, *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.KeyBundle:
        """Creates a new key, stores it, then returns key parameters and attributes to the client.

        The create key operation can be used to create any key type in Azure Key Vault. If the named
        key already exists, Azure Key Vault creates a new version of the key. It requires the
        keys/create permission.

        :param key_name: The name for the new key. The system will generate the version name for the
         new key. The value you provide may be copied globally for the purpose of running the service.
         The value provided should not include personally identifiable or sensitive information.
         Required.
        :type key_name: str
        :param parameters: The parameters to create a key. Required.
        :type parameters: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def create_key(
        self, key_name: str, parameters: IO[bytes], *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.KeyBundle:
        """Creates a new key, stores it, then returns key parameters and attributes to the client.

        The create key operation can be used to create any key type in Azure Key Vault. If the named
        key already exists, Azure Key Vault creates a new version of the key. It requires the
        keys/create permission.

        :param key_name: The name for the new key. The system will generate the version name for the
         new key. The value you provide may be copied globally for the purpose of running the service.
         The value provided should not include personally identifiable or sensitive information.
         Required.
        :type key_name: str
        :param parameters: The parameters to create a key. Required.
        :type parameters: IO[bytes]
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def create_key(
        self, key_name: str, parameters: Union[_models.KeyCreateParameters, JSON, IO[bytes]], **kwargs: Any
    ) -> _models.KeyBundle:
        """Creates a new key, stores it, then returns key parameters and attributes to the client.

        The create key operation can be used to create any key type in Azure Key Vault. If the named
        key already exists, Azure Key Vault creates a new version of the key. It requires the
        keys/create permission.

        :param key_name: The name for the new key. The system will generate the version name for the
         new key. The value you provide may be copied globally for the purpose of running the service.
         The value provided should not include personally identifiable or sensitive information.
         Required.
        :type key_name: str
        :param parameters: The parameters to create a key. Is one of the following types:
         KeyCreateParameters, JSON, IO[bytes] Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyCreateParameters or JSON or
         IO[bytes]
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.KeyBundle] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_key_vault_create_key_request(
            key_name=key_name,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyBundle, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @distributed_trace_async
    async def rotate_key(self, key_name: str, **kwargs: Any) -> _models.KeyBundle:
        """Creates a new key version, stores it, then returns key parameters, attributes and policy to the
        client.

        The operation will rotate the key based on the key policy. It requires the keys/rotate
        permission.

        :param key_name: The name of key to be rotated. The system will generate a new version in the
         specified key. Required.
        :type key_name: str
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = kwargs.pop("headers", {}) or {}
        _params = kwargs.pop("params", {}) or {}

        cls: ClsType[_models.KeyBundle] = kwargs.pop("cls", None)

        _request = build_key_vault_rotate_key_request(
            key_name=key_name,
            api_version=self._config.api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyBundle, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @overload
    async def import_key(
        self,
        key_name: str,
        parameters: _models.KeyImportParameters,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyBundle:
        """Imports an externally created key, stores it, and returns key parameters and attributes to the
        client.

        The import key operation may be used to import any key type into an Azure Key Vault. If the
        named key already exists, Azure Key Vault creates a new version of the key. This operation
        requires the keys/import permission.

        :param key_name: Name for the imported key. The value you provide may be copied globally for
         the purpose of running the service. The value provided should not include personally
         identifiable or sensitive information. Required.
        :type key_name: str
        :param parameters: The parameters to import a key. Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyImportParameters
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def import_key(
        self, key_name: str, parameters: JSON, *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.KeyBundle:
        """Imports an externally created key, stores it, and returns key parameters and attributes to the
        client.

        The import key operation may be used to import any key type into an Azure Key Vault. If the
        named key already exists, Azure Key Vault creates a new version of the key. This operation
        requires the keys/import permission.

        :param key_name: Name for the imported key. The value you provide may be copied globally for
         the purpose of running the service. The value provided should not include personally
         identifiable or sensitive information. Required.
        :type key_name: str
        :param parameters: The parameters to import a key. Required.
        :type parameters: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def import_key(
        self, key_name: str, parameters: IO[bytes], *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.KeyBundle:
        """Imports an externally created key, stores it, and returns key parameters and attributes to the
        client.

        The import key operation may be used to import any key type into an Azure Key Vault. If the
        named key already exists, Azure Key Vault creates a new version of the key. This operation
        requires the keys/import permission.

        :param key_name: Name for the imported key. The value you provide may be copied globally for
         the purpose of running the service. The value provided should not include personally
         identifiable or sensitive information. Required.
        :type key_name: str
        :param parameters: The parameters to import a key. Required.
        :type parameters: IO[bytes]
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def import_key(
        self, key_name: str, parameters: Union[_models.KeyImportParameters, JSON, IO[bytes]], **kwargs: Any
    ) -> _models.KeyBundle:
        """Imports an externally created key, stores it, and returns key parameters and attributes to the
        client.

        The import key operation may be used to import any key type into an Azure Key Vault. If the
        named key already exists, Azure Key Vault creates a new version of the key. This operation
        requires the keys/import permission.

        :param key_name: Name for the imported key. The value you provide may be copied globally for
         the purpose of running the service. The value provided should not include personally
         identifiable or sensitive information. Required.
        :type key_name: str
        :param parameters: The parameters to import a key. Is one of the following types:
         KeyImportParameters, JSON, IO[bytes] Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyImportParameters or JSON or
         IO[bytes]
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.KeyBundle] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_key_vault_import_key_request(
            key_name=key_name,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyBundle, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @distributed_trace_async
    async def delete_key(self, key_name: str, **kwargs: Any) -> _models.DeletedKeyBundle:
        """Deletes a key of any type from storage in Azure Key Vault.

        The delete key operation cannot be used to remove individual versions of a key. This operation
        removes the cryptographic material associated with the key, which means the key is not usable
        for Sign/Verify, Wrap/Unwrap or Encrypt/Decrypt operations. This operation requires the
        keys/delete permission.

        :param key_name: The name of the key to delete. Required.
        :type key_name: str
        :return: DeletedKeyBundle. The DeletedKeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.DeletedKeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = kwargs.pop("headers", {}) or {}
        _params = kwargs.pop("params", {}) or {}

        cls: ClsType[_models.DeletedKeyBundle] = kwargs.pop("cls", None)

        _request = build_key_vault_delete_key_request(
            key_name=key_name,
            api_version=self._config.api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.DeletedKeyBundle, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @overload
    async def update_key(
        self,
        key_name: str,
        key_version: str,
        parameters: _models.KeyUpdateParameters,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyBundle:
        """The update key operation changes specified attributes of a stored key and can be applied to any
        key type and key version stored in Azure Key Vault.

        In order to perform this operation, the key must already exist in the Key Vault. Note: The
        cryptographic material of a key itself cannot be changed. This operation requires the
        keys/update permission.

        :param key_name: The name of key to update. Required.
        :type key_name: str
        :param key_version: The version of the key to update. Required.
        :type key_version: str
        :param parameters: The parameters of the key to update. Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyUpdateParameters
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def update_key(
        self,
        key_name: str,
        key_version: str,
        parameters: JSON,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyBundle:
        """The update key operation changes specified attributes of a stored key and can be applied to any
        key type and key version stored in Azure Key Vault.

        In order to perform this operation, the key must already exist in the Key Vault. Note: The
        cryptographic material of a key itself cannot be changed. This operation requires the
        keys/update permission.

        :param key_name: The name of key to update. Required.
        :type key_name: str
        :param key_version: The version of the key to update. Required.
        :type key_version: str
        :param parameters: The parameters of the key to update. Required.
        :type parameters: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def update_key(
        self,
        key_name: str,
        key_version: str,
        parameters: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyBundle:
        """The update key operation changes specified attributes of a stored key and can be applied to any
        key type and key version stored in Azure Key Vault.

        In order to perform this operation, the key must already exist in the Key Vault. Note: The
        cryptographic material of a key itself cannot be changed. This operation requires the
        keys/update permission.

        :param key_name: The name of key to update. Required.
        :type key_name: str
        :param key_version: The version of the key to update. Required.
        :type key_version: str
        :param parameters: The parameters of the key to update. Required.
        :type parameters: IO[bytes]
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def update_key(
        self,
        key_name: str,
        key_version: str,
        parameters: Union[_models.KeyUpdateParameters, JSON, IO[bytes]],
        **kwargs: Any
    ) -> _models.KeyBundle:
        """The update key operation changes specified attributes of a stored key and can be applied to any
        key type and key version stored in Azure Key Vault.

        In order to perform this operation, the key must already exist in the Key Vault. Note: The
        cryptographic material of a key itself cannot be changed. This operation requires the
        keys/update permission.

        :param key_name: The name of key to update. Required.
        :type key_name: str
        :param key_version: The version of the key to update. Required.
        :type key_version: str
        :param parameters: The parameters of the key to update. Is one of the following types:
         KeyUpdateParameters, JSON, IO[bytes] Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyUpdateParameters or JSON or
         IO[bytes]
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.KeyBundle] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_key_vault_update_key_request(
            key_name=key_name,
            key_version=key_version,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyBundle, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @distributed_trace_async
    async def get_key(self, key_name: str, key_version: str, **kwargs: Any) -> _models.KeyBundle:
        """Gets the public part of a stored key.

        The get key operation is applicable to all key types. If the requested key is symmetric, then
        no key material is released in the response. This operation requires the keys/get permission.

        :param key_name: The name of the key to get. Required.
        :type key_name: str
        :param key_version: Adding the version parameter retrieves a specific version of a key. This
         URI fragment is optional. If not specified, the latest version of the key is returned.
         Required.
        :type key_version: str
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = kwargs.pop("headers", {}) or {}
        _params = kwargs.pop("params", {}) or {}

        cls: ClsType[_models.KeyBundle] = kwargs.pop("cls", None)

        _request = build_key_vault_get_key_request(
            key_name=key_name,
            key_version=key_version,
            api_version=self._config.api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyBundle, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @distributed_trace
    def get_key_versions(
        self, key_name: str, *, maxresults: Optional[int] = None, **kwargs: Any
    ) -> AsyncIterable["_models.KeyItem"]:
        """Retrieves a list of individual key versions with the same key name.

        The full key identifier, attributes, and tags are provided in the response. This operation
        requires the keys/list permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :keyword maxresults: Maximum number of results to return in a page. If not specified the
         service will return up to 25 results. Default value is None.
        :paramtype maxresults: int
        :return: An iterator like instance of KeyItem
        :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.keys._generated.models.KeyItem]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = kwargs.pop("params", {}) or {}

        cls: ClsType[List[_models.KeyItem]] = kwargs.pop("cls", None)

        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        def prepare_request(next_link=None):
            if not next_link:

                _request = build_key_vault_get_key_versions_request(
                    key_name=key_name,
                    maxresults=maxresults,
                    api_version=self._config.api_version,
                    headers=_headers,
                    params=_params,
                )
                path_format_arguments = {
                    "vaultBaseUrl": self._serialize.url(
                        "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
                    ),
                }
                _request.url = self._client.format_url(_request.url, **path_format_arguments)

            else:
                # make call to next link with the client's api-version
                _parsed_next_link = urllib.parse.urlparse(next_link)
                _next_request_params = case_insensitive_dict(
                    {
                        key: [urllib.parse.quote(v) for v in value]
                        for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items()
                    }
                )
                _next_request_params["api-version"] = self._config.api_version
                _request = HttpRequest(
                    "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
                )
                path_format_arguments = {
                    "vaultBaseUrl": self._serialize.url(
                        "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
                    ),
                }
                _request.url = self._client.format_url(_request.url, **path_format_arguments)

            return _request

        async def extract_data(pipeline_response):
            deserialized = pipeline_response.http_response.json()
            list_of_elem = _deserialize(List[_models.KeyItem], deserialized.get("value", []))
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.get("nextLink") or None, AsyncList(list_of_elem)

        async def get_next(next_link=None):
            _request = prepare_request(next_link)

            _stream = False
            pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
                _request, stream=_stream, **kwargs
            )
            response = pipeline_response.http_response

            if response.status_code not in [200]:
                map_error(status_code=response.status_code, response=response, error_map=error_map)
                error = _failsafe_deserialize(_models.KeyVaultError, response.json())
                raise HttpResponseError(response=response, model=error)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)

    @distributed_trace
    def get_keys(self, *, maxresults: Optional[int] = None, **kwargs: Any) -> AsyncIterable["_models.KeyItem"]:
        """List keys in the specified vault.

        Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the
        public part of a stored key. The LIST operation is applicable to all key types, however only
        the base key identifier, attributes, and tags are provided in the response. Individual versions
        of a key are not listed in the response. This operation requires the keys/list permission.

        :keyword maxresults: Maximum number of results to return in a page. If not specified the
         service will return up to 25 results. Default value is None.
        :paramtype maxresults: int
        :return: An iterator like instance of KeyItem
        :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.keys._generated.models.KeyItem]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = kwargs.pop("params", {}) or {}

        cls: ClsType[List[_models.KeyItem]] = kwargs.pop("cls", None)

        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        def prepare_request(next_link=None):
            if not next_link:

                _request = build_key_vault_get_keys_request(
                    maxresults=maxresults,
                    api_version=self._config.api_version,
                    headers=_headers,
                    params=_params,
                )
                path_format_arguments = {
                    "vaultBaseUrl": self._serialize.url(
                        "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
                    ),
                }
                _request.url = self._client.format_url(_request.url, **path_format_arguments)

            else:
                # make call to next link with the client's api-version
                _parsed_next_link = urllib.parse.urlparse(next_link)
                _next_request_params = case_insensitive_dict(
                    {
                        key: [urllib.parse.quote(v) for v in value]
                        for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items()
                    }
                )
                _next_request_params["api-version"] = self._config.api_version
                _request = HttpRequest(
                    "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
                )
                path_format_arguments = {
                    "vaultBaseUrl": self._serialize.url(
                        "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
                    ),
                }
                _request.url = self._client.format_url(_request.url, **path_format_arguments)

            return _request

        async def extract_data(pipeline_response):
            deserialized = pipeline_response.http_response.json()
            list_of_elem = _deserialize(List[_models.KeyItem], deserialized.get("value", []))
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.get("nextLink") or None, AsyncList(list_of_elem)

        async def get_next(next_link=None):
            _request = prepare_request(next_link)

            _stream = False
            pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
                _request, stream=_stream, **kwargs
            )
            response = pipeline_response.http_response

            if response.status_code not in [200]:
                map_error(status_code=response.status_code, response=response, error_map=error_map)
                error = _failsafe_deserialize(_models.KeyVaultError, response.json())
                raise HttpResponseError(response=response, model=error)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)

    @distributed_trace_async
    async def backup_key(self, key_name: str, **kwargs: Any) -> _models.BackupKeyResult:
        """Requests that a backup of the specified key be downloaded to the client.

        The Key Backup operation exports a key from Azure Key Vault in a protected form. Note that this
        operation does NOT return key material in a form that can be used outside the Azure Key Vault
        system, the returned key material is either protected to a Azure Key Vault HSM or to Azure Key
        Vault itself. The intent of this operation is to allow a client to GENERATE a key in one Azure
        Key Vault instance, BACKUP the key, and then RESTORE it into another Azure Key Vault instance.
        The BACKUP operation may be used to export, in protected form, any key type from Azure Key
        Vault. Individual versions of a key cannot be backed up. BACKUP / RESTORE can be performed
        within geographical boundaries only; meaning that a BACKUP from one geographical area cannot be
        restored to another geographical area. For example, a backup from the US geographical area
        cannot be restored in an EU geographical area. This operation requires the key/backup
        permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :return: BackupKeyResult. The BackupKeyResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.BackupKeyResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = kwargs.pop("headers", {}) or {}
        _params = kwargs.pop("params", {}) or {}

        cls: ClsType[_models.BackupKeyResult] = kwargs.pop("cls", None)

        _request = build_key_vault_backup_key_request(
            key_name=key_name,
            api_version=self._config.api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.BackupKeyResult, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @overload
    async def restore_key(
        self, parameters: _models.KeyRestoreParameters, *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.KeyBundle:
        """Restores a backed up key to a vault.

        Imports a previously backed up key into Azure Key Vault, restoring the key, its key identifier,
        attributes and access control policies. The RESTORE operation may be used to import a
        previously backed up key. Individual versions of a key cannot be restored. The key is restored
        in its entirety with the same key name as it had when it was backed up. If the key name is not
        available in the target Key Vault, the RESTORE operation will be rejected. While the key name
        is retained during restore, the final key identifier will change if the key is restored to a
        different vault. Restore will restore all versions and preserve version identifiers. The
        RESTORE operation is subject to security constraints: The target Key Vault must be owned by the
        same Microsoft Azure Subscription as the source Key Vault The user must have RESTORE permission
        in the target Key Vault. This operation requires the keys/restore permission.

        :param parameters: The parameters to restore the key. Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyRestoreParameters
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def restore_key(
        self, parameters: JSON, *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.KeyBundle:
        """Restores a backed up key to a vault.

        Imports a previously backed up key into Azure Key Vault, restoring the key, its key identifier,
        attributes and access control policies. The RESTORE operation may be used to import a
        previously backed up key. Individual versions of a key cannot be restored. The key is restored
        in its entirety with the same key name as it had when it was backed up. If the key name is not
        available in the target Key Vault, the RESTORE operation will be rejected. While the key name
        is retained during restore, the final key identifier will change if the key is restored to a
        different vault. Restore will restore all versions and preserve version identifiers. The
        RESTORE operation is subject to security constraints: The target Key Vault must be owned by the
        same Microsoft Azure Subscription as the source Key Vault The user must have RESTORE permission
        in the target Key Vault. This operation requires the keys/restore permission.

        :param parameters: The parameters to restore the key. Required.
        :type parameters: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def restore_key(
        self, parameters: IO[bytes], *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.KeyBundle:
        """Restores a backed up key to a vault.

        Imports a previously backed up key into Azure Key Vault, restoring the key, its key identifier,
        attributes and access control policies. The RESTORE operation may be used to import a
        previously backed up key. Individual versions of a key cannot be restored. The key is restored
        in its entirety with the same key name as it had when it was backed up. If the key name is not
        available in the target Key Vault, the RESTORE operation will be rejected. While the key name
        is retained during restore, the final key identifier will change if the key is restored to a
        different vault. Restore will restore all versions and preserve version identifiers. The
        RESTORE operation is subject to security constraints: The target Key Vault must be owned by the
        same Microsoft Azure Subscription as the source Key Vault The user must have RESTORE permission
        in the target Key Vault. This operation requires the keys/restore permission.

        :param parameters: The parameters to restore the key. Required.
        :type parameters: IO[bytes]
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def restore_key(
        self, parameters: Union[_models.KeyRestoreParameters, JSON, IO[bytes]], **kwargs: Any
    ) -> _models.KeyBundle:
        """Restores a backed up key to a vault.

        Imports a previously backed up key into Azure Key Vault, restoring the key, its key identifier,
        attributes and access control policies. The RESTORE operation may be used to import a
        previously backed up key. Individual versions of a key cannot be restored. The key is restored
        in its entirety with the same key name as it had when it was backed up. If the key name is not
        available in the target Key Vault, the RESTORE operation will be rejected. While the key name
        is retained during restore, the final key identifier will change if the key is restored to a
        different vault. Restore will restore all versions and preserve version identifiers. The
        RESTORE operation is subject to security constraints: The target Key Vault must be owned by the
        same Microsoft Azure Subscription as the source Key Vault The user must have RESTORE permission
        in the target Key Vault. This operation requires the keys/restore permission.

        :param parameters: The parameters to restore the key. Is one of the following types:
         KeyRestoreParameters, JSON, IO[bytes] Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyRestoreParameters or JSON or
         IO[bytes]
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.KeyBundle] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_key_vault_restore_key_request(
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyBundle, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @overload
    async def encrypt(
        self,
        key_name: str,
        key_version: str,
        parameters: _models.KeyOperationsParameters,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Encrypts an arbitrary sequence of bytes using an encryption key that is stored in a key vault.

        The ENCRYPT operation encrypts an arbitrary sequence of bytes using an encryption key that is
        stored in Azure Key Vault. Note that the ENCRYPT operation only supports a single block of
        data, the size of which is dependent on the target key and the encryption algorithm to be used.
        The ENCRYPT operation is only strictly necessary for symmetric keys stored in Azure Key Vault
        since protection with an asymmetric key can be performed using public portion of the key. This
        operation is supported for asymmetric keys as a convenience for callers that have a
        key-reference but do not have access to the public key material. This operation requires the
        keys/encrypt permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for the encryption operation. Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def encrypt(
        self,
        key_name: str,
        key_version: str,
        parameters: JSON,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Encrypts an arbitrary sequence of bytes using an encryption key that is stored in a key vault.

        The ENCRYPT operation encrypts an arbitrary sequence of bytes using an encryption key that is
        stored in Azure Key Vault. Note that the ENCRYPT operation only supports a single block of
        data, the size of which is dependent on the target key and the encryption algorithm to be used.
        The ENCRYPT operation is only strictly necessary for symmetric keys stored in Azure Key Vault
        since protection with an asymmetric key can be performed using public portion of the key. This
        operation is supported for asymmetric keys as a convenience for callers that have a
        key-reference but do not have access to the public key material. This operation requires the
        keys/encrypt permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for the encryption operation. Required.
        :type parameters: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def encrypt(
        self,
        key_name: str,
        key_version: str,
        parameters: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Encrypts an arbitrary sequence of bytes using an encryption key that is stored in a key vault.

        The ENCRYPT operation encrypts an arbitrary sequence of bytes using an encryption key that is
        stored in Azure Key Vault. Note that the ENCRYPT operation only supports a single block of
        data, the size of which is dependent on the target key and the encryption algorithm to be used.
        The ENCRYPT operation is only strictly necessary for symmetric keys stored in Azure Key Vault
        since protection with an asymmetric key can be performed using public portion of the key. This
        operation is supported for asymmetric keys as a convenience for callers that have a
        key-reference but do not have access to the public key material. This operation requires the
        keys/encrypt permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for the encryption operation. Required.
        :type parameters: IO[bytes]
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def encrypt(
        self,
        key_name: str,
        key_version: str,
        parameters: Union[_models.KeyOperationsParameters, JSON, IO[bytes]],
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Encrypts an arbitrary sequence of bytes using an encryption key that is stored in a key vault.

        The ENCRYPT operation encrypts an arbitrary sequence of bytes using an encryption key that is
        stored in Azure Key Vault. Note that the ENCRYPT operation only supports a single block of
        data, the size of which is dependent on the target key and the encryption algorithm to be used.
        The ENCRYPT operation is only strictly necessary for symmetric keys stored in Azure Key Vault
        since protection with an asymmetric key can be performed using public portion of the key. This
        operation is supported for asymmetric keys as a convenience for callers that have a
        key-reference but do not have access to the public key material. This operation requires the
        keys/encrypt permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for the encryption operation. Is one of the following types:
         KeyOperationsParameters, JSON, IO[bytes] Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters or JSON or
         IO[bytes]
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.KeyOperationResult] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_key_vault_encrypt_request(
            key_name=key_name,
            key_version=key_version,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyOperationResult, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @overload
    async def decrypt(
        self,
        key_name: str,
        key_version: str,
        parameters: _models.KeyOperationsParameters,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Decrypts a single block of encrypted data.

        The DECRYPT operation decrypts a well-formed block of ciphertext using the target encryption
        key and specified algorithm. This operation is the reverse of the ENCRYPT operation; only a
        single block of data may be decrypted, the size of this block is dependent on the target key
        and the algorithm to be used. The DECRYPT operation applies to asymmetric and symmetric keys
        stored in Azure Key Vault since it uses the private portion of the key. This operation requires
        the keys/decrypt permission. Microsoft recommends not to use CBC algorithms for decryption
        without first ensuring the integrity of the ciphertext using an HMAC, for example. See
        `https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode
        <https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode>`_ for more
        information.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for the decryption operation. Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def decrypt(
        self,
        key_name: str,
        key_version: str,
        parameters: JSON,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Decrypts a single block of encrypted data.

        The DECRYPT operation decrypts a well-formed block of ciphertext using the target encryption
        key and specified algorithm. This operation is the reverse of the ENCRYPT operation; only a
        single block of data may be decrypted, the size of this block is dependent on the target key
        and the algorithm to be used. The DECRYPT operation applies to asymmetric and symmetric keys
        stored in Azure Key Vault since it uses the private portion of the key. This operation requires
        the keys/decrypt permission. Microsoft recommends not to use CBC algorithms for decryption
        without first ensuring the integrity of the ciphertext using an HMAC, for example. See
        `https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode
        <https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode>`_ for more
        information.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for the decryption operation. Required.
        :type parameters: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def decrypt(
        self,
        key_name: str,
        key_version: str,
        parameters: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Decrypts a single block of encrypted data.

        The DECRYPT operation decrypts a well-formed block of ciphertext using the target encryption
        key and specified algorithm. This operation is the reverse of the ENCRYPT operation; only a
        single block of data may be decrypted, the size of this block is dependent on the target key
        and the algorithm to be used. The DECRYPT operation applies to asymmetric and symmetric keys
        stored in Azure Key Vault since it uses the private portion of the key. This operation requires
        the keys/decrypt permission. Microsoft recommends not to use CBC algorithms for decryption
        without first ensuring the integrity of the ciphertext using an HMAC, for example. See
        `https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode
        <https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode>`_ for more
        information.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for the decryption operation. Required.
        :type parameters: IO[bytes]
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def decrypt(
        self,
        key_name: str,
        key_version: str,
        parameters: Union[_models.KeyOperationsParameters, JSON, IO[bytes]],
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Decrypts a single block of encrypted data.

        The DECRYPT operation decrypts a well-formed block of ciphertext using the target encryption
        key and specified algorithm. This operation is the reverse of the ENCRYPT operation; only a
        single block of data may be decrypted, the size of this block is dependent on the target key
        and the algorithm to be used. The DECRYPT operation applies to asymmetric and symmetric keys
        stored in Azure Key Vault since it uses the private portion of the key. This operation requires
        the keys/decrypt permission. Microsoft recommends not to use CBC algorithms for decryption
        without first ensuring the integrity of the ciphertext using an HMAC, for example. See
        `https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode
        <https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode>`_ for more
        information.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for the decryption operation. Is one of the following types:
         KeyOperationsParameters, JSON, IO[bytes] Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters or JSON or
         IO[bytes]
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.KeyOperationResult] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_key_vault_decrypt_request(
            key_name=key_name,
            key_version=key_version,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyOperationResult, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @overload
    async def sign(
        self,
        key_name: str,
        key_version: str,
        parameters: _models.KeySignParameters,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Creates a signature from a digest using the specified key.

        The SIGN operation is applicable to asymmetric and symmetric keys stored in Azure Key Vault
        since this operation uses the private portion of the key. This operation requires the keys/sign
        permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for the signing operation. Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeySignParameters
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def sign(
        self,
        key_name: str,
        key_version: str,
        parameters: JSON,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Creates a signature from a digest using the specified key.

        The SIGN operation is applicable to asymmetric and symmetric keys stored in Azure Key Vault
        since this operation uses the private portion of the key. This operation requires the keys/sign
        permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for the signing operation. Required.
        :type parameters: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def sign(
        self,
        key_name: str,
        key_version: str,
        parameters: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Creates a signature from a digest using the specified key.

        The SIGN operation is applicable to asymmetric and symmetric keys stored in Azure Key Vault
        since this operation uses the private portion of the key. This operation requires the keys/sign
        permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for the signing operation. Required.
        :type parameters: IO[bytes]
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def sign(
        self,
        key_name: str,
        key_version: str,
        parameters: Union[_models.KeySignParameters, JSON, IO[bytes]],
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Creates a signature from a digest using the specified key.

        The SIGN operation is applicable to asymmetric and symmetric keys stored in Azure Key Vault
        since this operation uses the private portion of the key. This operation requires the keys/sign
        permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for the signing operation. Is one of the following types:
         KeySignParameters, JSON, IO[bytes] Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeySignParameters or JSON or IO[bytes]
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.KeyOperationResult] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_key_vault_sign_request(
            key_name=key_name,
            key_version=key_version,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyOperationResult, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @overload
    async def verify(
        self,
        key_name: str,
        key_version: str,
        parameters: _models.KeyVerifyParameters,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyVerifyResult:
        """Verifies a signature using a specified key.

        The VERIFY operation is applicable to symmetric keys stored in Azure Key Vault. VERIFY is not
        strictly necessary for asymmetric keys stored in Azure Key Vault since signature verification
        can be performed using the public portion of the key but this operation is supported as a
        convenience for callers that only have a key-reference and not the public portion of the key.
        This operation requires the keys/verify permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for verify operations. Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyVerifyParameters
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyVerifyResult. The KeyVerifyResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyVerifyResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def verify(
        self,
        key_name: str,
        key_version: str,
        parameters: JSON,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyVerifyResult:
        """Verifies a signature using a specified key.

        The VERIFY operation is applicable to symmetric keys stored in Azure Key Vault. VERIFY is not
        strictly necessary for asymmetric keys stored in Azure Key Vault since signature verification
        can be performed using the public portion of the key but this operation is supported as a
        convenience for callers that only have a key-reference and not the public portion of the key.
        This operation requires the keys/verify permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for verify operations. Required.
        :type parameters: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyVerifyResult. The KeyVerifyResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyVerifyResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def verify(
        self,
        key_name: str,
        key_version: str,
        parameters: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyVerifyResult:
        """Verifies a signature using a specified key.

        The VERIFY operation is applicable to symmetric keys stored in Azure Key Vault. VERIFY is not
        strictly necessary for asymmetric keys stored in Azure Key Vault since signature verification
        can be performed using the public portion of the key but this operation is supported as a
        convenience for callers that only have a key-reference and not the public portion of the key.
        This operation requires the keys/verify permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for verify operations. Required.
        :type parameters: IO[bytes]
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyVerifyResult. The KeyVerifyResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyVerifyResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def verify(
        self,
        key_name: str,
        key_version: str,
        parameters: Union[_models.KeyVerifyParameters, JSON, IO[bytes]],
        **kwargs: Any
    ) -> _models.KeyVerifyResult:
        """Verifies a signature using a specified key.

        The VERIFY operation is applicable to symmetric keys stored in Azure Key Vault. VERIFY is not
        strictly necessary for asymmetric keys stored in Azure Key Vault since signature verification
        can be performed using the public portion of the key but this operation is supported as a
        convenience for callers that only have a key-reference and not the public portion of the key.
        This operation requires the keys/verify permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for verify operations. Is one of the following types:
         KeyVerifyParameters, JSON, IO[bytes] Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyVerifyParameters or JSON or
         IO[bytes]
        :return: KeyVerifyResult. The KeyVerifyResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyVerifyResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.KeyVerifyResult] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_key_vault_verify_request(
            key_name=key_name,
            key_version=key_version,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyVerifyResult, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @overload
    async def wrap_key(
        self,
        key_name: str,
        key_version: str,
        parameters: _models.KeyOperationsParameters,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Wraps a symmetric key using a specified key.

        The WRAP operation supports encryption of a symmetric key using a key encryption key that has
        previously been stored in an Azure Key Vault. The WRAP operation is only strictly necessary for
        symmetric keys stored in Azure Key Vault since protection with an asymmetric key can be
        performed using the public portion of the key. This operation is supported for asymmetric keys
        as a convenience for callers that have a key-reference but do not have access to the public key
        material. This operation requires the keys/wrapKey permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for wrap operation. Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def wrap_key(
        self,
        key_name: str,
        key_version: str,
        parameters: JSON,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Wraps a symmetric key using a specified key.

        The WRAP operation supports encryption of a symmetric key using a key encryption key that has
        previously been stored in an Azure Key Vault. The WRAP operation is only strictly necessary for
        symmetric keys stored in Azure Key Vault since protection with an asymmetric key can be
        performed using the public portion of the key. This operation is supported for asymmetric keys
        as a convenience for callers that have a key-reference but do not have access to the public key
        material. This operation requires the keys/wrapKey permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for wrap operation. Required.
        :type parameters: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def wrap_key(
        self,
        key_name: str,
        key_version: str,
        parameters: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Wraps a symmetric key using a specified key.

        The WRAP operation supports encryption of a symmetric key using a key encryption key that has
        previously been stored in an Azure Key Vault. The WRAP operation is only strictly necessary for
        symmetric keys stored in Azure Key Vault since protection with an asymmetric key can be
        performed using the public portion of the key. This operation is supported for asymmetric keys
        as a convenience for callers that have a key-reference but do not have access to the public key
        material. This operation requires the keys/wrapKey permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for wrap operation. Required.
        :type parameters: IO[bytes]
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def wrap_key(
        self,
        key_name: str,
        key_version: str,
        parameters: Union[_models.KeyOperationsParameters, JSON, IO[bytes]],
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Wraps a symmetric key using a specified key.

        The WRAP operation supports encryption of a symmetric key using a key encryption key that has
        previously been stored in an Azure Key Vault. The WRAP operation is only strictly necessary for
        symmetric keys stored in Azure Key Vault since protection with an asymmetric key can be
        performed using the public portion of the key. This operation is supported for asymmetric keys
        as a convenience for callers that have a key-reference but do not have access to the public key
        material. This operation requires the keys/wrapKey permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for wrap operation. Is one of the following types:
         KeyOperationsParameters, JSON, IO[bytes] Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters or JSON or
         IO[bytes]
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.KeyOperationResult] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_key_vault_wrap_key_request(
            key_name=key_name,
            key_version=key_version,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyOperationResult, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @overload
    async def unwrap_key(
        self,
        key_name: str,
        key_version: str,
        parameters: _models.KeyOperationsParameters,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Unwraps a symmetric key using the specified key that was initially used for wrapping that key.

        The UNWRAP operation supports decryption of a symmetric key using the target key encryption
        key. This operation is the reverse of the WRAP operation. The UNWRAP operation applies to
        asymmetric and symmetric keys stored in Azure Key Vault since it uses the private portion of
        the key. This operation requires the keys/unwrapKey permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for the key operation. Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def unwrap_key(
        self,
        key_name: str,
        key_version: str,
        parameters: JSON,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Unwraps a symmetric key using the specified key that was initially used for wrapping that key.

        The UNWRAP operation supports decryption of a symmetric key using the target key encryption
        key. This operation is the reverse of the WRAP operation. The UNWRAP operation applies to
        asymmetric and symmetric keys stored in Azure Key Vault since it uses the private portion of
        the key. This operation requires the keys/unwrapKey permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for the key operation. Required.
        :type parameters: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def unwrap_key(
        self,
        key_name: str,
        key_version: str,
        parameters: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Unwraps a symmetric key using the specified key that was initially used for wrapping that key.

        The UNWRAP operation supports decryption of a symmetric key using the target key encryption
        key. This operation is the reverse of the WRAP operation. The UNWRAP operation applies to
        asymmetric and symmetric keys stored in Azure Key Vault since it uses the private portion of
        the key. This operation requires the keys/unwrapKey permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for the key operation. Required.
        :type parameters: IO[bytes]
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def unwrap_key(
        self,
        key_name: str,
        key_version: str,
        parameters: Union[_models.KeyOperationsParameters, JSON, IO[bytes]],
        **kwargs: Any
    ) -> _models.KeyOperationResult:
        """Unwraps a symmetric key using the specified key that was initially used for wrapping that key.

        The UNWRAP operation supports decryption of a symmetric key using the target key encryption
        key. This operation is the reverse of the WRAP operation. The UNWRAP operation applies to
        asymmetric and symmetric keys stored in Azure Key Vault since it uses the private portion of
        the key. This operation requires the keys/unwrapKey permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :param key_version: The version of the key. Required.
        :type key_version: str
        :param parameters: The parameters for the key operation. Is one of the following types:
         KeyOperationsParameters, JSON, IO[bytes] Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters or JSON or
         IO[bytes]
        :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.KeyOperationResult] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_key_vault_unwrap_key_request(
            key_name=key_name,
            key_version=key_version,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyOperationResult, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @overload
    async def release(
        self,
        key_name: str,
        key_version: str,
        parameters: _models.KeyReleaseParameters,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyReleaseResult:
        """Releases a key.

        The release key operation is applicable to all key types. The target key must be marked
        exportable. This operation requires the keys/release permission.

        :param key_name: The name of the key to get. Required.
        :type key_name: str
        :param key_version: Adding the version parameter retrieves a specific version of a key.
         Required.
        :type key_version: str
        :param parameters: The parameters for the key release operation. Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyReleaseParameters
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyReleaseResult. The KeyReleaseResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyReleaseResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def release(
        self,
        key_name: str,
        key_version: str,
        parameters: JSON,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyReleaseResult:
        """Releases a key.

        The release key operation is applicable to all key types. The target key must be marked
        exportable. This operation requires the keys/release permission.

        :param key_name: The name of the key to get. Required.
        :type key_name: str
        :param key_version: Adding the version parameter retrieves a specific version of a key.
         Required.
        :type key_version: str
        :param parameters: The parameters for the key release operation. Required.
        :type parameters: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyReleaseResult. The KeyReleaseResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyReleaseResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def release(
        self,
        key_name: str,
        key_version: str,
        parameters: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyReleaseResult:
        """Releases a key.

        The release key operation is applicable to all key types. The target key must be marked
        exportable. This operation requires the keys/release permission.

        :param key_name: The name of the key to get. Required.
        :type key_name: str
        :param key_version: Adding the version parameter retrieves a specific version of a key.
         Required.
        :type key_version: str
        :param parameters: The parameters for the key release operation. Required.
        :type parameters: IO[bytes]
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyReleaseResult. The KeyReleaseResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyReleaseResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def release(
        self,
        key_name: str,
        key_version: str,
        parameters: Union[_models.KeyReleaseParameters, JSON, IO[bytes]],
        **kwargs: Any
    ) -> _models.KeyReleaseResult:
        """Releases a key.

        The release key operation is applicable to all key types. The target key must be marked
        exportable. This operation requires the keys/release permission.

        :param key_name: The name of the key to get. Required.
        :type key_name: str
        :param key_version: Adding the version parameter retrieves a specific version of a key.
         Required.
        :type key_version: str
        :param parameters: The parameters for the key release operation. Is one of the following types:
         KeyReleaseParameters, JSON, IO[bytes] Required.
        :type parameters: ~azure.keyvault.keys._generated.models.KeyReleaseParameters or JSON or
         IO[bytes]
        :return: KeyReleaseResult. The KeyReleaseResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyReleaseResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.KeyReleaseResult] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_key_vault_release_request(
            key_name=key_name,
            key_version=key_version,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyReleaseResult, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @distributed_trace
    def get_deleted_keys(
        self, *, maxresults: Optional[int] = None, **kwargs: Any
    ) -> AsyncIterable["_models.DeletedKeyItem"]:
        """Lists the deleted keys in the specified vault.

        Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the
        public part of a deleted key. This operation includes deletion-specific information. The Get
        Deleted Keys operation is applicable for vaults enabled for soft-delete. While the operation
        can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled
        vault. This operation requires the keys/list permission.

        :keyword maxresults: Maximum number of results to return in a page. If not specified the
         service will return up to 25 results. Default value is None.
        :paramtype maxresults: int
        :return: An iterator like instance of DeletedKeyItem
        :rtype:
         ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.keys._generated.models.DeletedKeyItem]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = kwargs.pop("params", {}) or {}

        cls: ClsType[List[_models.DeletedKeyItem]] = kwargs.pop("cls", None)

        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        def prepare_request(next_link=None):
            if not next_link:

                _request = build_key_vault_get_deleted_keys_request(
                    maxresults=maxresults,
                    api_version=self._config.api_version,
                    headers=_headers,
                    params=_params,
                )
                path_format_arguments = {
                    "vaultBaseUrl": self._serialize.url(
                        "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
                    ),
                }
                _request.url = self._client.format_url(_request.url, **path_format_arguments)

            else:
                # make call to next link with the client's api-version
                _parsed_next_link = urllib.parse.urlparse(next_link)
                _next_request_params = case_insensitive_dict(
                    {
                        key: [urllib.parse.quote(v) for v in value]
                        for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items()
                    }
                )
                _next_request_params["api-version"] = self._config.api_version
                _request = HttpRequest(
                    "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
                )
                path_format_arguments = {
                    "vaultBaseUrl": self._serialize.url(
                        "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
                    ),
                }
                _request.url = self._client.format_url(_request.url, **path_format_arguments)

            return _request

        async def extract_data(pipeline_response):
            deserialized = pipeline_response.http_response.json()
            list_of_elem = _deserialize(List[_models.DeletedKeyItem], deserialized.get("value", []))
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.get("nextLink") or None, AsyncList(list_of_elem)

        async def get_next(next_link=None):
            _request = prepare_request(next_link)

            _stream = False
            pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
                _request, stream=_stream, **kwargs
            )
            response = pipeline_response.http_response

            if response.status_code not in [200]:
                map_error(status_code=response.status_code, response=response, error_map=error_map)
                error = _failsafe_deserialize(_models.KeyVaultError, response.json())
                raise HttpResponseError(response=response, model=error)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)

    @distributed_trace_async
    async def get_deleted_key(self, key_name: str, **kwargs: Any) -> _models.DeletedKeyBundle:
        """Gets the public part of a deleted key.

        The Get Deleted Key operation is applicable for soft-delete enabled vaults. While the operation
        can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled
        vault. This operation requires the keys/get permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :return: DeletedKeyBundle. The DeletedKeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.DeletedKeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = kwargs.pop("headers", {}) or {}
        _params = kwargs.pop("params", {}) or {}

        cls: ClsType[_models.DeletedKeyBundle] = kwargs.pop("cls", None)

        _request = build_key_vault_get_deleted_key_request(
            key_name=key_name,
            api_version=self._config.api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.DeletedKeyBundle, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @distributed_trace_async
    async def purge_deleted_key(self, key_name: str, **kwargs: Any) -> None:
        """Permanently deletes the specified key.

        The Purge Deleted Key operation is applicable for soft-delete enabled vaults. While the
        operation can be invoked on any vault, it will return an error if invoked on a non soft-delete
        enabled vault. This operation requires the keys/purge permission.

        :param key_name: The name of the key. Required.
        :type key_name: str
        :return: None
        :rtype: None
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = kwargs.pop("headers", {}) or {}
        _params = kwargs.pop("params", {}) or {}

        cls: ClsType[None] = kwargs.pop("cls", None)

        _request = build_key_vault_purge_deleted_key_request(
            key_name=key_name,
            api_version=self._config.api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = False
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [204]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if cls:
            return cls(pipeline_response, None, {})  # type: ignore

    @distributed_trace_async
    async def recover_deleted_key(self, key_name: str, **kwargs: Any) -> _models.KeyBundle:
        """Recovers the deleted key to its latest version.

        The Recover Deleted Key operation is applicable for deleted keys in soft-delete enabled vaults.
        It recovers the deleted key back to its latest version under /keys. An attempt to recover an
        non-deleted key will return an error. Consider this the inverse of the delete operation on
        soft-delete enabled vaults. This operation requires the keys/recover permission.

        :param key_name: The name of the deleted key. Required.
        :type key_name: str
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = kwargs.pop("headers", {}) or {}
        _params = kwargs.pop("params", {}) or {}

        cls: ClsType[_models.KeyBundle] = kwargs.pop("cls", None)

        _request = build_key_vault_recover_deleted_key_request(
            key_name=key_name,
            api_version=self._config.api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyBundle, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @distributed_trace_async
    async def get_key_rotation_policy(self, key_name: str, **kwargs: Any) -> _models.KeyRotationPolicy:
        """Lists the policy for a key.

        The GetKeyRotationPolicy operation returns the specified key policy resources in the specified
        key vault. This operation requires the keys/get permission.

        :param key_name: The name of the key in a given key vault. Required.
        :type key_name: str
        :return: KeyRotationPolicy. The KeyRotationPolicy is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyRotationPolicy
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = kwargs.pop("headers", {}) or {}
        _params = kwargs.pop("params", {}) or {}

        cls: ClsType[_models.KeyRotationPolicy] = kwargs.pop("cls", None)

        _request = build_key_vault_get_key_rotation_policy_request(
            key_name=key_name,
            api_version=self._config.api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyRotationPolicy, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @overload
    async def update_key_rotation_policy(
        self,
        key_name: str,
        key_rotation_policy: _models.KeyRotationPolicy,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.KeyRotationPolicy:
        """Updates the rotation policy for a key.

        Set specified members in the key policy. Leave others as undefined. This operation requires the
        keys/update permission.

        :param key_name: The name of the key in the given vault. Required.
        :type key_name: str
        :param key_rotation_policy: The policy for the key. Required.
        :type key_rotation_policy: ~azure.keyvault.keys._generated.models.KeyRotationPolicy
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyRotationPolicy. The KeyRotationPolicy is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyRotationPolicy
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def update_key_rotation_policy(
        self, key_name: str, key_rotation_policy: JSON, *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.KeyRotationPolicy:
        """Updates the rotation policy for a key.

        Set specified members in the key policy. Leave others as undefined. This operation requires the
        keys/update permission.

        :param key_name: The name of the key in the given vault. Required.
        :type key_name: str
        :param key_rotation_policy: The policy for the key. Required.
        :type key_rotation_policy: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyRotationPolicy. The KeyRotationPolicy is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyRotationPolicy
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def update_key_rotation_policy(
        self, key_name: str, key_rotation_policy: IO[bytes], *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.KeyRotationPolicy:
        """Updates the rotation policy for a key.

        Set specified members in the key policy. Leave others as undefined. This operation requires the
        keys/update permission.

        :param key_name: The name of the key in the given vault. Required.
        :type key_name: str
        :param key_rotation_policy: The policy for the key. Required.
        :type key_rotation_policy: IO[bytes]
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: KeyRotationPolicy. The KeyRotationPolicy is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyRotationPolicy
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def update_key_rotation_policy(
        self, key_name: str, key_rotation_policy: Union[_models.KeyRotationPolicy, JSON, IO[bytes]], **kwargs: Any
    ) -> _models.KeyRotationPolicy:
        """Updates the rotation policy for a key.

        Set specified members in the key policy. Leave others as undefined. This operation requires the
        keys/update permission.

        :param key_name: The name of the key in the given vault. Required.
        :type key_name: str
        :param key_rotation_policy: The policy for the key. Is one of the following types:
         KeyRotationPolicy, JSON, IO[bytes] Required.
        :type key_rotation_policy: ~azure.keyvault.keys._generated.models.KeyRotationPolicy or JSON or
         IO[bytes]
        :return: KeyRotationPolicy. The KeyRotationPolicy is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyRotationPolicy
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.KeyRotationPolicy] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _content = None
        if isinstance(key_rotation_policy, (IOBase, bytes)):
            _content = key_rotation_policy
        else:
            _content = json.dumps(key_rotation_policy, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_key_vault_update_key_rotation_policy_request(
            key_name=key_name,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyRotationPolicy, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @overload
    async def get_random_bytes(
        self, parameters: _models.GetRandomBytesRequest, *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.RandomBytes:
        """Get the requested number of bytes containing random values.

        Get the requested number of bytes containing random values from a managed HSM.

        :param parameters: The request object to get random bytes. Required.
        :type parameters: ~azure.keyvault.keys._generated.models.GetRandomBytesRequest
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: RandomBytes. The RandomBytes is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.RandomBytes
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def get_random_bytes(
        self, parameters: JSON, *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.RandomBytes:
        """Get the requested number of bytes containing random values.

        Get the requested number of bytes containing random values from a managed HSM.

        :param parameters: The request object to get random bytes. Required.
        :type parameters: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: RandomBytes. The RandomBytes is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.RandomBytes
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def get_random_bytes(
        self, parameters: IO[bytes], *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.RandomBytes:
        """Get the requested number of bytes containing random values.

        Get the requested number of bytes containing random values from a managed HSM.

        :param parameters: The request object to get random bytes. Required.
        :type parameters: IO[bytes]
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: RandomBytes. The RandomBytes is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.RandomBytes
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def get_random_bytes(
        self, parameters: Union[_models.GetRandomBytesRequest, JSON, IO[bytes]], **kwargs: Any
    ) -> _models.RandomBytes:
        """Get the requested number of bytes containing random values.

        Get the requested number of bytes containing random values from a managed HSM.

        :param parameters: The request object to get random bytes. Is one of the following types:
         GetRandomBytesRequest, JSON, IO[bytes] Required.
        :type parameters: ~azure.keyvault.keys._generated.models.GetRandomBytesRequest or JSON or
         IO[bytes]
        :return: RandomBytes. The RandomBytes is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.RandomBytes
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.RandomBytes] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_key_vault_get_random_bytes_request(
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.RandomBytes, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @distributed_trace_async
    @api_version_validation(
        method_added_on="7.6",
        params_added_on={"7.6": ["api_version", "key_name", "key_version", "accept"]},
    )
    async def get_key_attestation(self, key_name: str, key_version: str, **kwargs: Any) -> _models.KeyBundle:
        """Gets the public part of a stored key along with its attestation blob.

        The get key attestation operation returns the key along with its attestation blob. This
        operation requires the keys/get permission.

        :param key_name: The name of the key to retrieve attestation for. Required.
        :type key_name: str
        :param key_version: Adding the version parameter retrieves attestation blob for specific
         version of a key. This URI fragment is optional. If not specified, the latest version of the
         key attestation blob is returned. Required.
        :type key_version: str
        :return: KeyBundle. The KeyBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.keys._generated.models.KeyBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = kwargs.pop("headers", {}) or {}
        _params = kwargs.pop("params", {}) or {}

        cls: ClsType[_models.KeyBundle] = kwargs.pop("cls", None)

        _request = build_key_vault_get_key_attestation_request(
            key_name=key_name,
            key_version=key_version,
            api_version=self._config.api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = kwargs.pop("stream", False)
        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(_models.KeyVaultError, response.json())
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.KeyBundle, response.json())

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore
