From 75dace37d288db54495128438d55082cf7123388 Mon Sep 17 00:00:00 2001 From: SDKAuto Date: Wed, 23 Apr 2025 22:37:15 +0000 Subject: [PATCH] CodeGen from PR 34032 in Azure/azure-rest-api-specs Merge c05749c07658b43406ee1632c47ff96074aa5137 into 4689e75cdeaa04dbeead0237b72cae8dc8dbba4d --- .../azure-keyvault-secrets/MANIFEST.in | 6 +- .../azure-keyvault-secrets/_meta.json | 6 + .../apiview-properties.json | 29 + .../azure-keyvault-secrets/azure/__init__.py | 5 - .../azure/keyvault/__init__.py | 5 - .../azure/keyvault/secrets/__init__.py | 43 +- .../azure/keyvault/secrets/_client.py | 547 +++--------------- .../{_generated => }/_configuration.py | 0 .../keyvault/secrets/_generated/__init__.py | 32 - .../keyvault/secrets/_generated/_client.py | 100 ---- .../keyvault/secrets/_generated/_version.py | 9 - .../secrets/_generated/aio/__init__.py | 29 - .../secrets/_generated/aio/_client.py | 102 ---- .../secrets/_generated/models/_patch.py | 20 - .../keyvault/secrets/_generated/py.typed | 1 - .../secrets/_generated/tsp-location.yaml | 5 - .../secrets/{_generated => }/_model_base.py | 27 +- .../azure/keyvault/secrets/_models.py | 387 ------------- .../{_generated => }/_operations/__init__.py | 0 .../_operations/_operations.py | 70 ++- .../aio => }/_operations/_patch.py | 9 +- .../secrets/{_generated => }/_patch.py | 9 +- .../azure/keyvault/secrets/_sdk_moniker.py | 7 - .../{_generated => }/_serialization.py | 32 +- .../keyvault/secrets/_shared/__init__.py | 77 --- .../keyvault/secrets/_shared/_polling.py | 142 ----- .../secrets/_shared/_polling_async.py | 87 --- .../_shared/async_challenge_auth_policy.py | 262 --------- .../secrets/_shared/async_client_base.py | 117 ---- .../secrets/_shared/challenge_auth_policy.py | 270 --------- .../keyvault/secrets/_shared/client_base.py | 161 ------ .../secrets/_shared/http_challenge.py | 182 ------ .../secrets/_shared/http_challenge_cache.py | 93 --- .../secrets/{_generated => }/_vendor.py | 0 .../azure/keyvault/secrets/_version.py | 13 +- .../azure/keyvault/secrets/aio/__init__.py | 34 +- .../azure/keyvault/secrets/aio/_client.py | 523 +++-------------- .../{_generated => }/aio/_configuration.py | 0 .../aio/_operations/__init__.py | 0 .../aio/_operations/_operations.py | 68 +-- .../aio => aio/_operations}/_patch.py | 9 +- .../{_generated/_operations => aio}/_patch.py | 9 +- .../secrets/{_generated => }/aio/_vendor.py | 0 .../{_generated => }/models/__init__.py | 4 +- .../secrets/{_generated => }/models/_enums.py | 0 .../{_generated => }/models/_models.py | 160 ++--- .../azure/keyvault/secrets/models/_patch.py | 21 + .../azure/keyvault/secrets/py.typed | 1 + .../samples/backup_restore_operations.py | 1 + .../backup_restore_operations_async.py | 4 +- .../samples/hello_world.py | 1 + .../samples/hello_world_async.py | 2 + .../samples/list_operations.py | 13 +- .../samples/list_operations_async.py | 10 +- .../samples/recover_purge_operations.py | 1 + .../samples/recover_purge_operations_async.py | 2 + sdk/keyvault/azure-keyvault-secrets/setup.py | 57 +- .../azure-keyvault-secrets/tests/conftest.py | 2 +- .../tests/test_polling_method.py | 8 +- .../tests/test_secrets_async.py | 1 + .../tests/test_secrets_client.py | 1 + .../azure-keyvault-secrets/tsp-location.yaml | 5 + 62 files changed, 547 insertions(+), 3274 deletions(-) create mode 100644 sdk/keyvault/azure-keyvault-secrets/_meta.json create mode 100644 sdk/keyvault/azure-keyvault-secrets/apiview-properties.json rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated => }/_configuration.py (100%) delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/__init__.py delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_client.py delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_version.py delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/__init__.py delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_client.py delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/models/_patch.py delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/py.typed delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/tsp-location.yaml rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated => }/_model_base.py (98%) delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_models.py rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated => }/_operations/__init__.py (100%) rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated => }/_operations/_operations.py (96%) rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated/aio => }/_operations/_patch.py (61%) rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated => }/_patch.py (61%) delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_sdk_moniker.py rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated => }/_serialization.py (98%) delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/__init__.py delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/_polling.py delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/_polling_async.py delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/async_challenge_auth_policy.py delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/async_client_base.py delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/challenge_auth_policy.py delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/client_base.py delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/http_challenge.py delete mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/http_challenge_cache.py rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated => }/_vendor.py (100%) rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated => }/aio/_configuration.py (100%) rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated => }/aio/_operations/__init__.py (100%) rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated => }/aio/_operations/_operations.py (95%) rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated/aio => aio/_operations}/_patch.py (61%) rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated/_operations => aio}/_patch.py (61%) rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated => }/aio/_vendor.py (100%) rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated => }/models/__init__.py (96%) rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated => }/models/_enums.py (100%) rename sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/{_generated => }/models/_models.py (79%) create mode 100644 sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/models/_patch.py create mode 100644 sdk/keyvault/azure-keyvault-secrets/tsp-location.yaml diff --git a/sdk/keyvault/azure-keyvault-secrets/MANIFEST.in b/sdk/keyvault/azure-keyvault-secrets/MANIFEST.in index 428d4f96463e..91c95d391763 100644 --- a/sdk/keyvault/azure-keyvault-secrets/MANIFEST.in +++ b/sdk/keyvault/azure-keyvault-secrets/MANIFEST.in @@ -1,7 +1,7 @@ include *.md include LICENSE +include azure/keyvault/secrets/py.typed +recursive-include tests *.py +recursive-include samples *.py *.md include azure/__init__.py include azure/keyvault/__init__.py -recursive-include samples *.py -recursive-include tests *.py -include azure/keyvault/secrets/py.typed diff --git a/sdk/keyvault/azure-keyvault-secrets/_meta.json b/sdk/keyvault/azure-keyvault-secrets/_meta.json new file mode 100644 index 000000000000..8ececcf19014 --- /dev/null +++ b/sdk/keyvault/azure-keyvault-secrets/_meta.json @@ -0,0 +1,6 @@ +{ + "commit": "4465f2aaefeb75e8a088c7e0950979e03430a234", + "repository_url": "https://github.com/Azure/azure-rest-api-specs", + "typespec_src": "specification/keyvault/Security.KeyVault.Secrets", + "@azure-tools/typespec-python": "0.43.0" +} \ No newline at end of file diff --git a/sdk/keyvault/azure-keyvault-secrets/apiview-properties.json b/sdk/keyvault/azure-keyvault-secrets/apiview-properties.json new file mode 100644 index 000000000000..61c9c308ed86 --- /dev/null +++ b/sdk/keyvault/azure-keyvault-secrets/apiview-properties.json @@ -0,0 +1,29 @@ +{ + "CrossLanguagePackageId": "KeyVault", + "CrossLanguageDefinitionId": { + "azure.keyvault.secrets.models.BackupSecretResult": "KeyVault.BackupSecretResult", + "azure.keyvault.secrets.models.DeletedSecretBundle": "KeyVault.DeletedSecretBundle", + "azure.keyvault.secrets.models.DeletedSecretItem": "KeyVault.DeletedSecretItem", + "azure.keyvault.secrets.models.Error": "Error", + "azure.keyvault.secrets.models.KeyVaultError": "KeyVaultError", + "azure.keyvault.secrets.models.SecretAttributes": "KeyVault.SecretAttributes", + "azure.keyvault.secrets.models.SecretBundle": "KeyVault.SecretBundle", + "azure.keyvault.secrets.models.SecretItem": "KeyVault.SecretItem", + "azure.keyvault.secrets.models.SecretRestoreParameters": "KeyVault.SecretRestoreParameters", + "azure.keyvault.secrets.models.SecretSetParameters": "KeyVault.SecretSetParameters", + "azure.keyvault.secrets.models.SecretUpdateParameters": "KeyVault.SecretUpdateParameters", + "azure.keyvault.secrets.models.DeletionRecoveryLevel": "KeyVault.DeletionRecoveryLevel", + "azure.keyvault.secrets.KeyVaultClient.set_secret": "KeyVault.setSecret", + "azure.keyvault.secrets.KeyVaultClient.delete_secret": "KeyVault.deleteSecret", + "azure.keyvault.secrets.KeyVaultClient.update_secret": "KeyVault.updateSecret", + "azure.keyvault.secrets.KeyVaultClient.get_secret": "KeyVault.getSecret", + "azure.keyvault.secrets.KeyVaultClient.get_secrets": "KeyVault.getSecrets", + "azure.keyvault.secrets.KeyVaultClient.get_secret_versions": "KeyVault.getSecretVersions", + "azure.keyvault.secrets.KeyVaultClient.get_deleted_secrets": "KeyVault.getDeletedSecrets", + "azure.keyvault.secrets.KeyVaultClient.get_deleted_secret": "KeyVault.getDeletedSecret", + "azure.keyvault.secrets.KeyVaultClient.purge_deleted_secret": "KeyVault.purgeDeletedSecret", + "azure.keyvault.secrets.KeyVaultClient.recover_deleted_secret": "KeyVault.recoverDeletedSecret", + "azure.keyvault.secrets.KeyVaultClient.backup_secret": "KeyVault.backupSecret", + "azure.keyvault.secrets.KeyVaultClient.restore_secret": "KeyVault.restoreSecret" + } +} \ No newline at end of file diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/__init__.py b/sdk/keyvault/azure-keyvault-secrets/azure/__init__.py index 125860bac907..d55ccad1f573 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/__init__.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/__init__.py @@ -1,6 +1 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -# pylint:disable=missing-docstring __path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/__init__.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/__init__.py index 125860bac907..d55ccad1f573 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/__init__.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/__init__.py @@ -1,6 +1 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -# pylint:disable=missing-docstring __path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/__init__.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/__init__.py index ec1b5aaa0651..4f7962408227 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/__init__.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/__init__.py @@ -1,19 +1,32 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from ._models import DeletedSecret, KeyVaultSecret, KeyVaultSecretIdentifier, SecretProperties -from ._shared.client_base import ApiVersion -from ._client import SecretClient +# 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. +# -------------------------------------------------------------------------- +# pylint: disable=wrong-import-position -__all__ = [ - "ApiVersion", - "SecretClient", - "KeyVaultSecret", - "KeyVaultSecretIdentifier", - "SecretProperties", - "DeletedSecret" -] +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from ._patch import * # pylint: disable=unused-wildcard-import +from ._client import KeyVaultClient # type: ignore from ._version import VERSION + __version__ = VERSION + +try: + from ._patch import __all__ as _patch_all + from ._patch import * +except ImportError: + _patch_all = [] +from ._patch import patch_sdk as _patch_sdk + +__all__ = [ + "KeyVaultClient", +] +__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore + +_patch_sdk() diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_client.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_client.py index 7a64848801dd..ad79f0c7348a 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_client.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_client.py @@ -1,478 +1,101 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from datetime import datetime -from functools import partial -from typing import Any, cast, Dict, Optional +# 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 azure.core.paging import ItemPaged -from azure.core.polling import LROPoller -from azure.core.tracing.decorator import distributed_trace +from copy import deepcopy +from typing import Any, TYPE_CHECKING +from typing_extensions import Self -from ._models import KeyVaultSecret, DeletedSecret, SecretProperties -from ._shared import KeyVaultClientBase -from ._shared._polling import DeleteRecoverPollingMethod, KeyVaultOperationPoller +from azure.core import PipelineClient +from azure.core.pipeline import policies +from azure.core.rest import HttpRequest, HttpResponse +from ._configuration import KeyVaultClientConfiguration +from ._operations import KeyVaultClientOperationsMixin +from ._serialization import Deserializer, Serializer -class SecretClient(KeyVaultClientBase): - """A high-level interface for managing a vault's secrets. +if TYPE_CHECKING: + from azure.core.credentials import TokenCredential - :param str vault_url: URL of the vault the client will access. This is also called the vault's "DNS Name". - You should validate that this URL references a valid Key Vault resource. See https://aka.ms/azsdk/blog/vault-uri - for details. - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity` - :type credential: ~azure.core.credentials.TokenCredential - :keyword api_version: Version of the service API to use. Defaults to the most recent. - :paramtype api_version: ~azure.keyvault.secrets.ApiVersion or str - :keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key - Vault domain. Defaults to True. +class KeyVaultClient(KeyVaultClientOperationsMixin): + """The key vault client performs cryptographic key operations and vault operations against the Key + Vault service. - Example: - .. literalinclude:: ../tests/test_samples_secrets.py - :start-after: [START create_secret_client] - :end-before: [END create_secret_client] - :language: python - :caption: Create a new ``SecretClient`` - :dedent: 4 + :param vault_base_url: Required. + :type vault_base_url: str + :param credential: Credential used to authenticate requests to the service. Required. + :type credential: ~azure.core.credentials.TokenCredential + :keyword api_version: The API version to use for this operation. Default value is + "7.6-preview.2". Note that overriding this default value may result in unsupported behavior. + :paramtype api_version: str """ - # pylint:disable=protected-access - - @distributed_trace - def get_secret(self, name: str, version: Optional[str] = None, **kwargs: Any) -> KeyVaultSecret: - """Get a secret. Requires the secrets/get permission. - - :param str name: The name of the secret - :param str version: (optional) Version of the secret to get. If unspecified, gets the latest version. - - :returns: The fetched secret. - :rtype: ~azure.keyvault.secrets.KeyVaultSecret - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the secret doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_secrets.py - :start-after: [START get_secret] - :end-before: [END get_secret] - :language: python - :caption: Get a secret - :dedent: 8 - """ - bundle = self._client.get_secret( - secret_name=name, - secret_version=version or "", - **kwargs - ) - return KeyVaultSecret._from_secret_bundle(bundle) - - @distributed_trace - def set_secret( - self, - name: str, - value: str, - *, - enabled: Optional[bool] = None, - tags: Optional[Dict[str, str]] = None, - content_type: Optional[str] = None, - not_before: Optional[datetime] = None, - expires_on: Optional[datetime] = None, - **kwargs: Any, - ) -> KeyVaultSecret: - """Set a secret value. If `name` is in use, create a new version of the secret. If not, create a new secret. - - Requires secrets/set permission. - - :param str name: The name of the secret - :param str value: The value of the secret - - :keyword bool enabled: Whether the secret is enabled for use. - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: Dict[str, str] or None - :keyword str content_type: An arbitrary string indicating the type of the secret, e.g. 'password' - :keyword ~datetime.datetime not_before: Not before date of the secret in UTC - :keyword ~datetime.datetime expires_on: Expiry date of the secret in UTC - - :returns: The created or updated secret. - :rtype: ~azure.keyvault.secrets.KeyVaultSecret - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. literalinclude:: ../tests/test_samples_secrets.py - :start-after: [START set_secret] - :end-before: [END set_secret] - :language: python - :caption: Set a secret's value - :dedent: 8 - - """ - if enabled is not None or not_before is not None or expires_on is not None: - attributes = self._models.SecretAttributes( - enabled=enabled, not_before=not_before, expires=expires_on - ) - else: - attributes = None - - parameters = self._models.SecretSetParameters( - value=value, - tags=tags, - content_type=content_type, - secret_attributes=attributes - ) - - bundle = self._client.set_secret( - secret_name=name, - parameters=parameters, - **kwargs - ) - return KeyVaultSecret._from_secret_bundle(bundle) - - @distributed_trace - def update_secret_properties( - self, - name: str, - version: Optional[str] = None, - *, - enabled: Optional[bool] = None, - tags: Optional[Dict[str, str]] = None, - content_type: Optional[str] = None, - not_before: Optional[datetime] = None, - expires_on: Optional[datetime] = None, - **kwargs: Any, - ) -> SecretProperties: - """Update properties of a secret other than its value. Requires secrets/set permission. - - This method updates properties of the secret, such as whether it's enabled, but can't change the secret's - value. Use :func:`set_secret` to change the secret's value. - - :param str name: Name of the secret - :param str version: (optional) Version of the secret to update. If unspecified, the latest version is updated. - - :keyword bool enabled: Whether the secret is enabled for use. - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: Dict[str, str] or None - :keyword str content_type: An arbitrary string indicating the type of the secret, e.g. 'password' - :keyword ~datetime.datetime not_before: Not before date of the secret in UTC - :keyword ~datetime.datetime expires_on: Expiry date of the secret in UTC - - :returns: The updated secret properties. - :rtype: ~azure.keyvault.secrets.SecretProperties - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the secret doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_secrets.py - :start-after: [START update_secret] - :end-before: [END update_secret] - :language: python - :caption: Update a secret's attributes - :dedent: 8 - - """ - if enabled is not None or not_before is not None or expires_on is not None: - attributes = self._models.SecretAttributes( - enabled=enabled, not_before=not_before, expires=expires_on - ) - else: - attributes = None - - parameters = self._models.SecretUpdateParameters( - content_type=content_type, - secret_attributes=attributes, - tags=tags, - ) - - bundle = self._client.update_secret( - name, - secret_version=version or "", - parameters=parameters, - **kwargs - ) - return SecretProperties._from_secret_bundle(bundle) # pylint: disable=protected-access - - @distributed_trace - def list_properties_of_secrets(self, **kwargs: Any) -> ItemPaged[SecretProperties]: - """List identifiers and attributes of all secrets in the vault. Requires secrets/list permission. - - List items don't include secret values. Use :func:`get_secret` to get a secret's value. - - :returns: An iterator of secrets, excluding their values - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.secrets.SecretProperties] - - Example: - .. literalinclude:: ../tests/test_samples_secrets.py - :start-after: [START list_secrets] - :end-before: [END list_secrets] - :language: python - :caption: List all secrets - :dedent: 8 - - """ - return self._client.get_secrets( - maxresults=kwargs.pop("max_page_size", None), - cls=lambda objs: [SecretProperties._from_secret_item(x) for x in objs], - **kwargs - ) - - @distributed_trace - def list_properties_of_secret_versions(self, name: str, **kwargs: Any) -> ItemPaged[SecretProperties]: - """List properties of all versions of a secret, excluding their values. Requires secrets/list permission. - - List items don't include secret values. Use :func:`get_secret` to get a secret's value. - - :param str name: Name of the secret - - :returns: An iterator of secrets, excluding their values - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.secrets.SecretProperties] - - Example: - .. literalinclude:: ../tests/test_samples_secrets.py - :start-after: [START list_properties_of_secret_versions] - :end-before: [END list_properties_of_secret_versions] - :language: python - :caption: List all versions of a secret - :dedent: 8 - + def __init__(self, vault_base_url: str, credential: "TokenCredential", **kwargs: Any) -> None: + _endpoint = "{vaultBaseUrl}" + self._config = KeyVaultClientConfiguration(vault_base_url=vault_base_url, credential=credential, **kwargs) + + _policies = kwargs.pop("policies", None) + if _policies is None: + _policies = [ + policies.RequestIdPolicy(**kwargs), + self._config.headers_policy, + self._config.user_agent_policy, + self._config.proxy_policy, + policies.ContentDecodePolicy(**kwargs), + self._config.redirect_policy, + self._config.retry_policy, + self._config.authentication_policy, + self._config.custom_hook_policy, + self._config.logging_policy, + policies.DistributedTracingPolicy(**kwargs), + policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None, + self._config.http_logging_policy, + ] + self._client: PipelineClient = PipelineClient(base_url=_endpoint, policies=_policies, **kwargs) + + self._serialize = Serializer() + self._deserialize = Deserializer() + self._serialize.client_side_validation = False + + def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: Any) -> HttpResponse: + """Runs the network request through the client's chained policies. + + >>> from azure.core.rest import HttpRequest + >>> request = HttpRequest("GET", "https://www.example.org/") + + >>> response = client.send_request(request) + + + For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request + + :param request: The network request you want to make. Required. + :type request: ~azure.core.rest.HttpRequest + :keyword bool stream: Whether the response payload will be streamed. Defaults to False. + :return: The response of your network call. Does not do error handling on your response. + :rtype: ~azure.core.rest.HttpResponse """ - return self._client.get_secret_versions( - name, - maxresults=kwargs.pop("max_page_size", None), - cls=lambda objs: [SecretProperties._from_secret_item(x) for x in objs], - **kwargs - ) - @distributed_trace - def backup_secret(self, name: str, **kwargs: Any) -> bytes: - """Back up a secret in a protected form useable only by Azure Key Vault. Requires secrets/backup permission. - - :param str name: Name of the secret to back up - - :returns: The backup result, in a protected bytes format that can only be used by Azure Key Vault. - :rtype: bytes - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the secret doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_secrets.py - :start-after: [START backup_secret] - :end-before: [END backup_secret] - :language: python - :caption: Back up a secret - :dedent: 8 - - """ - backup_result = self._client.backup_secret(name, **kwargs) - return cast(bytes, backup_result.value) + request_copy = deepcopy(request) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } - @distributed_trace - def restore_secret_backup(self, backup: bytes, **kwargs: Any) -> SecretProperties: - """Restore a backed up secret. Requires the secrets/restore permission. + request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) + return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore - :param bytes backup: A secret backup as returned by :func:`backup_secret` + def close(self) -> None: + self._client.close() - :returns: The restored secret - :rtype: ~azure.keyvault.secrets.SecretProperties - - :raises ~azure.core.exceptions.ResourceExistsError or ~azure.core.exceptions.HttpResponseError: - the former if the secret's name is already in use; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_secrets.py - :start-after: [START restore_secret_backup] - :end-before: [END restore_secret_backup] - :language: python - :caption: Restore a backed up secret - :dedent: 8 - - """ - bundle = self._client.restore_secret( - parameters=self._models.SecretRestoreParameters(secret_bundle_backup=backup), - **kwargs - ) - return SecretProperties._from_secret_bundle(bundle) - - @distributed_trace - def begin_delete_secret(self, name: str, **kwargs: Any) -> LROPoller[DeletedSecret]: # pylint:disable=bad-option-value,delete-operation-wrong-return-type - """Delete all versions of a secret. Requires secrets/delete permission. - - When this method returns Key Vault has begun deleting the secret. Deletion may take several seconds in a vault - with soft-delete enabled. This method therefore returns a poller enabling you to wait for deletion to complete. - - :param str name: Name of the secret to delete. - - :returns: A poller for the delete operation. The poller's `result` method returns the - :class:`~azure.keyvault.secrets.DeletedSecret` without waiting for deletion to complete. If the vault has - soft-delete enabled and you want to permanently delete the secret with :func:`purge_deleted_secret`, call - the poller's `wait` method first. It will block until the deletion is complete. The `wait` method requires - secrets/get permission. - :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.secrets.DeletedSecret] - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the secret doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_secrets.py - :start-after: [START delete_secret] - :end-before: [END delete_secret] - :language: python - :caption: Delete a secret - :dedent: 8 - - """ - polling_interval = kwargs.pop("_polling_interval", None) - if polling_interval is None: - polling_interval = 2 - # Ignore pyright warning about return type not being iterable because we use `cls` to return a tuple - pipeline_response, deleted_secret_bundle = self._client.delete_secret( - secret_name=name, - cls=lambda pipeline_response, deserialized, _: (pipeline_response, deserialized), - **kwargs, - ) # pyright: ignore[reportGeneralTypeIssues] - deleted_secret = DeletedSecret._from_deleted_secret_bundle(deleted_secret_bundle) - - command = partial(self.get_deleted_secret, name=name, **kwargs) - polling_method = DeleteRecoverPollingMethod( - # no recovery ID means soft-delete is disabled, in which case we initialize the poller as finished - finished=deleted_secret.recovery_id is None, - pipeline_response=pipeline_response, - command=command, - final_resource=deleted_secret, - interval=polling_interval, - ) - return KeyVaultOperationPoller(polling_method) - - @distributed_trace - def get_deleted_secret(self, name: str, **kwargs: Any) -> DeletedSecret: - """Get a deleted secret. Possible only in vaults with soft-delete enabled. Requires secrets/get permission. - - :param str name: Name of the deleted secret - - :returns: The deleted secret. - :rtype: ~azure.keyvault.secrets.DeletedSecret - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the deleted secret doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_secrets.py - :start-after: [START get_deleted_secret] - :end-before: [END get_deleted_secret] - :language: python - :caption: Get a deleted secret - :dedent: 8 - - """ - bundle = self._client.get_deleted_secret(name, **kwargs) - return DeletedSecret._from_deleted_secret_bundle(bundle) - - @distributed_trace - def list_deleted_secrets(self, **kwargs: Any) -> ItemPaged[DeletedSecret]: - """Lists all deleted secrets. Possible only in vaults with soft-delete enabled. - - Requires secrets/list permission. - - :returns: An iterator of deleted secrets, excluding their values - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.secrets.DeletedSecret] - - Example: - .. literalinclude:: ../tests/test_samples_secrets.py - :start-after: [START list_deleted_secrets] - :end-before: [END list_deleted_secrets] - :language: python - :caption: List deleted secrets - :dedent: 8 - - """ - return self._client.get_deleted_secrets( - maxresults=kwargs.pop("max_page_size", None), - cls=lambda objs: [DeletedSecret._from_deleted_secret_item(x) for x in objs], - **kwargs - ) - - @distributed_trace - def purge_deleted_secret(self, name: str, **kwargs: Any) -> None: - """Permanently deletes a deleted secret. Possible only in vaults with soft-delete enabled. - - Performs an irreversible deletion of the specified secret, without possibility for recovery. The operation is - not available if the :py:attr:`~azure.keyvault.secrets.SecretProperties.recovery_level` does not specify - 'Purgeable'. This method is only necessary for purging a secret before its - :py:attr:`~azure.keyvault.secrets.DeletedSecret.scheduled_purge_date`. - - Requires secrets/purge permission. - - :param str name: Name of the deleted secret to purge - - :returns: None - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # if the vault has soft-delete enabled, purge permanently deletes the secret - # (with soft-delete disabled, begin_delete_secret is permanent) - secret_client.purge_deleted_secret("secret-name") - - """ - self._client.purge_deleted_secret(name, **kwargs) - - @distributed_trace - def begin_recover_deleted_secret(self, name: str, **kwargs: Any) -> LROPoller[SecretProperties]: - """Recover a deleted secret to its latest version. Possible only in a vault with soft-delete enabled. - - Requires the secrets/recover permission. If the vault does not have soft-delete enabled, - :func:`begin_delete_secret` is permanent, and this method will return an error. Attempting to recover a - non-deleted secret will also return an error. When this method returns Key Vault has begun recovering the - secret. Recovery may take several seconds. This method therefore returns a poller enabling you to wait for - recovery to complete. Waiting is only necessary when you want to use the recovered secret in another operation - immediately. - - :param str name: Name of the deleted secret to recover - - :returns: A poller for the recovery operation. The poller's `result` method returns the recovered secret's - :class:`~azure.keyvault.secrets.SecretProperties` without waiting for recovery to complete. If you want to - use the recovered secret immediately, call the poller's `wait` method, which blocks until the secret is - ready to use. The `wait` method requires secrets/get permission. - :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.secrets.SecretProperties] - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. literalinclude:: ../tests/test_samples_secrets.py - :start-after: [START recover_deleted_secret] - :end-before: [END recover_deleted_secret] - :language: python - :caption: Recover a deleted secret - :dedent: 8 - - """ - polling_interval = kwargs.pop("_polling_interval", None) - if polling_interval is None: - polling_interval = 2 - # Ignore pyright warning about return type not being iterable because we use `cls` to return a tuple - pipeline_response, recovered_secret_bundle = self._client.recover_deleted_secret( - secret_name=name, - cls=lambda pipeline_response, deserialized, _: (pipeline_response, deserialized), - **kwargs, - ) # pyright: ignore[reportGeneralTypeIssues] - recovered_secret = SecretProperties._from_secret_bundle(recovered_secret_bundle) - - command = partial(self.get_secret, name=name, **kwargs) - polling_method = DeleteRecoverPollingMethod( - finished=False, - pipeline_response=pipeline_response, - command=command, - final_resource=recovered_secret, - interval=polling_interval, - ) - return KeyVaultOperationPoller(polling_method) - - def __enter__(self) -> "SecretClient": + def __enter__(self) -> Self: self._client.__enter__() return self + + def __exit__(self, *exc_details: Any) -> None: + self._client.__exit__(*exc_details) diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_configuration.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_configuration.py similarity index 100% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_configuration.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_configuration.py diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/__init__.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/__init__.py deleted file mode 100644 index 4f7962408227..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -# 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. -# -------------------------------------------------------------------------- -# pylint: disable=wrong-import-position - -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - from ._patch import * # pylint: disable=unused-wildcard-import - -from ._client import KeyVaultClient # type: ignore -from ._version import VERSION - -__version__ = VERSION - -try: - from ._patch import __all__ as _patch_all - from ._patch import * -except ImportError: - _patch_all = [] -from ._patch import patch_sdk as _patch_sdk - -__all__ = [ - "KeyVaultClient", -] -__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore - -_patch_sdk() diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_client.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_client.py deleted file mode 100644 index a4f2ae420fbe..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_client.py +++ /dev/null @@ -1,100 +0,0 @@ -# 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 copy import deepcopy -from typing import Any, TYPE_CHECKING -from typing_extensions import Self - -from azure.core import PipelineClient -from azure.core.pipeline import policies -from azure.core.rest import HttpRequest, HttpResponse - -from ._configuration import KeyVaultClientConfiguration -from ._operations import KeyVaultClientOperationsMixin -from ._serialization import Deserializer, Serializer - -if TYPE_CHECKING: - from azure.core.credentials import TokenCredential - - -class KeyVaultClient(KeyVaultClientOperationsMixin): - """The key vault client performs cryptographic key operations and vault operations against the Key - Vault service. - - :param vault_base_url: Required. - :type vault_base_url: str - :param credential: Credential used to authenticate requests to the service. Required. - :type credential: ~azure.core.credentials.TokenCredential - :keyword api_version: The API version to use for this operation. Default value is - "7.6-preview.2". Note that overriding this default value may result in unsupported behavior. - :paramtype api_version: str - """ - - def __init__(self, vault_base_url: str, credential: "TokenCredential", **kwargs: Any) -> None: - _endpoint = "{vaultBaseUrl}" - self._config = KeyVaultClientConfiguration(vault_base_url=vault_base_url, credential=credential, **kwargs) - _policies = kwargs.pop("policies", None) - if _policies is None: - _policies = [ - policies.RequestIdPolicy(**kwargs), - self._config.headers_policy, - self._config.user_agent_policy, - self._config.proxy_policy, - policies.ContentDecodePolicy(**kwargs), - self._config.redirect_policy, - self._config.retry_policy, - self._config.authentication_policy, - self._config.custom_hook_policy, - self._config.logging_policy, - policies.DistributedTracingPolicy(**kwargs), - policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None, - self._config.http_logging_policy, - ] - self._client: PipelineClient = PipelineClient(base_url=_endpoint, policies=_policies, **kwargs) - - self._serialize = Serializer() - self._deserialize = Deserializer() - self._serialize.client_side_validation = False - - def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: Any) -> HttpResponse: - """Runs the network request through the client's chained policies. - - >>> from azure.core.rest import HttpRequest - >>> request = HttpRequest("GET", "https://www.example.org/") - - >>> response = client.send_request(request) - - - For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request - - :param request: The network request you want to make. Required. - :type request: ~azure.core.rest.HttpRequest - :keyword bool stream: Whether the response payload will be streamed. Defaults to False. - :return: The response of your network call. Does not do error handling on your response. - :rtype: ~azure.core.rest.HttpResponse - """ - - request_copy = deepcopy(request) - path_format_arguments = { - "vaultBaseUrl": self._serialize.url( - "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True - ), - } - - request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) - return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore - - def close(self) -> None: - self._client.close() - - def __enter__(self) -> Self: - self._client.__enter__() - return self - - def __exit__(self, *exc_details: Any) -> None: - self._client.__exit__(*exc_details) diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_version.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_version.py deleted file mode 100644 index 0d777283b3a2..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_version.py +++ /dev/null @@ -1,9 +0,0 @@ -# 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. -# -------------------------------------------------------------------------- - -VERSION = "4.9.0b1" diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/__init__.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/__init__.py deleted file mode 100644 index 8c996b993b8a..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/__init__.py +++ /dev/null @@ -1,29 +0,0 @@ -# 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. -# -------------------------------------------------------------------------- -# pylint: disable=wrong-import-position - -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - from ._patch import * # pylint: disable=unused-wildcard-import - -from ._client import KeyVaultClient # type: ignore - -try: - from ._patch import __all__ as _patch_all - from ._patch import * -except ImportError: - _patch_all = [] -from ._patch import patch_sdk as _patch_sdk - -__all__ = [ - "KeyVaultClient", -] -__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore - -_patch_sdk() diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_client.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_client.py deleted file mode 100644 index 2d775e8b1ece..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_client.py +++ /dev/null @@ -1,102 +0,0 @@ -# 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 copy import deepcopy -from typing import Any, Awaitable, TYPE_CHECKING -from typing_extensions import Self - -from azure.core import AsyncPipelineClient -from azure.core.pipeline import policies -from azure.core.rest import AsyncHttpResponse, HttpRequest - -from .._serialization import Deserializer, Serializer -from ._configuration import KeyVaultClientConfiguration -from ._operations import KeyVaultClientOperationsMixin - -if TYPE_CHECKING: - from azure.core.credentials_async import AsyncTokenCredential - - -class KeyVaultClient(KeyVaultClientOperationsMixin): - """The key vault client performs cryptographic key operations and vault operations against the Key - Vault service. - - :param vault_base_url: Required. - :type vault_base_url: str - :param credential: Credential used to authenticate requests to the service. Required. - :type credential: ~azure.core.credentials_async.AsyncTokenCredential - :keyword api_version: The API version to use for this operation. Default value is - "7.6-preview.2". Note that overriding this default value may result in unsupported behavior. - :paramtype api_version: str - """ - - def __init__(self, vault_base_url: str, credential: "AsyncTokenCredential", **kwargs: Any) -> None: - _endpoint = "{vaultBaseUrl}" - self._config = KeyVaultClientConfiguration(vault_base_url=vault_base_url, credential=credential, **kwargs) - _policies = kwargs.pop("policies", None) - if _policies is None: - _policies = [ - policies.RequestIdPolicy(**kwargs), - self._config.headers_policy, - self._config.user_agent_policy, - self._config.proxy_policy, - policies.ContentDecodePolicy(**kwargs), - self._config.redirect_policy, - self._config.retry_policy, - self._config.authentication_policy, - self._config.custom_hook_policy, - self._config.logging_policy, - policies.DistributedTracingPolicy(**kwargs), - policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None, - self._config.http_logging_policy, - ] - self._client: AsyncPipelineClient = AsyncPipelineClient(base_url=_endpoint, policies=_policies, **kwargs) - - self._serialize = Serializer() - self._deserialize = Deserializer() - self._serialize.client_side_validation = False - - def send_request( - self, request: HttpRequest, *, stream: bool = False, **kwargs: Any - ) -> Awaitable[AsyncHttpResponse]: - """Runs the network request through the client's chained policies. - - >>> from azure.core.rest import HttpRequest - >>> request = HttpRequest("GET", "https://www.example.org/") - - >>> response = await client.send_request(request) - - - For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request - - :param request: The network request you want to make. Required. - :type request: ~azure.core.rest.HttpRequest - :keyword bool stream: Whether the response payload will be streamed. Defaults to False. - :return: The response of your network call. Does not do error handling on your response. - :rtype: ~azure.core.rest.AsyncHttpResponse - """ - - request_copy = deepcopy(request) - path_format_arguments = { - "vaultBaseUrl": self._serialize.url( - "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True - ), - } - - request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) - return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore - - async def close(self) -> None: - await self._client.close() - - async def __aenter__(self) -> Self: - await self._client.__aenter__() - return self - - async def __aexit__(self, *exc_details: Any) -> None: - await self._client.__aexit__(*exc_details) diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/models/_patch.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/models/_patch.py deleted file mode 100644 index f7dd32510333..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/models/_patch.py +++ /dev/null @@ -1,20 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -"""Customize generated code here. - -Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize -""" -from typing import List - -__all__: List[str] = [] # Add all objects you want publicly available to users at this package level - - -def patch_sdk(): - """Do not remove from this file. - - `patch_sdk` is a last resort escape hatch that allows you to do customizations - you can't accomplish using the techniques described in - https://aka.ms/azsdk/python/dpcodegen/python/customize - """ diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/py.typed b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/py.typed deleted file mode 100644 index e5aff4f83af8..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/py.typed +++ /dev/null @@ -1 +0,0 @@ -# Marker file for PEP 561. \ No newline at end of file diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/tsp-location.yaml b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/tsp-location.yaml deleted file mode 100644 index e2aeb72f20cb..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/tsp-location.yaml +++ /dev/null @@ -1,5 +0,0 @@ -directory: specification/keyvault/Security.KeyVault.Secrets -commit: b8d26b0e4c1886458fa56c22aac09c3e3e9a5c9e -repo: Azure/azure-rest-api-specs -additionalDirectories: -- specification/keyvault/Security.KeyVault.Common/ diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_model_base.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_model_base.py similarity index 98% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_model_base.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_model_base.py index 3072ee252ed9..49d5c7259389 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_model_base.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_model_base.py @@ -2,8 +2,9 @@ # 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. +# 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. # -------------------------------------------------------------------------- # pylint: disable=protected-access, broad-except @@ -21,6 +22,7 @@ from datetime import datetime, date, time, timedelta, timezone from json import JSONEncoder import xml.etree.ElementTree as ET +from collections.abc import MutableMapping from typing_extensions import Self import isodate from azure.core.exceptions import DeserializationError @@ -28,11 +30,6 @@ from azure.core.pipeline import PipelineResponse from azure.core.serialization import _Null -if sys.version_info >= (3, 9): - from collections.abc import MutableMapping -else: - from typing import MutableMapping - _LOGGER = logging.getLogger(__name__) __all__ = ["SdkJSONEncoder", "Model", "rest_field", "rest_discriminator"] @@ -347,7 +344,7 @@ def _get_model(module_name: str, model_name: str): _UNSET = object() -class _MyMutableMapping(MutableMapping[str, typing.Any]): # pylint: disable=unsubscriptable-object +class _MyMutableMapping(MutableMapping[str, typing.Any]): def __init__(self, data: typing.Dict[str, typing.Any]) -> None: self._data = data @@ -407,13 +404,13 @@ def get(self, key: str, default: typing.Any = None) -> typing.Any: return default @typing.overload - def pop(self, key: str) -> typing.Any: ... + def pop(self, key: str) -> typing.Any: ... # pylint: disable=arguments-differ @typing.overload - def pop(self, key: str, default: _T) -> _T: ... + def pop(self, key: str, default: _T) -> _T: ... # pylint: disable=signature-differs @typing.overload - def pop(self, key: str, default: typing.Any) -> typing.Any: ... + def pop(self, key: str, default: typing.Any) -> typing.Any: ... # pylint: disable=signature-differs def pop(self, key: str, default: typing.Any = _UNSET) -> typing.Any: """ @@ -443,7 +440,7 @@ def clear(self) -> None: """ self._data.clear() - def update(self, *args: typing.Any, **kwargs: typing.Any) -> None: + def update(self, *args: typing.Any, **kwargs: typing.Any) -> None: # pylint: disable=arguments-differ """ Updates D from mapping/iterable E and F. :param any args: Either a mapping object or an iterable of key-value pairs. @@ -454,7 +451,7 @@ def update(self, *args: typing.Any, **kwargs: typing.Any) -> None: def setdefault(self, key: str, default: None = None) -> None: ... @typing.overload - def setdefault(self, key: str, default: typing.Any) -> typing.Any: ... + def setdefault(self, key: str, default: typing.Any) -> typing.Any: ... # pylint: disable=signature-differs def setdefault(self, key: str, default: typing.Any = _UNSET) -> typing.Any: """ @@ -644,7 +641,7 @@ def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> Self: cls._attr_to_rest_field: typing.Dict[str, _RestField] = dict(attr_to_rest_field.items()) cls._calculated.add(f"{cls.__module__}.{cls.__qualname__}") - return super().__new__(cls) # pylint: disable=no-value-for-parameter + return super().__new__(cls) def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: for base in cls.__bases__: @@ -680,7 +677,7 @@ def _deserialize(cls, data, exist_discriminators): discriminator_value = data.find(xml_name).text # pyright: ignore else: discriminator_value = data.get(discriminator._rest_name) - mapped_cls = cls.__mapping__.get(discriminator_value, cls) # pyright: ignore + mapped_cls = cls.__mapping__.get(discriminator_value, cls) # pyright: ignore # pylint: disable=no-member return mapped_cls._deserialize(data, exist_discriminators) def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_models.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_models.py deleted file mode 100644 index 73ec0ad5f609..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_models.py +++ /dev/null @@ -1,387 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from datetime import datetime - -from typing import Any, Dict, Optional, Union - -from ._generated import models as _models -from ._shared import parse_key_vault_id - - -class SecretProperties(object): - """A secret's ID and attributes.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - self._attributes: Optional[_models.SecretAttributes] = args[0] if args else kwargs.get("attributes", None) - self._id: Optional[str] = args[1] if len(args) > 1 else kwargs.get("vault_id", None) - self._vault_id = KeyVaultSecretIdentifier(self._id) if self._id else None - self._content_type = kwargs.get("content_type", None) - self._key_id = kwargs.get("key_id", None) - self._managed = kwargs.get("managed", None) - self._tags = kwargs.get("tags", None) - - def __repr__(self) -> str: - return f""[:1024] - - @classmethod - def _from_secret_bundle( - cls, secret_bundle: Union[_models.DeletedSecretBundle, _models.SecretBundle] - ) -> "SecretProperties": - return cls( - secret_bundle.attributes, - secret_bundle.id, - content_type=secret_bundle.content_type, - key_id=secret_bundle.kid, - managed=secret_bundle.managed, - tags=secret_bundle.tags, - ) - - @classmethod - def _from_secret_item(cls, secret_item: Union[_models.DeletedSecretItem, _models.SecretItem]) -> "SecretProperties": - return cls( - secret_item.attributes, - secret_item.id, - content_type=secret_item.content_type, - managed=secret_item.managed, - tags=secret_item.tags, - ) - - @property - def content_type(self) -> Optional[str]: - """An arbitrary string indicating the type of the secret. - - :returns: The content type of the secret. - :rtype: str or None - """ - return self._content_type - - @property - def id(self) -> Optional[str]: - """The secret's ID. - - :returns: The secret's ID. - :rtype: str or None - """ - return self._id - - @property - def key_id(self) -> Optional[str]: - """If this secret backs a certificate, this property is the identifier of the corresponding key. - - :returns: The ID of the key backing the certificate that's backed by this secret. If the secret isn't backing a - certificate, this is None. - :rtype: str or None - """ - return self._key_id - - @property - def enabled(self) -> Optional[bool]: - """Whether the secret is enabled for use. - - :returns: True if the secret is enabled for use; False otherwise. - :rtype: bool or None - """ - return self._attributes.enabled if self._attributes else None - - @property - def not_before(self) -> Optional[datetime]: - """The time before which the secret cannot be used, in UTC. - - :returns: The time before which the secret cannot be used, in UTC. - :rtype: ~datetime.datetime or None - """ - return self._attributes.not_before if self._attributes else None - - @property - def expires_on(self) -> Optional[datetime]: - """When the secret expires, in UTC. - - :returns: When the secret expires, in UTC. - :rtype: ~datetime.datetime or None - """ - return self._attributes.expires if self._attributes else None - - @property - def created_on(self) -> Optional[datetime]: - """When the secret was created, in UTC. - - :returns: When the secret was created, in UTC. - :rtype: ~datetime.datetime or None - """ - return self._attributes.created if self._attributes else None - - @property - def updated_on(self) -> Optional[datetime]: - """When the secret was last updated, in UTC. - - :returns: When the secret was last updated, in UTC. - :rtype: ~datetime.datetime or None - """ - return self._attributes.updated if self._attributes else None - - @property - def recoverable_days(self) -> Optional[int]: - """The number of days the key is retained before being deleted from a soft-delete enabled Key Vault. - - :returns: The number of days the key is retained before being deleted from a soft-delete enabled Key Vault. - :rtype: int or None - """ - # recoverable_days was added in 7.1-preview - if self._attributes and hasattr(self._attributes, "recoverable_days"): - return self._attributes.recoverable_days - return None - - @property - def recovery_level(self) -> Optional[str]: - """The vault's deletion recovery level for secrets. - - :returns: The vault's deletion recovery level for secrets. - :rtype: str or None - """ - return self._attributes.recovery_level if self._attributes else None - - @property - def vault_url(self) -> Optional[str]: - """URL of the vault containing the secret. - - :returns: URL of the vault containing the secret. - :rtype: str or None - """ - return self._vault_id.vault_url if self._vault_id else None - - @property - def name(self) -> Optional[str]: - """The secret's name. - - :returns: The secret's name. - :rtype: str or None - """ - return self._vault_id.name if self._vault_id else None - - @property - def version(self) -> Optional[str]: - """The secret's version. - - :returns: The secret's version. - :rtype: str or None - """ - return self._vault_id.version if self._vault_id else None - - @property - def tags(self) -> Optional[Dict[str, str]]: - """Application specific metadata in the form of key-value pairs. - - :returns: A dictionary of tags attached to this secret. - :rtype: dict or None - """ - return self._tags - - @property - def managed(self) -> Optional[bool]: - """Whether the secret's lifetime is managed by Key Vault. If the secret backs a certificate, this will be true. - - :returns: True if the secret's lifetime is managed by Key Vault; False otherwise. - :rtype: bool or None - """ - return self._managed - - -class KeyVaultSecret(object): - """All of a secret's properties, and its value. - - :param properties: The secret's properties. - :type properties: ~azure.keyvault.secrets.SecretProperties - :param value: The value of the secret. - :type value: str or None - """ - - def __init__(self, properties: SecretProperties, value: Optional[str]) -> None: - self._properties = properties - self._value = value - - def __repr__(self) -> str: - return f""[:1024] - - @classmethod - def _from_secret_bundle(cls, secret_bundle: _models.SecretBundle) -> "KeyVaultSecret": - return cls( - properties=SecretProperties._from_secret_bundle(secret_bundle), # pylint: disable=protected-access - value=secret_bundle.value, - ) - - @property - def name(self) -> Optional[str]: - """The secret's name. - - :returns: The secret's name. - :rtype: str or None - """ - return self._properties.name - - @property - def id(self) -> Optional[str]: - """The secret's ID. - - :returns: The secret's ID. - :rtype: str or None - """ - return self._properties.id - - @property - def properties(self) -> SecretProperties: - """The secret's properties. - - :returns: The secret's properties. - :rtype: ~azure.keyvault.secrets.SecretProperties - """ - return self._properties - - @property - def value(self) -> Optional[str]: - """The secret's value. - - :returns: The secret's value. - :rtype: str or None - """ - return self._value - - -class KeyVaultSecretIdentifier(object): - """Information about a KeyVaultSecret parsed from a secret ID. - - :param str source_id: the full original identifier of a secret - - :raises ValueError: if the secret ID is improperly formatted - - Example: - .. literalinclude:: ../tests/test_parse_id.py - :start-after: [START parse_key_vault_secret_id] - :end-before: [END parse_key_vault_secret_id] - :language: python - :caption: Parse a secret's ID - :dedent: 8 - """ - - def __init__(self, source_id: str) -> None: - self._resource_id = parse_key_vault_id(source_id) - - @property - def source_id(self) -> str: - return self._resource_id.source_id - - @property - def vault_url(self) -> str: - return self._resource_id.vault_url - - @property - def name(self) -> str: - return self._resource_id.name - - @property - def version(self) -> Optional[str]: - return self._resource_id.version - - -class DeletedSecret(object): - """A deleted secret's properties and information about its deletion. - - If soft-delete is enabled, returns information about its recovery as well. - - :param properties: The deleted secret's properties. - :type properties: ~azure.keyvault.secrets.SecretProperties - :param deleted_date: When the secret was deleted, in UTC. - :type deleted_date: ~datetime.datetime or None - :param recovery_id: An identifier used to recover the deleted secret. - :type recovery_id: str or None - :param scheduled_purge_date: When the secret is scheduled to be purged by Key Vault, in UTC. - :type scheduled_purge_date: ~datetime.datetime or None - """ - - def __init__( - self, - properties: SecretProperties, - deleted_date: Optional[datetime] = None, - recovery_id: Optional[str] = None, - scheduled_purge_date: Optional[datetime] = None, - ) -> None: - self._properties = properties - self._deleted_date = deleted_date - self._recovery_id = recovery_id - self._scheduled_purge_date = scheduled_purge_date - - def __repr__(self) -> str: - return f""[:1024] - - @classmethod - def _from_deleted_secret_bundle(cls, deleted_secret_bundle: _models.DeletedSecretBundle) -> "DeletedSecret": - return cls( - properties=SecretProperties._from_secret_bundle(deleted_secret_bundle), # pylint: disable=protected-access - deleted_date=deleted_secret_bundle.deleted_date, - recovery_id=deleted_secret_bundle.recovery_id, - scheduled_purge_date=deleted_secret_bundle.scheduled_purge_date, - ) - - @classmethod - def _from_deleted_secret_item(cls, deleted_secret_item: _models.DeletedSecretItem) -> "DeletedSecret": - return cls( - properties=SecretProperties._from_secret_item(deleted_secret_item), # pylint: disable=protected-access - deleted_date=deleted_secret_item.deleted_date, - recovery_id=deleted_secret_item.recovery_id, - scheduled_purge_date=deleted_secret_item.scheduled_purge_date, - ) - - @property - def name(self) -> Optional[str]: - """The secret's name. - - :returns: The secret's name. - :rtype: str or None - """ - return self._properties.name - - @property - def id(self) -> Optional[str]: - """The secret's ID. - - :returns: The secret's ID. - :rtype: str or None - """ - return self._properties.id - - @property - def properties(self) -> SecretProperties: - """The properties of the deleted secret. - - :returns: The properties of the deleted secret. - :rtype: ~azure.keyvault.secrets.SecretProperties - """ - return self._properties - - @property - def deleted_date(self) -> Optional[datetime]: - """When the secret was deleted, in UTC. - - :returns: When the secret was deleted, in UTC. - :rtype: ~datetime.datetime or None - """ - return self._deleted_date - - @property - def recovery_id(self) -> Optional[str]: - """An identifier used to recover the deleted secret. - - :returns: An identifier used to recover the deleted secret. - :rtype: str or None - """ - return self._recovery_id - - @property - def scheduled_purge_date(self) -> Optional[datetime]: - """When the secret is scheduled to be purged by Key Vault, in UTC. - - :returns: When the secret is scheduled to be purged by Key Vault, in UTC. - :rtype: ~datetime.datetime or None - """ - return self._scheduled_purge_date diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_operations/__init__.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_operations/__init__.py similarity index 100% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_operations/__init__.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_operations/__init__.py diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_operations/_operations.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_operations/_operations.py similarity index 96% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_operations/_operations.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_operations/_operations.py index fb975c7cad4e..1a226c86a2f8 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_operations/_operations.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_operations/_operations.py @@ -6,9 +6,9 @@ # 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 -import sys from typing import Any, Callable, Dict, IO, Iterable, List, Optional, TypeVar, Union, overload import urllib.parse @@ -33,11 +33,7 @@ from .._serialization import Serializer from .._vendor import KeyVaultClientMixinABC -if sys.version_info >= (3, 9): - from collections.abc import MutableMapping -else: - from typing import MutableMapping # type: ignore -JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object +JSON = MutableMapping[str, Any] T = TypeVar("T") ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] @@ -105,7 +101,7 @@ def build_key_vault_update_secret_request(secret_name: str, secret_version: str, accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/secrets/{secret-name}/{secret-version}" + _url = "/secrets/{secret-name}{secret-version}" path_format_arguments = { "secret-name": _SERIALIZER.url("secret_name", secret_name, "str"), "secret-version": _SERIALIZER.url("secret_version", secret_version, "str"), @@ -132,7 +128,7 @@ def build_key_vault_get_secret_request(secret_name: str, secret_version: str, ** accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/secrets/{secret-name}/{secret-version}" + _url = "/secrets/{secret-name}{secret-version}" path_format_arguments = { "secret-name": _SERIALIZER.url("secret_name", secret_name, "str"), "secret-version": _SERIALIZER.url("secret_version", secret_version, "str"), @@ -367,12 +363,12 @@ def set_secret( identifiable or sensitive information. Required. :type secret_name: str :param parameters: The parameters for setting the secret. Required. - :type parameters: ~azure.keyvault.secrets._generated.models.SecretSetParameters + :type parameters: ~azure.keyvault.secrets.models.SecretSetParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -396,7 +392,7 @@ def set_secret( Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -420,7 +416,7 @@ def set_secret( Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -440,9 +436,9 @@ def set_secret( :type secret_name: str :param parameters: The parameters for setting the secret. Is one of the following types: SecretSetParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.secrets._generated.models.SecretSetParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.secrets.models.SecretSetParameters or JSON or IO[bytes] :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -518,7 +514,7 @@ def delete_secret(self, secret_name: str, **kwargs: Any) -> _models.DeletedSecre :param secret_name: The name of the secret. Required. :type secret_name: str :return: DeletedSecretBundle. The DeletedSecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.DeletedSecretBundle + :rtype: ~azure.keyvault.secrets.models.DeletedSecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -595,12 +591,12 @@ def update_secret( :param secret_version: The version of the secret. Required. :type secret_version: str :param parameters: The parameters for update secret operation. Required. - :type parameters: ~azure.keyvault.secrets._generated.models.SecretUpdateParameters + :type parameters: ~azure.keyvault.secrets.models.SecretUpdateParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -630,7 +626,7 @@ def update_secret( Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -660,7 +656,7 @@ def update_secret( Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -684,9 +680,9 @@ def update_secret( :type secret_version: str :param parameters: The parameters for update secret operation. Is one of the following types: SecretUpdateParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.secrets._generated.models.SecretUpdateParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.secrets.models.SecretUpdateParameters or JSON or IO[bytes] :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -766,7 +762,7 @@ def get_secret(self, secret_name: str, secret_version: str, **kwargs: Any) -> _m specified, the latest version of the secret is returned. Required. :type secret_version: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -835,7 +831,7 @@ def get_secrets(self, *, maxresults: Optional[int] = None, **kwargs: Any) -> Ite service will return up to 25 results. Default value is None. :paramtype maxresults: int :return: An iterator like instance of SecretItem - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.secrets._generated.models.SecretItem] + :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.secrets.models.SecretItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} @@ -891,7 +887,7 @@ def prepare_request(next_link=None): def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize(List[_models.SecretItem], deserialized["value"]) + list_of_elem = _deserialize(List[_models.SecretItem], deserialized.get("value", [])) if cls: list_of_elem = cls(list_of_elem) # type: ignore return deserialized.get("nextLink") or None, iter(list_of_elem) @@ -929,7 +925,7 @@ def get_secret_versions( service will return up to 25 results. Default value is None. :paramtype maxresults: int :return: An iterator like instance of SecretItem - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.secrets._generated.models.SecretItem] + :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.secrets.models.SecretItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} @@ -986,7 +982,7 @@ def prepare_request(next_link=None): def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize(List[_models.SecretItem], deserialized["value"]) + list_of_elem = _deserialize(List[_models.SecretItem], deserialized.get("value", [])) if cls: list_of_elem = cls(list_of_elem) # type: ignore return deserialized.get("nextLink") or None, iter(list_of_elem) @@ -1022,7 +1018,7 @@ def get_deleted_secrets( service will return up to 25 results. Default value is None. :paramtype maxresults: int :return: An iterator like instance of DeletedSecretItem - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.secrets._generated.models.DeletedSecretItem] + :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.secrets.models.DeletedSecretItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} @@ -1078,7 +1074,7 @@ def prepare_request(next_link=None): def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize(List[_models.DeletedSecretItem], deserialized["value"]) + list_of_elem = _deserialize(List[_models.DeletedSecretItem], deserialized.get("value", [])) if cls: list_of_elem = cls(list_of_elem) # type: ignore return deserialized.get("nextLink") or None, iter(list_of_elem) @@ -1111,7 +1107,7 @@ def get_deleted_secret(self, secret_name: str, **kwargs: Any) -> _models.Deleted :param secret_name: The name of the secret. Required. :type secret_name: str :return: DeletedSecretBundle. The DeletedSecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.DeletedSecretBundle + :rtype: ~azure.keyvault.secrets.models.DeletedSecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -1234,7 +1230,7 @@ def recover_deleted_secret(self, secret_name: str, **kwargs: Any) -> _models.Sec :param secret_name: The name of the deleted secret. Required. :type secret_name: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -1300,7 +1296,7 @@ def backup_secret(self, secret_name: str, **kwargs: Any) -> _models.BackupSecret :param secret_name: The name of the secret. Required. :type secret_name: str :return: BackupSecretResult. The BackupSecretResult is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.BackupSecretResult + :rtype: ~azure.keyvault.secrets.models.BackupSecretResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -1366,12 +1362,12 @@ def restore_secret( secrets/restore permission. :param parameters: The parameters to restore the secret. Required. - :type parameters: ~azure.keyvault.secrets._generated.models.SecretRestoreParameters + :type parameters: ~azure.keyvault.secrets.models.SecretRestoreParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1390,7 +1386,7 @@ def restore_secret( Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1409,7 +1405,7 @@ def restore_secret( Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1424,9 +1420,9 @@ def restore_secret( :param parameters: The parameters to restore the secret. Is one of the following types: SecretRestoreParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.secrets._generated.models.SecretRestoreParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.secrets.models.SecretRestoreParameters or JSON or IO[bytes] :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_operations/_patch.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_operations/_patch.py similarity index 61% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_operations/_patch.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_operations/_patch.py index f7dd32510333..8bcb627aa475 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_operations/_patch.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_operations/_patch.py @@ -1,7 +1,8 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ +# 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. +# -------------------------------------------------------------------------- """Customize generated code here. Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_patch.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_patch.py similarity index 61% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_patch.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_patch.py index f7dd32510333..8bcb627aa475 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_patch.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_patch.py @@ -1,7 +1,8 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ +# 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. +# -------------------------------------------------------------------------- """Customize generated code here. Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_sdk_moniker.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_sdk_moniker.py deleted file mode 100644 index 43fd4b4a87ac..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_sdk_moniker.py +++ /dev/null @@ -1,7 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from ._version import VERSION - -SDK_MONIKER = f"keyvault-secrets/{VERSION}" diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_serialization.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_serialization.py similarity index 98% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_serialization.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_serialization.py index a066e16a64dd..eb86ea23c965 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_serialization.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_serialization.py @@ -1,28 +1,10 @@ -# pylint: disable=too-many-lines +# pylint: disable=line-too-long,useless-suppression,too-many-lines +# coding=utf-8 # -------------------------------------------------------------------------- -# # Copyright (c) Microsoft Corporation. All rights reserved. -# -# The MIT License (MIT) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the ""Software""), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. -# +# 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. # -------------------------------------------------------------------------- # pyright: reportUnnecessaryTypeIgnoreComment=false @@ -411,7 +393,7 @@ def from_dict( :param function key_extractors: A key extractor function. :param str content_type: JSON by default, set application/xml if XML. :returns: An instance of this model - :raises: DeserializationError if something went wrong + :raises DeserializationError: if something went wrong :rtype: Self """ deserializer = Deserializer(cls._infer_class_models()) @@ -1361,7 +1343,7 @@ def xml_key_extractor(attr, attr_desc, data): # pylint: disable=unused-argument # Iter and wrapped, should have found one node only (the wrap one) if len(children) != 1: raise DeserializationError( - "Tried to deserialize an array not wrapped, and found several nodes '{}'. Maybe you should declare this array as wrapped?".format( # pylint: disable=line-too-long + "Tried to deserialize an array not wrapped, and found several nodes '{}'. Maybe you should declare this array as wrapped?".format( xml_name ) ) diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/__init__.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/__init__.py deleted file mode 100644 index 4bcf3faed073..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/__init__.py +++ /dev/null @@ -1,77 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from typing import Optional -from urllib import parse - -from .challenge_auth_policy import ChallengeAuthPolicy -from .client_base import KeyVaultClientBase -from .http_challenge import HttpChallenge -from . import http_challenge_cache - -HttpChallengeCache = http_challenge_cache # to avoid aliasing pylint error (C4745) - - -__all__ = [ - "ChallengeAuthPolicy", - "HttpChallenge", - "HttpChallengeCache", - "KeyVaultClientBase", -] - -class KeyVaultResourceId(): - """Represents a Key Vault identifier and its parsed contents. - - :param str source_id: The complete identifier received from Key Vault - :param str vault_url: The vault URL - :param str name: The name extracted from the ID - :param str version: The version extracted from the ID - """ - - def __init__( - self, - source_id: str, - vault_url: str, - name: str, - version: "Optional[str]" = None, - ) -> None: - self.source_id = source_id - self.vault_url = vault_url - self.name = name - self.version = version - - -def parse_key_vault_id(source_id: str) -> KeyVaultResourceId: - try: - parsed_uri = parse.urlparse(source_id) - except Exception as exc: - raise ValueError(f"'{source_id}' is not a valid ID") from exc - if not (parsed_uri.scheme and parsed_uri.hostname): - raise ValueError(f"'{source_id}' is not a valid ID") - - path = list(filter(None, parsed_uri.path.split("/"))) - - if len(path) < 2 or len(path) > 3: - raise ValueError(f"'{source_id}' is not a valid ID") - - vault_url = f"{parsed_uri.scheme}://{parsed_uri.hostname}" - if parsed_uri.port: - vault_url += f":{parsed_uri.port}" - - return KeyVaultResourceId( - source_id=source_id, - vault_url=vault_url, - name=path[1], - version=path[2] if len(path) == 3 else None, - ) - - -try: - # pylint:disable=unused-import - from .async_challenge_auth_policy import AsyncChallengeAuthPolicy - from .async_client_base import AsyncKeyVaultClientBase - - __all__.extend(["AsyncChallengeAuthPolicy", "AsyncKeyVaultClientBase"]) -except (SyntaxError, ImportError): - pass diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/_polling.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/_polling.py deleted file mode 100644 index d4b83a0eca57..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/_polling.py +++ /dev/null @@ -1,142 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import logging -import threading -import uuid -from typing import Any, Callable, cast, Optional - -from azure.core.exceptions import ResourceNotFoundError, HttpResponseError -from azure.core.pipeline import PipelineResponse -from azure.core.pipeline.transport import HttpTransport -from azure.core.polling import PollingMethod, LROPoller, NoPolling - -from azure.core.tracing.decorator import distributed_trace -from azure.core.tracing.common import with_current_context - -logger = logging.getLogger(__name__) - - -class KeyVaultOperationPoller(LROPoller): - """Poller for long running operations where calling result() doesn't wait for operation to complete. - - :param polling_method: The poller's polling method. - :type polling_method: ~azure.core.polling.PollingMethod - """ - - def __init__(self, polling_method: PollingMethod) -> None: - super(KeyVaultOperationPoller, self).__init__(None, None, lambda *_: None, NoPolling()) - self._polling_method = polling_method - - # pylint: disable=arguments-differ - def result(self) -> "Any": # type: ignore - """Returns a representation of the final resource without waiting for the operation to complete. - - :returns: The deserialized resource of the long running operation - :rtype: Any - - :raises ~azure.core.exceptions.HttpResponseError: Server problem with the query. - """ - return self._polling_method.resource() - - @distributed_trace - def wait(self, timeout: Optional[float] = None) -> None: - """Wait on the long running operation for a number of seconds. - - You can check if this call has ended with timeout with the "done()" method. - - :param float timeout: Period of time to wait for the long running operation to complete (in seconds). - - :raises ~azure.core.exceptions.HttpResponseError: Server problem with the query. - """ - - if not self._polling_method.finished(): - self._done = threading.Event() - self._thread = threading.Thread( - target=with_current_context(self._start), name=f"KeyVaultOperationPoller({uuid.uuid4()})" - ) - self._thread.daemon = True - self._thread.start() - - if self._thread is None: - return - self._thread.join(timeout=timeout) - try: - # Let's handle possible None in forgiveness here - raise self._exception # type: ignore - except TypeError: # Was None - pass - - -class DeleteRecoverPollingMethod(PollingMethod): - """Poller for deleting resources, and recovering deleted resources, in vaults with soft-delete enabled. - - This works by polling for the existence of the deleted or recovered resource. When a resource is deleted, Key Vault - immediately removes it from its collection. However, the resource will not immediately appear in the deleted - collection. Key Vault will therefore respond 404 to GET requests for the deleted resource; when it responds 2xx, - the resource exists in the deleted collection i.e. its deletion is complete. - - Similarly, while recovering a deleted resource, Key Vault will respond 404 to GET requests for the non-deleted - resource; when it responds 2xx, the resource exists in the non-deleted collection, i.e. its recovery is complete. - - :param pipeline_response: The operation's original pipeline response. - :type pipeline_response: PipelineResponse - :param command: A callable to invoke when polling. - :type command: Callable - :param final_resource: The final resource returned by the polling operation. - :type final_resource: Any - :param bool finished: Whether or not the polling operation is completed. - :param int interval: The polling interval, in seconds. - """ - def __init__( - self, - pipeline_response: PipelineResponse, - command: Callable, - final_resource: Any, - finished: bool, - interval: int = 2 - ) -> None: - self._pipeline_response = pipeline_response - self._command = command - self._resource = final_resource - self._polling_interval = interval - self._finished = finished - - def _update_status(self) -> None: - try: - self._command() - self._finished = True - except ResourceNotFoundError: - pass - except HttpResponseError as e: - # If we are polling on get_deleted_* and we don't have get permissions, we will get - # ResourceNotFoundError until the resource is recovered, at which point we'll get a 403. - if e.status_code == 403: - self._finished = True - else: - raise - - def initialize(self, client: Any, initial_response: Any, deserialization_callback: Callable) -> None: - pass - - def run(self) -> None: - try: - while not self.finished(): - self._update_status() - if not self.finished(): - # We should always ask the client's transport to sleep, instead of sleeping directly - transport: HttpTransport = cast(HttpTransport, self._pipeline_response.context.transport) - transport.sleep(self._polling_interval) - except Exception as e: - logger.warning(str(e)) - raise - - def finished(self) -> bool: - return self._finished - - def resource(self) -> Any: - return self._resource - - def status(self) -> str: - return "finished" if self._finished else "polling" diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/_polling_async.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/_polling_async.py deleted file mode 100644 index a089567b7c1f..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/_polling_async.py +++ /dev/null @@ -1,87 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import logging -from typing import Any, Callable, cast - -from azure.core.exceptions import ResourceNotFoundError, HttpResponseError -from azure.core.pipeline import PipelineResponse -from azure.core.pipeline.transport import AsyncHttpTransport -from azure.core.polling import AsyncPollingMethod - -logger = logging.getLogger(__name__) - - -class AsyncDeleteRecoverPollingMethod(AsyncPollingMethod): - """Poller for deleting resources, and recovering deleted resources, in vaults with soft-delete enabled. - - This works by polling for the existence of the deleted or recovered resource. When a resource is deleted, Key Vault - immediately removes it from its collection. However, the resource will not immediately appear in the deleted - collection. Key Vault will therefore respond 404 to GET requests for the deleted resource; when it responds 2xx, - the resource exists in the deleted collection i.e. its deletion is complete. - - Similarly, while recovering a deleted resource, Key Vault will respond 404 to GET requests for the non-deleted - resource; when it responds 2xx, the resource exists in the non-deleted collection, i.e. its recovery is complete. - - :param pipeline_response: The operation's original pipeline response. - :type pipeline_response: PipelineResponse - :param command: An awaitable to invoke when polling. - :type command: Callable - :param final_resource: The final resource returned by the polling operation. - :type final_resource: Any - :param bool finished: Whether or not the polling operation is completed. - :param int interval: The polling interval, in seconds. - """ - - def __init__( - self, - pipeline_response: PipelineResponse, - command: Callable, - final_resource: Any, - finished: bool, - interval: int = 2 - ) -> None: - self._pipeline_response = pipeline_response - self._command = command - self._resource = final_resource - self._polling_interval = interval - self._finished = finished - - def initialize(self, client, initial_response, deserialization_callback): - pass - - async def _update_status(self) -> None: - try: - await self._command() - self._finished = True - except ResourceNotFoundError: - pass - except HttpResponseError as e: - # If we are polling on get_deleted_* and we don't have get permissions, we will get - # ResourceNotFoundError until the resource is recovered, at which point we'll get a 403. - if e.status_code == 403: - self._finished = True - else: - raise - - async def run(self) -> None: - try: - while not self.finished(): - await self._update_status() - if not self.finished(): - # We should always ask the client's transport to sleep, instead of sleeping directly - transport: AsyncHttpTransport = cast(AsyncHttpTransport, self._pipeline_response.context.transport) - await transport.sleep(self._polling_interval) - except Exception as e: - logger.warning(str(e)) - raise - - def finished(self) -> bool: - return self._finished - - def resource(self) -> Any: - return self._resource - - def status(self) -> str: - return "finished" if self._finished else "polling" diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/async_challenge_auth_policy.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/async_challenge_auth_policy.py deleted file mode 100644 index dad851f8f58c..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/async_challenge_auth_policy.py +++ /dev/null @@ -1,262 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -"""Policy implementing Key Vault's challenge authentication protocol. - -Normally the protocol is only used for the client's first service request, upon which: -1. The challenge authentication policy sends a copy of the request, without authorization or content. -2. Key Vault responds 401 with a header (the 'challenge') detailing how the client should authenticate such a request. -3. The policy authenticates according to the challenge and sends the original request with authorization. - -The policy caches the challenge and thus knows how to authenticate future requests. However, authentication -requirements can change. For example, a vault may move to a new tenant. In such a case the policy will attempt the -protocol again. -""" - -from copy import deepcopy -import sys -import time -from typing import Any, Callable, cast, Optional, overload, TypeVar, Union -from urllib.parse import urlparse - -from typing_extensions import ParamSpec - -from azure.core.credentials import AccessToken, AccessTokenInfo, TokenRequestOptions -from azure.core.credentials_async import AsyncSupportsTokenInfo, AsyncTokenCredential, AsyncTokenProvider -from azure.core.pipeline import PipelineRequest, PipelineResponse -from azure.core.pipeline.policies import AsyncBearerTokenCredentialPolicy -from azure.core.rest import AsyncHttpResponse, HttpRequest - -from .http_challenge import HttpChallenge -from . import http_challenge_cache as ChallengeCache -from .challenge_auth_policy import _enforce_tls, _has_claims, _update_challenge - -if sys.version_info < (3, 9): - from typing import Awaitable -else: - from collections.abc import Awaitable - - -P = ParamSpec("P") -T = TypeVar("T") - - -@overload -async def await_result(func: Callable[P, Awaitable[T]], *args: P.args, **kwargs: P.kwargs) -> T: ... - - -@overload -async def await_result(func: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T: ... - - -async def await_result(func: Callable[P, Union[T, Awaitable[T]]], *args: P.args, **kwargs: P.kwargs) -> T: - """If func returns an awaitable, await it. - - :param func: The function to run. - :type func: callable - :param args: The positional arguments to pass to the function. - :type args: list - :rtype: any - :return: The result of the function - """ - result = func(*args, **kwargs) - if isinstance(result, Awaitable): - return await result - return result - - -class AsyncChallengeAuthPolicy(AsyncBearerTokenCredentialPolicy): - """Policy for handling HTTP authentication challenges. - - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity.aio` - :type credential: ~azure.core.credentials_async.AsyncTokenProvider - """ - - def __init__(self, credential: AsyncTokenProvider, *scopes: str, **kwargs: Any) -> None: - # Pass `enable_cae` so `enable_cae=True` is always passed through self.authorize_request - super().__init__(credential, *scopes, enable_cae=True, **kwargs) - self._credential: AsyncTokenProvider = credential - self._token: Optional[Union["AccessToken", "AccessTokenInfo"]] = None - self._verify_challenge_resource = kwargs.pop("verify_challenge_resource", True) - self._request_copy: Optional[HttpRequest] = None - - async def send( - self, request: PipelineRequest[HttpRequest] - ) -> PipelineResponse[HttpRequest, AsyncHttpResponse]: - """Authorize request with a bearer token and send it to the next policy. - - We implement this method to account for the valid scenario where a Key Vault authentication challenge is - immediately followed by a CAE claims challenge. The base class's implementation would return the second 401 to - the caller, but we should handle that second challenge as well (and only return any third 401 response). - - :param request: The pipeline request object - :type request: ~azure.core.pipeline.PipelineRequest - :return: The pipeline response object - :rtype: ~azure.core.pipeline.PipelineResponse - """ - await await_result(self.on_request, request) - response: PipelineResponse[HttpRequest, AsyncHttpResponse] - try: - response = await self.next.send(request) - except Exception: # pylint:disable=broad-except - await await_result(self.on_exception, request) - raise - await await_result(self.on_response, request, response) - - if response.http_response.status_code == 401: - return await self.handle_challenge_flow(request, response) - return response - - async def handle_challenge_flow( - self, - request: PipelineRequest[HttpRequest], - response: PipelineResponse[HttpRequest, AsyncHttpResponse], - consecutive_challenge: bool = False, - ) -> PipelineResponse[HttpRequest, AsyncHttpResponse]: - """Handle the challenge flow of Key Vault and CAE authentication. - - :param request: The pipeline request object - :type request: ~azure.core.pipeline.PipelineRequest - :param response: The pipeline response object - :type response: ~azure.core.pipeline.PipelineResponse - :param bool consecutive_challenge: Whether the challenge is arriving immediately after another challenge. - Consecutive challenges can only be valid if a Key Vault challenge is followed by a CAE claims challenge. - True if the preceding challenge was a Key Vault challenge; False otherwise. - - :return: The pipeline response object - :rtype: ~azure.core.pipeline.PipelineResponse - """ - self._token = None # any cached token is invalid - if "WWW-Authenticate" in response.http_response.headers: - # If the previous challenge was a KV challenge and this one is too, return the 401 - claims_challenge = _has_claims(response.http_response.headers["WWW-Authenticate"]) - if consecutive_challenge and not claims_challenge: - return response - - request_authorized = await self.on_challenge(request, response) - if request_authorized: - # if we receive a challenge response, we retrieve a new token - # which matches the new target. In this case, we don't want to remove - # token from the request so clear the 'insecure_domain_change' tag - request.context.options.pop("insecure_domain_change", False) - try: - response = await self.next.send(request) - except Exception: # pylint:disable=broad-except - await await_result(self.on_exception, request) - raise - - # If consecutive_challenge == True, this could be a third consecutive 401 - if response.http_response.status_code == 401 and not consecutive_challenge: - # If the previous challenge wasn't from CAE, we can try this function one more time - if not claims_challenge: - return await self.handle_challenge_flow(request, response, consecutive_challenge=True) - await await_result(self.on_response, request, response) - return response - - - async def on_request(self, request: PipelineRequest) -> None: - _enforce_tls(request) - challenge = ChallengeCache.get_challenge_for_url(request.http_request.url) - if challenge: - # Note that if the vault has moved to a new tenant since our last request for it, this request will fail. - if self._need_new_token(): - # azure-identity credentials require an AADv2 scope but the challenge may specify an AADv1 resource - scope = challenge.get_scope() or challenge.get_resource() + "/.default" - await self._request_kv_token(scope, challenge) - - bearer_token = cast(Union[AccessToken, AccessTokenInfo], self._token).token - request.http_request.headers["Authorization"] = f"Bearer {bearer_token}" - return - - # else: discover authentication information by eliciting a challenge from Key Vault. Remove any request data, - # saving it for later. Key Vault will reject the request as unauthorized and respond with a challenge. - # on_challenge will parse that challenge, use the original request including the body, authorize the - # request, and tell super to send it again. - if request.http_request.content: - self._request_copy = request.http_request - bodiless_request = HttpRequest( - method=request.http_request.method, - url=request.http_request.url, - headers=deepcopy(request.http_request.headers), - ) - bodiless_request.headers["Content-Length"] = "0" - request.http_request = bodiless_request - - - async def on_challenge(self, request: PipelineRequest, response: PipelineResponse) -> bool: - try: - # CAE challenges may not include a scope or tenant; cache from the previous challenge to use if necessary - old_scope: Optional[str] = None - old_tenant: Optional[str] = None - cached_challenge = ChallengeCache.get_challenge_for_url(request.http_request.url) - if cached_challenge: - old_scope = cached_challenge.get_scope() or cached_challenge.get_resource() + "/.default" - old_tenant = cached_challenge.tenant_id - - challenge = _update_challenge(request, response) - # CAE challenges may not include a scope or tenant; use the previous challenge's values if necessary - if challenge.claims and old_scope: - challenge._parameters["scope"] = old_scope # pylint:disable=protected-access - challenge.tenant_id = old_tenant - # azure-identity credentials require an AADv2 scope but the challenge may specify an AADv1 resource - scope = challenge.get_scope() or challenge.get_resource() + "/.default" - except ValueError: - return False - - if self._verify_challenge_resource: - resource_domain = urlparse(scope).netloc - if not resource_domain: - raise ValueError(f"The challenge contains invalid scope '{scope}'.") - - request_domain = urlparse(request.http_request.url).netloc - if not request_domain.lower().endswith(f".{resource_domain.lower()}"): - raise ValueError( - f"The challenge resource '{resource_domain}' does not match the requested domain. Pass " - "`verify_challenge_resource=False` to your client's constructor to disable this verification. " - "See https://aka.ms/azsdk/blog/vault-uri for more information." - ) - - # If we had created a request copy in on_request, use it now to send along the original body content - if self._request_copy: - request.http_request = self._request_copy - - # The tenant parsed from AD FS challenges is "adfs"; we don't actually need a tenant for AD FS authentication - # For AD FS we skip cross-tenant authentication per https://github.com/Azure/azure-sdk-for-python/issues/28648 - if challenge.tenant_id and challenge.tenant_id.lower().endswith("adfs"): - await self.authorize_request(request, scope, claims=challenge.claims) - else: - await self.authorize_request( - request, scope, claims=challenge.claims, tenant_id=challenge.tenant_id - ) - - return True - - def _need_new_token(self) -> bool: - now = time.time() - refresh_on = getattr(self._token, "refresh_on", None) - return not self._token or (refresh_on and refresh_on <= now) or self._token.expires_on - now < 300 - - async def _request_kv_token(self, scope: str, challenge: HttpChallenge) -> None: - """Implementation of BearerTokenCredentialPolicy's _request_token method, but specific to Key Vault. - - :param str scope: The scope for which to request a token. - :param challenge: The challenge for the request being made. - :type challenge: HttpChallenge - """ - # Exclude tenant for AD FS authentication - exclude_tenant = challenge.tenant_id and challenge.tenant_id.lower().endswith("adfs") - # The AsyncSupportsTokenInfo protocol needs TokenRequestOptions for token requests instead of kwargs - if hasattr(self._credential, "get_token_info"): - options: TokenRequestOptions = {"enable_cae": True} - if challenge.tenant_id and not exclude_tenant: - options["tenant_id"] = challenge.tenant_id - self._token = await cast(AsyncSupportsTokenInfo, self._credential).get_token_info(scope, options=options) - else: - if exclude_tenant: - self._token = await self._credential.get_token(scope, enable_cae=True) - else: - self._token = await cast(AsyncTokenCredential, self._credential).get_token( - scope, tenant_id=challenge.tenant_id, enable_cae=True - ) diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/async_client_base.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/async_client_base.py deleted file mode 100644 index ebef8d98ca41..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/async_client_base.py +++ /dev/null @@ -1,117 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import sys -from typing import Any - -from azure.core.credentials_async import AsyncTokenCredential -from azure.core.pipeline.policies import HttpLoggingPolicy -from azure.core.rest import AsyncHttpResponse, HttpRequest -from azure.core.tracing.decorator_async import distributed_trace_async - -from . import AsyncChallengeAuthPolicy -from .client_base import ApiVersion, DEFAULT_VERSION, _format_api_version, _SERIALIZER -from .._sdk_moniker import SDK_MONIKER -from .._generated.aio import KeyVaultClient as _KeyVaultClient -from .._generated import models as _models - -if sys.version_info < (3, 9): - from typing import Awaitable -else: - from collections.abc import Awaitable - - -class AsyncKeyVaultClientBase(object): - # pylint:disable=protected-access - def __init__(self, vault_url: str, credential: AsyncTokenCredential, **kwargs: Any) -> None: - if not credential: - raise ValueError( - "credential should be an object supporting the AsyncTokenCredential protocol, " - "such as a credential from azure-identity" - ) - if not vault_url: - raise ValueError("vault_url must be the URL of an Azure Key Vault") - - try: - self.api_version = kwargs.pop("api_version", DEFAULT_VERSION) - # If API version was provided as an enum value, need to make a plain string for 3.11 compatibility - if hasattr(self.api_version, "value"): - self.api_version = self.api_version.value - self._vault_url = vault_url.strip(" /") - - client = kwargs.get("generated_client") - if client: - # caller provided a configured client -> only models left to initialize - self._client = client - models = kwargs.get("generated_models") - self._models = models or _models - return - - http_logging_policy = HttpLoggingPolicy(**kwargs) - http_logging_policy.allowed_header_names.update( - {"x-ms-keyvault-network-info", "x-ms-keyvault-region", "x-ms-keyvault-service-version"} - ) - - verify_challenge = kwargs.pop("verify_challenge_resource", True) - self._client = _KeyVaultClient( - credential=credential, - vault_base_url=self._vault_url, - api_version=self.api_version, - authentication_policy=AsyncChallengeAuthPolicy(credential, verify_challenge_resource=verify_challenge), - sdk_moniker=SDK_MONIKER, - http_logging_policy=http_logging_policy, - **kwargs - ) - self._models = _models - except ValueError as exc: - # Ignore pyright error that comes from not identifying ApiVersion as an iterable enum - raise NotImplementedError( - f"This package doesn't support API version '{self.api_version}'. " - + "Supported versions: " - + f"{', '.join(v.value for v in ApiVersion)}" # pyright: ignore[reportGeneralTypeIssues] - ) from exc - - @property - def vault_url(self) -> str: - return self._vault_url - - async def __aenter__(self) -> "AsyncKeyVaultClientBase": - await self._client.__aenter__() - return self - - async def __aexit__(self, *args: Any) -> None: - await self._client.__aexit__(*args) - - async def close(self) -> None: - """Close sockets opened by the client. - - Calling this method is unnecessary when using the client as a context manager. - """ - await self._client.close() - - @distributed_trace_async - def send_request( - self, request: HttpRequest, *, stream: bool = False, **kwargs: Any - ) -> Awaitable[AsyncHttpResponse]: - """Runs a network request using the client's existing pipeline. - - The request URL can be relative to the vault URL. The service API version used for the request is the same as - the client's unless otherwise specified. This method does not raise if the response is an error; to raise an - exception, call `raise_for_status()` on the returned response object. For more information about how to send - custom requests with this method, see https://aka.ms/azsdk/dpcodegen/python/send_request. - - :param request: The network request you want to make. - :type request: ~azure.core.rest.HttpRequest - - :keyword bool stream: Whether the response payload will be streamed. Defaults to False. - - :return: The response of your network call. Does not do error handling on your response. - :rtype: ~azure.core.rest.AsyncHttpResponse - """ - request_copy = _format_api_version(request, self.api_version) - path_format_arguments = { - "vaultBaseUrl": _SERIALIZER.url("vault_base_url", self._vault_url, "str", skip_quote=True), - } - request_copy.url = self._client._client.format_url(request_copy.url, **path_format_arguments) - return self._client._client.send_request(request_copy, stream=stream, **kwargs) diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/challenge_auth_policy.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/challenge_auth_policy.py deleted file mode 100644 index eb4073d0e699..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/challenge_auth_policy.py +++ /dev/null @@ -1,270 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -"""Policy implementing Key Vault's challenge authentication protocol. - -Normally the protocol is only used for the client's first service request, upon which: -1. The challenge authentication policy sends a copy of the request, without authorization or content. -2. Key Vault responds 401 with a header (the 'challenge') detailing how the client should authenticate such a request. -3. The policy authenticates according to the challenge and sends the original request with authorization. - -The policy caches the challenge and thus knows how to authenticate future requests. However, authentication -requirements can change. For example, a vault may move to a new tenant. In such a case the policy will attempt the -protocol again. -""" - -from copy import deepcopy -import time -from typing import Any, cast, Optional, Union -from urllib.parse import urlparse - -from azure.core.credentials import ( - AccessToken, - AccessTokenInfo, - TokenCredential, - TokenProvider, - TokenRequestOptions, - SupportsTokenInfo, -) -from azure.core.exceptions import ServiceRequestError -from azure.core.pipeline import PipelineRequest, PipelineResponse -from azure.core.pipeline.policies import BearerTokenCredentialPolicy -from azure.core.rest import HttpRequest, HttpResponse - -from .http_challenge import HttpChallenge -from . import http_challenge_cache as ChallengeCache - - -def _enforce_tls(request: PipelineRequest) -> None: - if not request.http_request.url.lower().startswith("https"): - raise ServiceRequestError( - "Bearer token authentication is not permitted for non-TLS protected (non-https) URLs." - ) - - -def _has_claims(challenge: str) -> bool: - """Check if a challenge header contains claims. - - :param challenge: The challenge header to check. - :type challenge: str - - :returns: True if the challenge contains claims; False otherwise. - :rtype: bool - """ - # Split the challenge into its scheme and parameters, then check if any parameter contains claims - split_challenge = challenge.strip().split(" ", 1) - return any("claims=" in item for item in split_challenge[1].split(",")) - - -def _update_challenge(request: PipelineRequest, challenger: PipelineResponse) -> HttpChallenge: - """Parse challenge from a challenge response, cache it, and return it. - - :param request: The pipeline request that prompted the challenge response. - :type request: ~azure.core.pipeline.PipelineRequest - :param challenger: The pipeline response containing the authentication challenge. - :type challenger: ~azure.core.pipeline.PipelineResponse - - :returns: An HttpChallenge object representing the authentication challenge. - :rtype: HttpChallenge - """ - - challenge = HttpChallenge( - request.http_request.url, - challenger.http_response.headers.get("WWW-Authenticate"), - response_headers=challenger.http_response.headers, - ) - ChallengeCache.set_challenge_for_url(request.http_request.url, challenge) - return challenge - - -class ChallengeAuthPolicy(BearerTokenCredentialPolicy): - """Policy for handling HTTP authentication challenges. - - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity` - :type credential: ~azure.core.credentials.TokenProvider - :param str scopes: Lets you specify the type of access needed. - """ - - def __init__(self, credential: TokenProvider, *scopes: str, **kwargs: Any) -> None: - # Pass `enable_cae` so `enable_cae=True` is always passed through self.authorize_request - super(ChallengeAuthPolicy, self).__init__(credential, *scopes, enable_cae=True, **kwargs) - self._credential: TokenProvider = credential - self._token: Optional[Union["AccessToken", "AccessTokenInfo"]] = None - self._verify_challenge_resource = kwargs.pop("verify_challenge_resource", True) - self._request_copy: Optional[HttpRequest] = None - - def send(self, request: PipelineRequest[HttpRequest]) -> PipelineResponse[HttpRequest, HttpResponse]: - """Authorize request with a bearer token and send it to the next policy. - - We implement this method to account for the valid scenario where a Key Vault authentication challenge is - immediately followed by a CAE claims challenge. The base class's implementation would return the second 401 to - the caller, but we should handle that second challenge as well (and only return any third 401 response). - - :param request: The pipeline request object - :type request: ~azure.core.pipeline.PipelineRequest - - :return: The pipeline response object - :rtype: ~azure.core.pipeline.PipelineResponse - """ - self.on_request(request) - try: - response = self.next.send(request) - except Exception: # pylint:disable=broad-except - self.on_exception(request) - raise - - self.on_response(request, response) - if response.http_response.status_code == 401: - return self.handle_challenge_flow(request, response) - return response - - def handle_challenge_flow( - self, - request: PipelineRequest[HttpRequest], - response: PipelineResponse[HttpRequest, HttpResponse], - consecutive_challenge: bool = False, - ) -> PipelineResponse[HttpRequest, HttpResponse]: - """Handle the challenge flow of Key Vault and CAE authentication. - - :param request: The pipeline request object - :type request: ~azure.core.pipeline.PipelineRequest - :param response: The pipeline response object - :type response: ~azure.core.pipeline.PipelineResponse - :param bool consecutive_challenge: Whether the challenge is arriving immediately after another challenge. - Consecutive challenges can only be valid if a Key Vault challenge is followed by a CAE claims challenge. - True if the preceding challenge was a Key Vault challenge; False otherwise. - - :return: The pipeline response object - :rtype: ~azure.core.pipeline.PipelineResponse - """ - self._token = None # any cached token is invalid - if "WWW-Authenticate" in response.http_response.headers: - # If the previous challenge was a KV challenge and this one is too, return the 401 - claims_challenge = _has_claims(response.http_response.headers["WWW-Authenticate"]) - if consecutive_challenge and not claims_challenge: - return response - - request_authorized = self.on_challenge(request, response) - if request_authorized: - # if we receive a challenge response, we retrieve a new token - # which matches the new target. In this case, we don't want to remove - # token from the request so clear the 'insecure_domain_change' tag - request.context.options.pop("insecure_domain_change", False) - try: - response = self.next.send(request) - except Exception: # pylint:disable=broad-except - self.on_exception(request) - raise - - # If consecutive_challenge == True, this could be a third consecutive 401 - if response.http_response.status_code == 401 and not consecutive_challenge: - # If the previous challenge wasn't from CAE, we can try this function one more time - if not claims_challenge: - return self.handle_challenge_flow(request, response, consecutive_challenge=True) - self.on_response(request, response) - return response - - def on_request(self, request: PipelineRequest) -> None: - _enforce_tls(request) - challenge = ChallengeCache.get_challenge_for_url(request.http_request.url) - if challenge: - # Note that if the vault has moved to a new tenant since our last request for it, this request will fail. - if self._need_new_token: - # azure-identity credentials require an AADv2 scope but the challenge may specify an AADv1 resource - scope = challenge.get_scope() or challenge.get_resource() + "/.default" - self._request_kv_token(scope, challenge) - - bearer_token = cast(Union["AccessToken", "AccessTokenInfo"], self._token).token - request.http_request.headers["Authorization"] = f"Bearer {bearer_token}" - return - - # else: discover authentication information by eliciting a challenge from Key Vault. Remove any request data, - # saving it for later. Key Vault will reject the request as unauthorized and respond with a challenge. - # on_challenge will parse that challenge, use the original request including the body, authorize the - # request, and tell super to send it again. - if request.http_request.content: - self._request_copy = request.http_request - bodiless_request = HttpRequest( - method=request.http_request.method, - url=request.http_request.url, - headers=deepcopy(request.http_request.headers), - ) - bodiless_request.headers["Content-Length"] = "0" - request.http_request = bodiless_request - - def on_challenge(self, request: PipelineRequest, response: PipelineResponse) -> bool: - try: - # CAE challenges may not include a scope or tenant; cache from the previous challenge to use if necessary - old_scope: Optional[str] = None - old_tenant: Optional[str] = None - cached_challenge = ChallengeCache.get_challenge_for_url(request.http_request.url) - if cached_challenge: - old_scope = cached_challenge.get_scope() or cached_challenge.get_resource() + "/.default" - old_tenant = cached_challenge.tenant_id - - challenge = _update_challenge(request, response) - # CAE challenges may not include a scope or tenant; use the previous challenge's values if necessary - if challenge.claims and old_scope: - challenge._parameters["scope"] = old_scope # pylint:disable=protected-access - challenge.tenant_id = old_tenant - # azure-identity credentials require an AADv2 scope but the challenge may specify an AADv1 resource - scope = challenge.get_scope() or challenge.get_resource() + "/.default" - except ValueError: - return False - - if self._verify_challenge_resource: - resource_domain = urlparse(scope).netloc - if not resource_domain: - raise ValueError(f"The challenge contains invalid scope '{scope}'.") - - request_domain = urlparse(request.http_request.url).netloc - if not request_domain.lower().endswith(f".{resource_domain.lower()}"): - raise ValueError( - f"The challenge resource '{resource_domain}' does not match the requested domain. Pass " - "`verify_challenge_resource=False` to your client's constructor to disable this verification. " - "See https://aka.ms/azsdk/blog/vault-uri for more information." - ) - - # If we had created a request copy in on_request, use it now to send along the original body content - if self._request_copy: - request.http_request = self._request_copy - - # The tenant parsed from AD FS challenges is "adfs"; we don't actually need a tenant for AD FS authentication - # For AD FS we skip cross-tenant authentication per https://github.com/Azure/azure-sdk-for-python/issues/28648 - if challenge.tenant_id and challenge.tenant_id.lower().endswith("adfs"): - self.authorize_request(request, scope, claims=challenge.claims) - else: - self.authorize_request(request, scope, claims=challenge.claims, tenant_id=challenge.tenant_id) - - return True - - @property - def _need_new_token(self) -> bool: - now = time.time() - refresh_on = getattr(self._token, "refresh_on", None) - return not self._token or (refresh_on and refresh_on <= now) or self._token.expires_on - now < 300 - - def _request_kv_token(self, scope: str, challenge: HttpChallenge) -> None: - """Implementation of BearerTokenCredentialPolicy's _request_token method, but specific to Key Vault. - - :param str scope: The scope for which to request a token. - :param challenge: The challenge for the request being made. - :type challenge: HttpChallenge - """ - # Exclude tenant for AD FS authentication - exclude_tenant = challenge.tenant_id and challenge.tenant_id.lower().endswith("adfs") - # The SupportsTokenInfo protocol needs TokenRequestOptions for token requests instead of kwargs - if hasattr(self._credential, "get_token_info"): - options: TokenRequestOptions = {"enable_cae": True} - if challenge.tenant_id and not exclude_tenant: - options["tenant_id"] = challenge.tenant_id - self._token = cast(SupportsTokenInfo, self._credential).get_token_info(scope, options=options) - else: - if exclude_tenant: - self._token = self._credential.get_token(scope, enable_cae=True) - else: - self._token = cast(TokenCredential, self._credential).get_token( - scope, tenant_id=challenge.tenant_id, enable_cae=True - ) diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/client_base.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/client_base.py deleted file mode 100644 index 38ad2ee6b385..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/client_base.py +++ /dev/null @@ -1,161 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from copy import deepcopy -from enum import Enum -from typing import Any -from urllib.parse import urlparse - -from azure.core import CaseInsensitiveEnumMeta -from azure.core.credentials import TokenCredential -from azure.core.pipeline.policies import HttpLoggingPolicy -from azure.core.rest import HttpRequest, HttpResponse -from azure.core.tracing.decorator import distributed_trace - -from . import ChallengeAuthPolicy -from .._generated import KeyVaultClient as _KeyVaultClient -from .._generated import models as _models -from .._generated._serialization import Serializer -from .._sdk_moniker import SDK_MONIKER - - -class ApiVersion(str, Enum, metaclass=CaseInsensitiveEnumMeta): - """Key Vault API versions supported by this package""" - - #: this is the default version - V7_6_PREVIEW_2 = "7.6-preview.2" - V7_5 = "7.5" - V7_4 = "7.4" - V7_3 = "7.3" - V7_2 = "7.2" - V7_1 = "7.1" - V7_0 = "7.0" - V2016_10_01 = "2016-10-01" - - -DEFAULT_VERSION = ApiVersion.V7_6_PREVIEW_2 - -_SERIALIZER = Serializer() -_SERIALIZER.client_side_validation = False - - -def _format_api_version(request: HttpRequest, api_version: str) -> HttpRequest: - """Returns a request copy that includes an api-version query parameter if one wasn't originally present. - - :param request: The HTTP request being sent. - :type request: ~azure.core.rest.HttpRequest - :param str api_version: The service API version that the request should include. - - :returns: A copy of the request that includes an api-version query parameter. - :rtype: azure.core.rest.HttpRequest - """ - request_copy = deepcopy(request) - params = {"api-version": api_version} # By default, we want to use the client's API version - query = urlparse(request_copy.url).query - - if query: - request_copy.url = request_copy.url.partition("?")[0] - existing_params = {p[0]: p[-1] for p in [p.partition("=") for p in query.split("&")]} - params.update(existing_params) # If an api-version was provided, this will overwrite our default - - # Reconstruct the query parameters onto the URL - query_params = [] - for k, v in params.items(): - query_params.append("{}={}".format(k, v)) - query = "?" + "&".join(query_params) - request_copy.url = request_copy.url + query - return request_copy - - -class KeyVaultClientBase(object): - # pylint:disable=protected-access - def __init__(self, vault_url: str, credential: TokenCredential, **kwargs: Any) -> None: - if not credential: - raise ValueError( - "credential should be an object supporting the TokenCredential protocol, " - "such as a credential from azure-identity" - ) - if not vault_url: - raise ValueError("vault_url must be the URL of an Azure Key Vault") - - try: - self.api_version = kwargs.pop("api_version", DEFAULT_VERSION) - # If API version was provided as an enum value, need to make a plain string for 3.11 compatibility - if hasattr(self.api_version, "value"): - self.api_version = self.api_version.value - self._vault_url = vault_url.strip(" /") - - client = kwargs.get("generated_client") - if client: - # caller provided a configured client -> only models left to initialize - self._client = client - models = kwargs.get("generated_models") - self._models = models or _models - return - - http_logging_policy = HttpLoggingPolicy(**kwargs) - http_logging_policy.allowed_header_names.update( - {"x-ms-keyvault-network-info", "x-ms-keyvault-region", "x-ms-keyvault-service-version"} - ) - - verify_challenge = kwargs.pop("verify_challenge_resource", True) - self._client = _KeyVaultClient( - credential=credential, - vault_base_url=self._vault_url, - api_version=self.api_version, - authentication_policy=ChallengeAuthPolicy(credential, verify_challenge_resource=verify_challenge), - sdk_moniker=SDK_MONIKER, - http_logging_policy=http_logging_policy, - **kwargs, - ) - self._models = _models - except ValueError as exc: - # Ignore pyright error that comes from not identifying ApiVersion as an iterable enum - raise NotImplementedError( - f"This package doesn't support API version '{self.api_version}'. " - + "Supported versions: " - + f"{', '.join(v.value for v in ApiVersion)}" # pyright: ignore[reportGeneralTypeIssues] - ) from exc - - @property - def vault_url(self) -> str: - return self._vault_url - - def __enter__(self) -> "KeyVaultClientBase": - self._client.__enter__() - return self - - def __exit__(self, *args: Any) -> None: - self._client.__exit__(*args) - - def close(self) -> None: - """Close sockets opened by the client. - - Calling this method is unnecessary when using the client as a context manager. - """ - self._client.close() - - @distributed_trace - def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: Any) -> HttpResponse: - """Runs a network request using the client's existing pipeline. - - The request URL can be relative to the vault URL. The service API version used for the request is the same as - the client's unless otherwise specified. This method does not raise if the response is an error; to raise an - exception, call `raise_for_status()` on the returned response object. For more information about how to send - custom requests with this method, see https://aka.ms/azsdk/dpcodegen/python/send_request. - - :param request: The network request you want to make. - :type request: ~azure.core.rest.HttpRequest - - :keyword bool stream: Whether the response payload will be streamed. Defaults to False. - - :return: The response of your network call. Does not do error handling on your response. - :rtype: ~azure.core.rest.HttpResponse - """ - request_copy = _format_api_version(request, self.api_version) - path_format_arguments = { - "vaultBaseUrl": _SERIALIZER.url("vault_base_url", self._vault_url, "str", skip_quote=True), - } - request_copy.url = self._client._client.format_url(request_copy.url, **path_format_arguments) - return self._client._client.send_request(request_copy, stream=stream, **kwargs) diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/http_challenge.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/http_challenge.py deleted file mode 100644 index 0320df5a868b..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/http_challenge.py +++ /dev/null @@ -1,182 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import base64 -from typing import Dict, MutableMapping, Optional -from urllib import parse - - -class HttpChallenge(object): - """An object representing the content of a Key Vault authentication challenge. - - :param str request_uri: The URI of the HTTP request that prompted this challenge. - :param str challenge: The WWW-Authenticate header of the challenge response. - :param response_headers: Optional. The headers attached to the challenge response. - :type response_headers: MutableMapping[str, str] or None - """ - - def __init__( - self, request_uri: str, challenge: str, response_headers: "Optional[MutableMapping[str, str]]" = None - ) -> None: - """Parses an HTTP WWW-Authentication Bearer challenge from a server. - - Example challenge with claims: - Bearer authorization="https://login.windows-ppe.net/", error="invalid_token", - error_description="User session has been revoked", - claims="eyJhY2Nlc3NfdG9rZW4iOnsibmJmIjp7ImVzc2VudGlhbCI6dHJ1ZSwgInZhbHVlIjoiMTYwMzc0MjgwMCJ9fX0=" - """ - self.source_authority = self._validate_request_uri(request_uri) - self.source_uri = request_uri - self._parameters: "Dict[str, str]" = {} - - # get the scheme of the challenge and remove from the challenge string - trimmed_challenge = self._validate_challenge(challenge) - split_challenge = trimmed_challenge.split(" ", 1) - self.scheme = split_challenge[0] - trimmed_challenge = split_challenge[1] - - self.claims = None - # split trimmed challenge into comma-separated name=value pairs. Values are expected - # to be surrounded by quotes which are stripped here. - for item in trimmed_challenge.split(","): - # Special case for claims, which can contain = symbols as padding. Assume at most one claim per challenge - if "claims=" in item: - encoded_claims = item[item.index("=") + 1 :].strip(" \"'") - padding_needed = -len(encoded_claims) % 4 - try: - decoded_claims = base64.urlsafe_b64decode(encoded_claims + "=" * padding_needed).decode() - self.claims = decoded_claims - except Exception: # pylint:disable=broad-except - continue - # process name=value pairs - else: - comps = item.split("=") - if len(comps) == 2: - key = comps[0].strip(' "') - value = comps[1].strip(' "') - if key: - self._parameters[key] = value - - # minimum set of parameters - if not self._parameters: - raise ValueError("Invalid challenge parameters") - - # must specify authorization or authorization_uri - if "authorization" not in self._parameters and "authorization_uri" not in self._parameters: - raise ValueError("Invalid challenge parameters") - - authorization_uri = self.get_authorization_server() - # the authorization server URI should look something like https://login.windows.net/tenant-id - raw_uri_path = str(parse.urlparse(authorization_uri).path) - uri_path = raw_uri_path.lstrip("/") - self.tenant_id = uri_path.split("/", maxsplit=1)[0] or None - - # if the response headers were supplied - if response_headers: - # get the message signing key and message key encryption key from the headers - self.server_signature_key = response_headers.get("x-ms-message-signing-key", None) - self.server_encryption_key = response_headers.get("x-ms-message-encryption-key", None) - - def is_bearer_challenge(self) -> bool: - """Tests whether the HttpChallenge is a Bearer challenge. - - :returns: True if the challenge is a Bearer challenge; False otherwise. - :rtype: bool - """ - if not self.scheme: - return False - - return self.scheme.lower() == "bearer" - - def is_pop_challenge(self) -> bool: - """Tests whether the HttpChallenge is a proof of possession challenge. - - :returns: True if the challenge is a proof of possession challenge; False otherwise. - :rtype: bool - """ - if not self.scheme: - return False - - return self.scheme.lower() == "pop" - - def get_value(self, key: str) -> "Optional[str]": - return self._parameters.get(key) - - def get_authorization_server(self) -> str: - """Returns the URI for the authorization server if present, otherwise an empty string. - - :returns: The URI for the authorization server if present, otherwise an empty string. - :rtype: str - """ - value = "" - for key in ["authorization_uri", "authorization"]: - value = self.get_value(key) or "" - if value: - break - return value - - def get_resource(self) -> str: - """Returns the resource if present, otherwise an empty string. - - :returns: The challenge resource if present, otherwise an empty string. - :rtype: str - """ - return self.get_value("resource") or "" - - def get_scope(self) -> str: - """Returns the scope if present, otherwise an empty string. - - :returns: The challenge scope if present, otherwise an empty string. - :rtype: str - """ - return self.get_value("scope") or "" - - def supports_pop(self) -> bool: - """Returns True if the challenge supports proof of possession token auth; False otherwise. - - :returns: True if the challenge supports proof of possession token auth; False otherwise. - :rtype: bool - """ - return self._parameters.get("supportspop", "").lower() == "true" - - def supports_message_protection(self) -> bool: - """Returns True if the challenge vault supports message protection; False otherwise. - - :returns: True if the challenge vault supports message protection; False otherwise. - :rtype: bool - """ - return self.supports_pop() and self.server_encryption_key and self.server_signature_key # type: ignore - - def _validate_challenge(self, challenge: str) -> str: # pylint:disable=bad-option-value,useless-option-value,no-self-use - """Verifies that the challenge is a valid auth challenge and returns the key=value pairs. - - :param str challenge: The WWW-Authenticate header of the challenge response. - - :returns: The challenge key/value pairs, with whitespace removed, as a string. - :rtype: str - """ - if not challenge: - raise ValueError("Challenge cannot be empty") - - return challenge.strip() - - def _validate_request_uri(self, uri: str) -> str: # pylint:disable=bad-option-value,useless-option-value,no-self-use - """Extracts the host authority from the given URI. - - :param str uri: The URI of the HTTP request that prompted the challenge. - - :returns: The challenge host authority. - :rtype: str - """ - if not uri: - raise ValueError("request_uri cannot be empty") - - parsed = parse.urlparse(uri) - if not parsed.netloc: - raise ValueError("request_uri must be an absolute URI") - - if parsed.scheme.lower() not in ["http", "https"]: - raise ValueError("request_uri must be HTTP or HTTPS") - - return parsed.netloc diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/http_challenge_cache.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/http_challenge_cache.py deleted file mode 100644 index f1448cc53391..000000000000 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/http_challenge_cache.py +++ /dev/null @@ -1,93 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import threading -from typing import Dict, Optional -from urllib import parse - -from .http_challenge import HttpChallenge - - -_cache: "Dict[str, HttpChallenge]" = {} -_lock = threading.Lock() - - -def get_challenge_for_url(url: str) -> "Optional[HttpChallenge]": - """Gets the challenge for the cached URL. - - :param str url: the URL the challenge is cached for. - - :returns: The challenge for the cached request URL, or None if the request URL isn't cached. - :rtype: HttpChallenge or None - """ - - if not url: - raise ValueError("URL cannot be None") - - key = _get_cache_key(url) - - with _lock: - return _cache.get(key) - - -def _get_cache_key(url: str) -> str: - """Use the URL's netloc as cache key except when the URL specifies the default port for its scheme. In that case - use the netloc without the port. That is to say, https://foo.bar and https://foo.bar:443 are considered equivalent. - - This equivalency prevents an unnecessary challenge when using Key Vault's paging API. The Key Vault client doesn't - specify ports, but Key Vault's next page links do, so a redundant challenge would otherwise be executed when the - client requests the next page. - - :param str url: The HTTP request URL. - - :returns: The URL's `netloc`, minus any port attached to the URL. - :rtype: str - """ - - parsed = parse.urlparse(url) - if parsed.scheme == "https" and parsed.port == 443: - return parsed.netloc[:-4] - return parsed.netloc - - -def remove_challenge_for_url(url: str) -> None: - """Removes the cached challenge for the specified URL. - - :param str url: the URL for which to remove the cached challenge - """ - if not url: - raise ValueError("URL cannot be empty") - - parsed = parse.urlparse(url) - - with _lock: - del _cache[parsed.netloc] - - -def set_challenge_for_url(url: str, challenge: "HttpChallenge") -> None: - """Caches the challenge for the specified URL. - - :param str url: the URL for which to cache the challenge - :param challenge: the challenge to cache - :type challenge: HttpChallenge - """ - if not url: - raise ValueError("URL cannot be empty") - - if not challenge: - raise ValueError("Challenge cannot be empty") - - src_url = parse.urlparse(url) - if src_url.netloc != challenge.source_authority: - raise ValueError("Source URL and Challenge URL do not match") - - with _lock: - _cache[src_url.netloc] = challenge - - -def clear() -> None: - """Clears the cache.""" - - with _lock: - _cache.clear() diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_vendor.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_vendor.py similarity index 100% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_vendor.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_vendor.py diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_version.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_version.py index f058fb2e3bd0..0d777283b3a2 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_version.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_version.py @@ -1,6 +1,9 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ +# 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. +# -------------------------------------------------------------------------- -VERSION = "4.10.0b2" +VERSION = "4.9.0b1" diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/__init__.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/__init__.py index 44967833f2df..8c996b993b8a 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/__init__.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/__init__.py @@ -1,7 +1,29 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from ._client import SecretClient +# 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. +# -------------------------------------------------------------------------- +# pylint: disable=wrong-import-position -__all__ = ["SecretClient"] +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from ._patch import * # pylint: disable=unused-wildcard-import + +from ._client import KeyVaultClient # type: ignore + +try: + from ._patch import __all__ as _patch_all + from ._patch import * +except ImportError: + _patch_all = [] +from ._patch import patch_sdk as _patch_sdk + +__all__ = [ + "KeyVaultClient", +] +__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore + +_patch_sdk() diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_client.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_client.py index 20904cf11646..86d6fc4a3056 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_client.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_client.py @@ -1,452 +1,103 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from datetime import datetime -from typing import Any, cast, Dict, Optional -from functools import partial +# 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 azure.core.tracing.decorator import distributed_trace -from azure.core.tracing.decorator_async import distributed_trace_async -from azure.core.async_paging import AsyncItemPaged +from copy import deepcopy +from typing import Any, Awaitable, TYPE_CHECKING +from typing_extensions import Self -from .._models import KeyVaultSecret, DeletedSecret, SecretProperties -from .._shared import AsyncKeyVaultClientBase -from .._shared._polling_async import AsyncDeleteRecoverPollingMethod +from azure.core import AsyncPipelineClient +from azure.core.pipeline import policies +from azure.core.rest import AsyncHttpResponse, HttpRequest +from .._serialization import Deserializer, Serializer +from ._configuration import KeyVaultClientConfiguration +from ._operations import KeyVaultClientOperationsMixin -class SecretClient(AsyncKeyVaultClientBase): - """A high-level asynchronous interface for managing a vault's secrets. +if TYPE_CHECKING: + from azure.core.credentials_async import AsyncTokenCredential - :param str vault_url: URL of the vault the client will access. This is also called the vault's "DNS Name". - You should validate that this URL references a valid Key Vault resource. See https://aka.ms/azsdk/blog/vault-uri - for details. - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity.aio` - :type credential: ~azure.core.credentials_async.AsyncTokenCredential - :keyword api_version: Version of the service API to use. Defaults to the most recent. - :paramtype api_version: ~azure.keyvault.secrets.ApiVersion or str - :keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key - Vault domain. Defaults to True. +class KeyVaultClient(KeyVaultClientOperationsMixin): + """The key vault client performs cryptographic key operations and vault operations against the Key + Vault service. - Example: - .. literalinclude:: ../tests/test_samples_secrets_async.py - :start-after: [START create_secret_client] - :end-before: [END create_secret_client] - :language: python - :caption: Create a new ``SecretClient`` - :dedent: 4 + :param vault_base_url: Required. + :type vault_base_url: str + :param credential: Credential used to authenticate requests to the service. Required. + :type credential: ~azure.core.credentials_async.AsyncTokenCredential + :keyword api_version: The API version to use for this operation. Default value is + "7.6-preview.2". Note that overriding this default value may result in unsupported behavior. + :paramtype api_version: str """ - # pylint:disable=protected-access - - @distributed_trace_async - async def get_secret(self, name: str, version: Optional[str] = None, **kwargs: Any) -> KeyVaultSecret: - """Get a secret. Requires the secrets/get permission. - - :param str name: The name of the secret - :param str version: (optional) Version of the secret to get. If unspecified, gets the latest version. - - :returns: The fetched secret. - :rtype: ~azure.keyvault.secrets.KeyVaultSecret - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the secret doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_secrets_async.py - :start-after: [START get_secret] - :end-before: [END get_secret] - :language: python - :caption: Get a secret - :dedent: 8 - """ - bundle = await self._client.get_secret(name, version or "", **kwargs) - return KeyVaultSecret._from_secret_bundle(bundle) - - @distributed_trace_async - async def set_secret( - self, - name: str, - value: str, - *, - enabled: Optional[bool] = None, - tags: Optional[Dict[str, str]] = None, - content_type: Optional[str] = None, - not_before: Optional[datetime] = None, - expires_on: Optional[datetime] = None, - **kwargs: Any, - ) -> KeyVaultSecret: - """Set a secret value. If `name` is in use, create a new version of the secret. If not, create a new secret. - - Requires secrets/set permission. - - :param str name: The name of the secret - :param str value: The value of the secret - - :keyword bool enabled: Whether the secret is enabled for use. - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: Dict[str, str] or None - :keyword str content_type: An arbitrary string indicating the type of the secret, e.g. 'password' - :keyword ~datetime.datetime not_before: Not before date of the secret in UTC - :keyword ~datetime.datetime expires_on: Expiry date of the secret in UTC - - :returns: The created or updated secret. - :rtype: ~azure.keyvault.secrets.KeyVaultSecret - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. literalinclude:: ../tests/test_samples_secrets_async.py - :start-after: [START set_secret] - :end-before: [END set_secret] - :language: python - :caption: Set a secret's value - :dedent: 8 - """ - if enabled is not None or not_before is not None or expires_on is not None: - attributes = self._models.SecretAttributes(enabled=enabled, not_before=not_before, expires=expires_on) - else: - attributes = None - - parameters = self._models.SecretSetParameters( - value=value, - tags=tags, - content_type=content_type, - secret_attributes=attributes - ) - - bundle = await self._client.set_secret( - name, - parameters=parameters, - **kwargs - ) - return KeyVaultSecret._from_secret_bundle(bundle) - - @distributed_trace_async - async def update_secret_properties( - self, - name: str, - version: Optional[str] = None, - *, - enabled: Optional[bool] = None, - tags: Optional[Dict[str, str]] = None, - content_type: Optional[str] = None, - not_before: Optional[datetime] = None, - expires_on: Optional[datetime] = None, - **kwargs: Any, - ) -> SecretProperties: - """Update properties of a secret other than its value. Requires secrets/set permission. - - This method updates properties of the secret, such as whether it's enabled, but can't change the secret's - value. Use :func:`set_secret` to change the secret's value. - - :param str name: Name of the secret - :param str version: (optional) Version of the secret to update. If unspecified, the latest version is updated. - - :keyword bool enabled: Whether the secret is enabled for use. - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: Dict[str, str] or None - :keyword str content_type: An arbitrary string indicating the type of the secret, e.g. 'password' - :keyword ~datetime.datetime not_before: Not before date of the secret in UTC - :keyword ~datetime.datetime expires_on: Expiry date of the secret in UTC - - :returns: The updated secret properties. - :rtype: ~azure.keyvault.secrets.SecretProperties - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the secret doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_secrets_async.py - :start-after: [START update_secret] - :end-before: [END update_secret] - :language: python - :caption: Updates a secret's attributes - :dedent: 8 - """ - if enabled is not None or not_before is not None or expires_on is not None: - attributes = self._models.SecretAttributes(enabled=enabled, not_before=not_before, expires=expires_on) - else: - attributes = None - - parameters = self._models.SecretUpdateParameters( - content_type=content_type, - secret_attributes=attributes, - tags=tags, - ) - - bundle = await self._client.update_secret( - name, - secret_version=version or "", - parameters=parameters, - **kwargs - ) - return SecretProperties._from_secret_bundle(bundle) # pylint: disable=protected-access - - @distributed_trace - def list_properties_of_secrets(self, **kwargs: Any) -> AsyncItemPaged[SecretProperties]: - """List identifiers and attributes of all secrets in the vault. Requires secrets/list permission. - - List items don't include secret values. Use :func:`get_secret` to get a secret's value. - - :returns: An iterator of secrets - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.secrets.SecretProperties] - - Example: - .. literalinclude:: ../tests/test_samples_secrets_async.py - :start-after: [START list_secrets] - :end-before: [END list_secrets] - :language: python - :caption: Lists all secrets - :dedent: 8 - """ - return self._client.get_secrets( - maxresults=kwargs.pop("max_page_size", None), - cls=lambda objs: [SecretProperties._from_secret_item(x) for x in objs], - **kwargs - ) - - @distributed_trace - def list_properties_of_secret_versions(self, name: str, **kwargs: Any) -> AsyncItemPaged[SecretProperties]: - """List properties of all versions of a secret, excluding their values. Requires secrets/list permission. - - List items don't include secret values. Use :func:`get_secret` to get a secret's value. - - :param str name: Name of the secret - - :returns: An iterator of secrets, excluding their values - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.secrets.SecretProperties] - - Example: - .. literalinclude:: ../tests/test_samples_secrets_async.py - :start-after: [START list_properties_of_secret_versions] - :end-before: [END list_properties_of_secret_versions] - :language: python - :caption: List all versions of a secret - :dedent: 8 - """ - return self._client.get_secret_versions( - name, - maxresults=kwargs.pop("max_page_size", None), - cls=lambda objs: [SecretProperties._from_secret_item(x) for x in objs], - **kwargs - ) - - @distributed_trace_async - async def backup_secret(self, name: str, **kwargs: Any) -> bytes: - """Back up a secret in a protected form useable only by Azure Key Vault. Requires secrets/backup permission. - - :param str name: Name of the secret to back up - - :returns: The backup result, in a protected bytes format that can only be used by Azure Key Vault. - :rtype: bytes - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the secret doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_secrets_async.py - :start-after: [START backup_secret] - :end-before: [END backup_secret] - :language: python - :caption: Back up a secret - :dedent: 8 + def __init__(self, vault_base_url: str, credential: "AsyncTokenCredential", **kwargs: Any) -> None: + _endpoint = "{vaultBaseUrl}" + self._config = KeyVaultClientConfiguration(vault_base_url=vault_base_url, credential=credential, **kwargs) + + _policies = kwargs.pop("policies", None) + if _policies is None: + _policies = [ + policies.RequestIdPolicy(**kwargs), + self._config.headers_policy, + self._config.user_agent_policy, + self._config.proxy_policy, + policies.ContentDecodePolicy(**kwargs), + self._config.redirect_policy, + self._config.retry_policy, + self._config.authentication_policy, + self._config.custom_hook_policy, + self._config.logging_policy, + policies.DistributedTracingPolicy(**kwargs), + policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None, + self._config.http_logging_policy, + ] + self._client: AsyncPipelineClient = AsyncPipelineClient(base_url=_endpoint, policies=_policies, **kwargs) + + self._serialize = Serializer() + self._deserialize = Deserializer() + self._serialize.client_side_validation = False + + def send_request( + self, request: HttpRequest, *, stream: bool = False, **kwargs: Any + ) -> Awaitable[AsyncHttpResponse]: + """Runs the network request through the client's chained policies. + + >>> from azure.core.rest import HttpRequest + >>> request = HttpRequest("GET", "https://www.example.org/") + + >>> response = await client.send_request(request) + + + For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request + + :param request: The network request you want to make. Required. + :type request: ~azure.core.rest.HttpRequest + :keyword bool stream: Whether the response payload will be streamed. Defaults to False. + :return: The response of your network call. Does not do error handling on your response. + :rtype: ~azure.core.rest.AsyncHttpResponse """ - backup_result = await self._client.backup_secret(name, **kwargs) - return cast(bytes, backup_result.value) - @distributed_trace_async - async def restore_secret_backup(self, backup: bytes, **kwargs: Any) -> SecretProperties: - """Restore a backed up secret. Requires the secrets/restore permission. + request_copy = deepcopy(request) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } - :param bytes backup: A secret backup as returned by :func:`backup_secret` + request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) + return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore - :returns: The restored secret - :rtype: ~azure.keyvault.secrets.SecretProperties + async def close(self) -> None: + await self._client.close() - :raises ~azure.core.exceptions.ResourceExistsError or ~azure.core.exceptions.HttpResponseError: - the former if the secret's name is already in use; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_secrets_async.py - :start-after: [START restore_secret_backup] - :end-before: [END restore_secret_backup] - :language: python - :caption: Restore a backed up secret - :dedent: 8 - """ - bundle = await self._client.restore_secret( - parameters=self._models.SecretRestoreParameters(secret_bundle_backup=backup), - **kwargs - ) - return SecretProperties._from_secret_bundle(bundle) - - @distributed_trace_async - async def delete_secret(self, name: str, **kwargs: Any) -> DeletedSecret: - """Delete all versions of a secret. Requires secrets/delete permission. - - If the vault has soft-delete enabled, deletion may take several seconds to complete. - - :param str name: Name of the secret to delete. - - :returns: The deleted secret. - :rtype: ~azure.keyvault.secrets.DeletedSecret - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the secret doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_secrets_async.py - :start-after: [START delete_secret] - :end-before: [END delete_secret] - :language: python - :caption: Delete a secret - :dedent: 8 - """ - polling_interval = kwargs.pop("_polling_interval", None) - if polling_interval is None: - polling_interval = 2 - # Ignore pyright warning about return type not being iterable because we use `cls` to return a tuple - pipeline_response, deleted_secret_bundle = await self._client.delete_secret( - secret_name=name, - cls=lambda pipeline_response, deserialized, _: (pipeline_response, deserialized), - **kwargs, - ) # pyright: ignore[reportGeneralTypeIssues] - deleted_secret = DeletedSecret._from_deleted_secret_bundle(deleted_secret_bundle) - - polling_method = AsyncDeleteRecoverPollingMethod( - # no recovery ID means soft-delete is disabled, in which case we initialize the poller as finished - pipeline_response=pipeline_response, - command=partial(self.get_deleted_secret, name=name, **kwargs), - final_resource=deleted_secret, - finished=deleted_secret.recovery_id is None, - interval=polling_interval, - ) - await polling_method.run() - - return polling_method.resource() - - @distributed_trace_async - async def get_deleted_secret(self, name: str, **kwargs: Any) -> DeletedSecret: - """Get a deleted secret. Possible only in vaults with soft-delete enabled. Requires secrets/get permission. - - :param str name: Name of the deleted secret - - :returns: The deleted secret. - :rtype: ~azure.keyvault.secrets.DeletedSecret - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the deleted secret doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_secrets_async.py - :start-after: [START get_deleted_secret] - :end-before: [END get_deleted_secret] - :language: python - :caption: Get a deleted secret - :dedent: 8 - """ - bundle = await self._client.get_deleted_secret(name, **kwargs) - return DeletedSecret._from_deleted_secret_bundle(bundle) - - @distributed_trace - def list_deleted_secrets(self, **kwargs: Any) -> AsyncItemPaged[DeletedSecret]: - """Lists all deleted secrets. Possible only in vaults with soft-delete enabled. - - Requires secrets/list permission. - - :returns: An iterator of deleted secrets, excluding their values - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.secrets.DeletedSecret] - - Example: - .. literalinclude:: ../tests/test_samples_secrets_async.py - :start-after: [START list_deleted_secrets] - :end-before: [END list_deleted_secrets] - :language: python - :caption: Lists deleted secrets - :dedent: 8 - """ - return self._client.get_deleted_secrets( - maxresults=kwargs.pop("max_page_size", None), - cls=lambda objs: [DeletedSecret._from_deleted_secret_item(x) for x in objs], - **kwargs - ) - - @distributed_trace_async - async def purge_deleted_secret(self, name: str, **kwargs: Any) -> None: - """Permanently delete a deleted secret. Possible only in vaults with soft-delete enabled. - - Performs an irreversible deletion of the specified secret, without possibility for recovery. The operation is - not available if the :py:attr:`~azure.keyvault.secrets.SecretProperties.recovery_level` does not specify - 'Purgeable'. This method is only necessary for purging a secret before its - :py:attr:`~azure.keyvault.secrets.DeletedSecret.scheduled_purge_date`. - - Requires secrets/purge permission. - - :param str name: Name of the deleted secret to purge - - :returns: None - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # if the vault has soft-delete enabled, purge permanently deletes the secret - # (with soft-delete disabled, delete_secret is permanent) - await secret_client.purge_deleted_secret("secret-name") - - """ - await self._client.purge_deleted_secret(name, **kwargs) - - @distributed_trace_async - async def recover_deleted_secret(self, name: str, **kwargs: Any) -> SecretProperties: - """Recover a deleted secret to its latest version. This is possible only in vaults with soft-delete enabled. - - Requires the secrets/recover permission. If the vault does not have soft-delete enabled, :func:`delete_secret` - is permanent, and this method will raise an error. Attempting to recover a non-deleted secret will also raise an - error. - - :param str name: Name of the deleted secret to recover - - :returns: The recovered secret's properties. - :rtype: ~azure.keyvault.secrets.SecretProperties - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. literalinclude:: ../tests/test_samples_secrets_async.py - :start-after: [START recover_deleted_secret] - :end-before: [END recover_deleted_secret] - :language: python - :caption: Recover a deleted secret - :dedent: 8 - """ - polling_interval = kwargs.pop("_polling_interval", None) - if polling_interval is None: - polling_interval = 2 - # Ignore pyright warning about return type not being iterable because we use `cls` to return a tuple - pipeline_response, recovered_secret_bundle = await self._client.recover_deleted_secret( - secret_name=name, - cls=lambda pipeline_response, deserialized, _: (pipeline_response, deserialized), - **kwargs, - ) # pyright: ignore[reportGeneralTypeIssues] - recovered_secret = SecretProperties._from_secret_bundle(recovered_secret_bundle) - - command = partial(self.get_secret, name=name, **kwargs) - polling_method = AsyncDeleteRecoverPollingMethod( - pipeline_response=pipeline_response, - command=command, - final_resource=recovered_secret, - finished=False, - interval=polling_interval - ) - await polling_method.run() - - return polling_method.resource() - - async def __aenter__(self) -> "SecretClient": + async def __aenter__(self) -> Self: await self._client.__aenter__() return self + + async def __aexit__(self, *exc_details: Any) -> None: + await self._client.__aexit__(*exc_details) diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_configuration.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_configuration.py similarity index 100% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_configuration.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_configuration.py diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_operations/__init__.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_operations/__init__.py similarity index 100% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_operations/__init__.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_operations/__init__.py diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_operations/_operations.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_operations/_operations.py similarity index 95% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_operations/_operations.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_operations/_operations.py index d5fb2854a004..022d6623bce4 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_operations/_operations.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_operations/_operations.py @@ -1,4 +1,4 @@ -# pylint: disable=too-many-lines +# pylint: disable=line-too-long,useless-suppression,too-many-lines # coding=utf-8 # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. @@ -6,9 +6,9 @@ # 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 -import sys from typing import Any, AsyncIterable, Callable, Dict, IO, List, Optional, TypeVar, Union, overload import urllib.parse @@ -47,11 +47,7 @@ ) from .._vendor import KeyVaultClientMixinABC -if sys.version_info >= (3, 9): - from collections.abc import MutableMapping -else: - from typing import MutableMapping # type: ignore -JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object +JSON = MutableMapping[str, Any] T = TypeVar("T") ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] @@ -78,12 +74,12 @@ async def set_secret( identifiable or sensitive information. Required. :type secret_name: str :param parameters: The parameters for setting the secret. Required. - :type parameters: ~azure.keyvault.secrets._generated.models.SecretSetParameters + :type parameters: ~azure.keyvault.secrets.models.SecretSetParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -107,7 +103,7 @@ async def set_secret( Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -131,7 +127,7 @@ async def set_secret( Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -151,9 +147,9 @@ async def set_secret( :type secret_name: str :param parameters: The parameters for setting the secret. Is one of the following types: SecretSetParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.secrets._generated.models.SecretSetParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.secrets.models.SecretSetParameters or JSON or IO[bytes] :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -229,7 +225,7 @@ async def delete_secret(self, secret_name: str, **kwargs: Any) -> _models.Delete :param secret_name: The name of the secret. Required. :type secret_name: str :return: DeletedSecretBundle. The DeletedSecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.DeletedSecretBundle + :rtype: ~azure.keyvault.secrets.models.DeletedSecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -306,12 +302,12 @@ async def update_secret( :param secret_version: The version of the secret. Required. :type secret_version: str :param parameters: The parameters for update secret operation. Required. - :type parameters: ~azure.keyvault.secrets._generated.models.SecretUpdateParameters + :type parameters: ~azure.keyvault.secrets.models.SecretUpdateParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -341,7 +337,7 @@ async def update_secret( Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -371,7 +367,7 @@ async def update_secret( Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -395,9 +391,9 @@ async def update_secret( :type secret_version: str :param parameters: The parameters for update secret operation. Is one of the following types: SecretUpdateParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.secrets._generated.models.SecretUpdateParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.secrets.models.SecretUpdateParameters or JSON or IO[bytes] :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -477,7 +473,7 @@ async def get_secret(self, secret_name: str, secret_version: str, **kwargs: Any) specified, the latest version of the secret is returned. Required. :type secret_version: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -546,7 +542,7 @@ def get_secrets(self, *, maxresults: Optional[int] = None, **kwargs: Any) -> Asy service will return up to 25 results. Default value is None. :paramtype maxresults: int :return: An iterator like instance of SecretItem - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.secrets._generated.models.SecretItem] + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.secrets.models.SecretItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} @@ -602,7 +598,7 @@ def prepare_request(next_link=None): async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize(List[_models.SecretItem], deserialized["value"]) + list_of_elem = _deserialize(List[_models.SecretItem], deserialized.get("value", [])) if cls: list_of_elem = cls(list_of_elem) # type: ignore return deserialized.get("nextLink") or None, AsyncList(list_of_elem) @@ -640,7 +636,7 @@ def get_secret_versions( service will return up to 25 results. Default value is None. :paramtype maxresults: int :return: An iterator like instance of SecretItem - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.secrets._generated.models.SecretItem] + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.secrets.models.SecretItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} @@ -697,7 +693,7 @@ def prepare_request(next_link=None): async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize(List[_models.SecretItem], deserialized["value"]) + list_of_elem = _deserialize(List[_models.SecretItem], deserialized.get("value", [])) if cls: list_of_elem = cls(list_of_elem) # type: ignore return deserialized.get("nextLink") or None, AsyncList(list_of_elem) @@ -734,7 +730,7 @@ def get_deleted_secrets( :paramtype maxresults: int :return: An iterator like instance of DeletedSecretItem :rtype: - ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.secrets._generated.models.DeletedSecretItem] + ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.secrets.models.DeletedSecretItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} @@ -790,7 +786,7 @@ def prepare_request(next_link=None): async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize(List[_models.DeletedSecretItem], deserialized["value"]) + list_of_elem = _deserialize(List[_models.DeletedSecretItem], deserialized.get("value", [])) if cls: list_of_elem = cls(list_of_elem) # type: ignore return deserialized.get("nextLink") or None, AsyncList(list_of_elem) @@ -823,7 +819,7 @@ async def get_deleted_secret(self, secret_name: str, **kwargs: Any) -> _models.D :param secret_name: The name of the secret. Required. :type secret_name: str :return: DeletedSecretBundle. The DeletedSecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.DeletedSecretBundle + :rtype: ~azure.keyvault.secrets.models.DeletedSecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -944,7 +940,7 @@ async def recover_deleted_secret(self, secret_name: str, **kwargs: Any) -> _mode :param secret_name: The name of the deleted secret. Required. :type secret_name: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -1010,7 +1006,7 @@ async def backup_secret(self, secret_name: str, **kwargs: Any) -> _models.Backup :param secret_name: The name of the secret. Required. :type secret_name: str :return: BackupSecretResult. The BackupSecretResult is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.BackupSecretResult + :rtype: ~azure.keyvault.secrets.models.BackupSecretResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -1076,12 +1072,12 @@ async def restore_secret( secrets/restore permission. :param parameters: The parameters to restore the secret. Required. - :type parameters: ~azure.keyvault.secrets._generated.models.SecretRestoreParameters + :type parameters: ~azure.keyvault.secrets.models.SecretRestoreParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1100,7 +1096,7 @@ async def restore_secret( Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1119,7 +1115,7 @@ async def restore_secret( Default value is "application/json". :paramtype content_type: str :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1134,9 +1130,9 @@ async def restore_secret( :param parameters: The parameters to restore the secret. Is one of the following types: SecretRestoreParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.secrets._generated.models.SecretRestoreParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.secrets.models.SecretRestoreParameters or JSON or IO[bytes] :return: SecretBundle. The SecretBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle + :rtype: ~azure.keyvault.secrets.models.SecretBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_patch.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_operations/_patch.py similarity index 61% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_patch.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_operations/_patch.py index f7dd32510333..8bcb627aa475 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_patch.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_operations/_patch.py @@ -1,7 +1,8 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ +# 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. +# -------------------------------------------------------------------------- """Customize generated code here. Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_operations/_patch.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_patch.py similarity index 61% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_operations/_patch.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_patch.py index f7dd32510333..8bcb627aa475 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/_operations/_patch.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_patch.py @@ -1,7 +1,8 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ +# 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. +# -------------------------------------------------------------------------- """Customize generated code here. Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_vendor.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_vendor.py similarity index 100% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/aio/_vendor.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/aio/_vendor.py diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/models/__init__.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/models/__init__.py similarity index 96% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/models/__init__.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/models/__init__.py index 5a383fd12320..2911026b11ab 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/models/__init__.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/models/__init__.py @@ -17,8 +17,8 @@ BackupSecretResult, DeletedSecretBundle, DeletedSecretItem, + Error, KeyVaultError, - KeyVaultErrorError, SecretAttributes, SecretBundle, SecretItem, @@ -38,8 +38,8 @@ "BackupSecretResult", "DeletedSecretBundle", "DeletedSecretItem", + "Error", "KeyVaultError", - "KeyVaultErrorError", "SecretAttributes", "SecretBundle", "SecretItem", diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/models/_enums.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/models/_enums.py similarity index 100% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/models/_enums.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/models/_enums.py diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/models/_models.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/models/_models.py similarity index 79% rename from sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/models/_models.py rename to sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/models/_models.py index b9fffdc59a63..4ed32856af5c 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_generated/models/_models.py +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/models/_models.py @@ -20,8 +20,6 @@ class BackupSecretResult(_model_base.Model): """The backup secret result, containing the backup blob. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar value: The backup blob containing the backed up secret. :vartype value: bytes """ @@ -34,8 +32,6 @@ class DeletedSecretBundle(_model_base.Model): """A Deleted Secret consisting of its previous id, attributes and its tags, as well as information on when it will be purged. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar value: The secret value. :vartype value: str :ivar id: The secret id. @@ -43,7 +39,7 @@ class DeletedSecretBundle(_model_base.Model): :ivar content_type: The content type of the secret. :vartype content_type: str :ivar attributes: The secret management attributes. - :vartype attributes: ~azure.keyvault.secrets._generated.models.SecretAttributes + :vartype attributes: ~azure.keyvault.secrets.models.SecretAttributes :ivar tags: Application specific metadata in the form of key-value pairs. :vartype tags: dict[str, str] :ivar kid: If this is a secret backing a KV certificate, then this field specifies the @@ -61,15 +57,19 @@ class DeletedSecretBundle(_model_base.Model): :vartype deleted_date: ~datetime.datetime """ - value: Optional[str] = rest_field() + value: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The secret value.""" - id: Optional[str] = rest_field() + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The secret id.""" - content_type: Optional[str] = rest_field(name="contentType") + content_type: Optional[str] = rest_field( + name="contentType", visibility=["read", "create", "update", "delete", "query"] + ) """The content type of the secret.""" - attributes: Optional["_models.SecretAttributes"] = rest_field() + attributes: Optional["_models.SecretAttributes"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The secret management attributes.""" - tags: Optional[Dict[str, str]] = rest_field() + tags: Optional[Dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Application specific metadata in the form of key-value pairs.""" kid: Optional[str] = rest_field(visibility=["read"]) """If this is a secret backing a KV certificate, then this field specifies the corresponding key @@ -77,7 +77,9 @@ class DeletedSecretBundle(_model_base.Model): managed: Optional[bool] = rest_field(visibility=["read"]) """True if the secret's lifetime is managed by key vault. If this is a secret backing a certificate, then managed will be true.""" - recovery_id: Optional[str] = rest_field(name="recoveryId") + recovery_id: Optional[str] = rest_field( + name="recoveryId", visibility=["read", "create", "update", "delete", "query"] + ) """The url of the recovery object, used to identify and recover the deleted secret.""" scheduled_purge_date: Optional[datetime.datetime] = rest_field( name="scheduledPurgeDate", visibility=["read"], format="unix-timestamp" @@ -114,12 +116,10 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class DeletedSecretItem(_model_base.Model): """The deleted secret item containing metadata about the deleted secret. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar id: Secret identifier. :vartype id: str :ivar attributes: The secret management attributes. - :vartype attributes: ~azure.keyvault.secrets._generated.models.SecretAttributes + :vartype attributes: ~azure.keyvault.secrets.models.SecretAttributes :ivar tags: Application specific metadata in the form of key-value pairs. :vartype tags: dict[str, str] :ivar content_type: Type of the secret value such as a password. @@ -136,18 +136,24 @@ class DeletedSecretItem(_model_base.Model): :vartype deleted_date: ~datetime.datetime """ - id: Optional[str] = rest_field() + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Secret identifier.""" - attributes: Optional["_models.SecretAttributes"] = rest_field() + attributes: Optional["_models.SecretAttributes"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The secret management attributes.""" - tags: Optional[Dict[str, str]] = rest_field() + tags: Optional[Dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Application specific metadata in the form of key-value pairs.""" - content_type: Optional[str] = rest_field(name="contentType") + content_type: Optional[str] = rest_field( + name="contentType", visibility=["read", "create", "update", "delete", "query"] + ) """Type of the secret value such as a password.""" managed: Optional[bool] = rest_field(visibility=["read"]) """True if the secret's lifetime is managed by key vault. If this is a key backing a certificate, then managed will be true.""" - recovery_id: Optional[str] = rest_field(name="recoveryId") + recovery_id: Optional[str] = rest_field( + name="recoveryId", visibility=["read", "create", "update", "delete", "query"] + ) """The url of the recovery object, used to identify and recover the deleted secret.""" scheduled_purge_date: Optional[datetime.datetime] = rest_field( name="scheduledPurgeDate", visibility=["read"], format="unix-timestamp" @@ -180,45 +186,39 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class KeyVaultError(_model_base.Model): - """The key vault error exception. - - Readonly variables are only populated by the server, and will be ignored when sending a request. - - :ivar error: The key vault server error. - :vartype error: ~azure.keyvault.secrets._generated.models.KeyVaultErrorError - """ - - error: Optional["_models.KeyVaultErrorError"] = rest_field(visibility=["read"]) - """The key vault server error.""" - - -class KeyVaultErrorError(_model_base.Model): - """KeyVaultErrorError. - - Readonly variables are only populated by the server, and will be ignored when sending a request. +class Error(_model_base.Model): + """The key vault server error. :ivar code: The error code. :vartype code: str :ivar message: The error message. :vartype message: str :ivar inner_error: The key vault server error. - :vartype inner_error: ~azure.keyvault.secrets._generated.models.KeyVaultErrorError + :vartype inner_error: ~azure.keyvault.secrets.models.Error """ code: Optional[str] = rest_field(visibility=["read"]) """The error code.""" message: Optional[str] = rest_field(visibility=["read"]) """The error message.""" - inner_error: Optional["_models.KeyVaultErrorError"] = rest_field(name="innererror", visibility=["read"]) + inner_error: Optional["_models.Error"] = rest_field(name="innererror", visibility=["read"]) + """The key vault server error.""" + + +class KeyVaultError(_model_base.Model): + """The key vault error exception. + + :ivar error: The key vault server error. + :vartype error: ~azure.keyvault.secrets.models.Error + """ + + error: Optional["_models.Error"] = rest_field(visibility=["read"]) """The key vault server error.""" class SecretAttributes(_model_base.Model): """The secret management attributes. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar enabled: Determines whether the object is enabled. :vartype enabled: bool :ivar not_before: Not before date in UTC. @@ -238,14 +238,18 @@ class SecretAttributes(_model_base.Model): interval. Known values are: "Purgeable", "Recoverable+Purgeable", "Recoverable", "Recoverable+ProtectedSubscription", "CustomizedRecoverable+Purgeable", "CustomizedRecoverable", and "CustomizedRecoverable+ProtectedSubscription". - :vartype recovery_level: str or ~azure.keyvault.secrets._generated.models.DeletionRecoveryLevel + :vartype recovery_level: str or ~azure.keyvault.secrets.models.DeletionRecoveryLevel """ - enabled: Optional[bool] = rest_field() + enabled: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Determines whether the object is enabled.""" - not_before: Optional[datetime.datetime] = rest_field(name="nbf", format="unix-timestamp") + not_before: Optional[datetime.datetime] = rest_field( + name="nbf", visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) """Not before date in UTC.""" - expires: Optional[datetime.datetime] = rest_field(name="exp", format="unix-timestamp") + expires: Optional[datetime.datetime] = rest_field( + name="exp", visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) """Expiry date in UTC.""" created: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") """Creation time in UTC.""" @@ -287,8 +291,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class SecretBundle(_model_base.Model): """A secret consisting of a value, id and its attributes. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar value: The secret value. :vartype value: str :ivar id: The secret id. @@ -296,7 +298,7 @@ class SecretBundle(_model_base.Model): :ivar content_type: The content type of the secret. :vartype content_type: str :ivar attributes: The secret management attributes. - :vartype attributes: ~azure.keyvault.secrets._generated.models.SecretAttributes + :vartype attributes: ~azure.keyvault.secrets.models.SecretAttributes :ivar tags: Application specific metadata in the form of key-value pairs. :vartype tags: dict[str, str] :ivar kid: If this is a secret backing a KV certificate, then this field specifies the @@ -307,15 +309,19 @@ class SecretBundle(_model_base.Model): :vartype managed: bool """ - value: Optional[str] = rest_field() + value: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The secret value.""" - id: Optional[str] = rest_field() + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The secret id.""" - content_type: Optional[str] = rest_field(name="contentType") + content_type: Optional[str] = rest_field( + name="contentType", visibility=["read", "create", "update", "delete", "query"] + ) """The content type of the secret.""" - attributes: Optional["_models.SecretAttributes"] = rest_field() + attributes: Optional["_models.SecretAttributes"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The secret management attributes.""" - tags: Optional[Dict[str, str]] = rest_field() + tags: Optional[Dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Application specific metadata in the form of key-value pairs.""" kid: Optional[str] = rest_field(visibility=["read"]) """If this is a secret backing a KV certificate, then this field specifies the corresponding key @@ -349,12 +355,10 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class SecretItem(_model_base.Model): """The secret item containing secret metadata. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar id: Secret identifier. :vartype id: str :ivar attributes: The secret management attributes. - :vartype attributes: ~azure.keyvault.secrets._generated.models.SecretAttributes + :vartype attributes: ~azure.keyvault.secrets.models.SecretAttributes :ivar tags: Application specific metadata in the form of key-value pairs. :vartype tags: dict[str, str] :ivar content_type: Type of the secret value such as a password. @@ -364,13 +368,17 @@ class SecretItem(_model_base.Model): :vartype managed: bool """ - id: Optional[str] = rest_field() + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Secret identifier.""" - attributes: Optional["_models.SecretAttributes"] = rest_field() + attributes: Optional["_models.SecretAttributes"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The secret management attributes.""" - tags: Optional[Dict[str, str]] = rest_field() + tags: Optional[Dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Application specific metadata in the form of key-value pairs.""" - content_type: Optional[str] = rest_field(name="contentType") + content_type: Optional[str] = rest_field( + name="contentType", visibility=["read", "create", "update", "delete", "query"] + ) """Type of the secret value such as a password.""" managed: Optional[bool] = rest_field(visibility=["read"]) """True if the secret's lifetime is managed by key vault. If this is a key backing a certificate, @@ -400,13 +408,13 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class SecretRestoreParameters(_model_base.Model): """The secret restore parameters. - All required parameters must be populated in order to send to server. - :ivar secret_bundle_backup: The backup blob associated with a secret bundle. Required. :vartype secret_bundle_backup: bytes """ - secret_bundle_backup: bytes = rest_field(name="value", format="base64url") + secret_bundle_backup: bytes = rest_field( + name="value", visibility=["read", "create", "update", "delete", "query"], format="base64url" + ) """The backup blob associated with a secret bundle. Required.""" @overload @@ -430,8 +438,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class SecretSetParameters(_model_base.Model): """The secret set parameters. - All required parameters must be populated in order to send to server. - :ivar value: The value of the secret. Required. :vartype value: str :ivar tags: Application specific metadata in the form of key-value pairs. @@ -439,16 +445,20 @@ class SecretSetParameters(_model_base.Model): :ivar content_type: Type of the secret value such as a password. :vartype content_type: str :ivar secret_attributes: The secret management attributes. - :vartype secret_attributes: ~azure.keyvault.secrets._generated.models.SecretAttributes + :vartype secret_attributes: ~azure.keyvault.secrets.models.SecretAttributes """ - value: str = rest_field() + value: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The value of the secret. Required.""" - tags: Optional[Dict[str, str]] = rest_field() + tags: Optional[Dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Application specific metadata in the form of key-value pairs.""" - content_type: Optional[str] = rest_field(name="contentType") + content_type: Optional[str] = rest_field( + name="contentType", visibility=["read", "create", "update", "delete", "query"] + ) """Type of the secret value such as a password.""" - secret_attributes: Optional["_models.SecretAttributes"] = rest_field(name="attributes") + secret_attributes: Optional["_models.SecretAttributes"] = rest_field( + name="attributes", visibility=["read", "create", "update", "delete", "query"] + ) """The secret management attributes.""" @overload @@ -478,16 +488,20 @@ class SecretUpdateParameters(_model_base.Model): :ivar content_type: Type of the secret value such as a password. :vartype content_type: str :ivar secret_attributes: The secret management attributes. - :vartype secret_attributes: ~azure.keyvault.secrets._generated.models.SecretAttributes + :vartype secret_attributes: ~azure.keyvault.secrets.models.SecretAttributes :ivar tags: Application specific metadata in the form of key-value pairs. :vartype tags: dict[str, str] """ - content_type: Optional[str] = rest_field(name="contentType") + content_type: Optional[str] = rest_field( + name="contentType", visibility=["read", "create", "update", "delete", "query"] + ) """Type of the secret value such as a password.""" - secret_attributes: Optional["_models.SecretAttributes"] = rest_field(name="attributes") + secret_attributes: Optional["_models.SecretAttributes"] = rest_field( + name="attributes", visibility=["read", "create", "update", "delete", "query"] + ) """The secret management attributes.""" - tags: Optional[Dict[str, str]] = rest_field() + tags: Optional[Dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Application specific metadata in the form of key-value pairs.""" @overload diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/models/_patch.py b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/models/_patch.py new file mode 100644 index 000000000000..8bcb627aa475 --- /dev/null +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/models/_patch.py @@ -0,0 +1,21 @@ +# 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. +# -------------------------------------------------------------------------- +"""Customize generated code here. + +Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize +""" +from typing import List + +__all__: List[str] = [] # Add all objects you want publicly available to users at this package level + + +def patch_sdk(): + """Do not remove from this file. + + `patch_sdk` is a last resort escape hatch that allows you to do customizations + you can't accomplish using the techniques described in + https://aka.ms/azsdk/python/dpcodegen/python/customize + """ diff --git a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/py.typed b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/py.typed index e69de29bb2d1..e5aff4f83af8 100644 --- a/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/py.typed +++ b/sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561. \ No newline at end of file diff --git a/sdk/keyvault/azure-keyvault-secrets/samples/backup_restore_operations.py b/sdk/keyvault/azure-keyvault-secrets/samples/backup_restore_operations.py index 6cf17e27fb66..e03c2f3cace0 100644 --- a/sdk/keyvault/azure-keyvault-secrets/samples/backup_restore_operations.py +++ b/sdk/keyvault/azure-keyvault-secrets/samples/backup_restore_operations.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. diff --git a/sdk/keyvault/azure-keyvault-secrets/samples/backup_restore_operations_async.py b/sdk/keyvault/azure-keyvault-secrets/samples/backup_restore_operations_async.py index 3412407cee50..61ecc9baf868 100644 --- a/sdk/keyvault/azure-keyvault-secrets/samples/backup_restore_operations_async.py +++ b/sdk/keyvault/azure-keyvault-secrets/samples/backup_restore_operations_async.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -8,6 +9,7 @@ from azure.keyvault.secrets.aio import SecretClient from azure.identity.aio import DefaultAzureCredential + # ---------------------------------------------------------------------------------------------------------- # Prerequisites: # 1. An Azure Key Vault (https://learn.microsoft.com/azure/key-vault/quick-create-cli) @@ -74,4 +76,4 @@ async def run_sample(): if __name__ == "__main__": - asyncio.run(run_sample()) \ No newline at end of file + asyncio.run(run_sample()) diff --git a/sdk/keyvault/azure-keyvault-secrets/samples/hello_world.py b/sdk/keyvault/azure-keyvault-secrets/samples/hello_world.py index f9c4bc8f96fe..3a7748229984 100644 --- a/sdk/keyvault/azure-keyvault-secrets/samples/hello_world.py +++ b/sdk/keyvault/azure-keyvault-secrets/samples/hello_world.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. diff --git a/sdk/keyvault/azure-keyvault-secrets/samples/hello_world_async.py b/sdk/keyvault/azure-keyvault-secrets/samples/hello_world_async.py index ff1e1de91d97..b42e93ce1234 100644 --- a/sdk/keyvault/azure-keyvault-secrets/samples/hello_world_async.py +++ b/sdk/keyvault/azure-keyvault-secrets/samples/hello_world_async.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -9,6 +10,7 @@ from azure.keyvault.secrets.aio import SecretClient from azure.identity.aio import DefaultAzureCredential + # ---------------------------------------------------------------------------------------------------------- # Prerequisites: # 1. An Azure Key Vault (https://learn.microsoft.com/azure/key-vault/quick-create-cli) diff --git a/sdk/keyvault/azure-keyvault-secrets/samples/list_operations.py b/sdk/keyvault/azure-keyvault-secrets/samples/list_operations.py index bf31a8a86fc5..207d938c0720 100644 --- a/sdk/keyvault/azure-keyvault-secrets/samples/list_operations.py +++ b/sdk/keyvault/azure-keyvault-secrets/samples/list_operations.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -58,17 +59,13 @@ for secret in secrets: assert secret.name retrieved_secret = client.get_secret(secret.name) - print( - f"Secret with name '{retrieved_secret.name}' and value {retrieved_secret.name} was found." - ) + print(f"Secret with name '{retrieved_secret.name}' and value {retrieved_secret.name} was found.") # The bank account password got updated, so you want to update the secret in Key Vault to ensure it reflects the # new password. Calling set_secret on an existing secret creates a new version of the secret in the Key Vault # with the new value. updated_secret = client.set_secret(bank_secret.name, "newSecretValue") -print( - f"Secret with name '{updated_secret.name}' was updated with new value '{updated_secret.value}'" -) +print(f"Secret with name '{updated_secret.name}' was updated with new value '{updated_secret.value}'") # You need to check all the different values your bank account password secret had previously. Lets print all # the versions of this secret. @@ -89,6 +86,4 @@ print("\n.. List deleted secrets from the Key Vault") deleted_secrets = client.list_deleted_secrets() for deleted_secret in deleted_secrets: - print( - f"Secret with name '{deleted_secret.name}' has recovery id '{deleted_secret.recovery_id}'" - ) + print(f"Secret with name '{deleted_secret.name}' has recovery id '{deleted_secret.recovery_id}'") diff --git a/sdk/keyvault/azure-keyvault-secrets/samples/list_operations_async.py b/sdk/keyvault/azure-keyvault-secrets/samples/list_operations_async.py index 7a591519b0a0..6c02546e7e58 100644 --- a/sdk/keyvault/azure-keyvault-secrets/samples/list_operations_async.py +++ b/sdk/keyvault/azure-keyvault-secrets/samples/list_operations_async.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -8,6 +9,7 @@ from azure.keyvault.secrets.aio import SecretClient from azure.identity.aio import DefaultAzureCredential + # ---------------------------------------------------------------------------------------------------------- # Prerequisites: # 1. An Azure Key Vault (https://learn.microsoft.com/azure/key-vault/quick-create-cli) @@ -64,9 +66,7 @@ async def run_sample(): # new password. Calling set_secret on an existing secret creates a new version of the secret in the Key Vault # with the new value. updated_secret = await client.set_secret(bank_secret.name, "newSecretValue") - print( - f"Secret with name '{updated_secret.name}' was updated with new value '{updated_secret.value}'" - ) + print(f"Secret with name '{updated_secret.name}' was updated with new value '{updated_secret.value}'") # You need to check all the different values your bank account password secret had previously. Lets print all # the versions of this secret. @@ -84,9 +84,7 @@ async def run_sample(): print("\n.. List deleted secrets from the Key Vault") deleted_secrets = client.list_deleted_secrets() async for deleted_secret in deleted_secrets: - print( - f"Secret with name '{deleted_secret.name}' has recovery id '{deleted_secret.recovery_id}'" - ) + print(f"Secret with name '{deleted_secret.name}' has recovery id '{deleted_secret.recovery_id}'") print("\nrun_sample done") await credential.close() diff --git a/sdk/keyvault/azure-keyvault-secrets/samples/recover_purge_operations.py b/sdk/keyvault/azure-keyvault-secrets/samples/recover_purge_operations.py index c22aac38188e..13d810d778bb 100644 --- a/sdk/keyvault/azure-keyvault-secrets/samples/recover_purge_operations.py +++ b/sdk/keyvault/azure-keyvault-secrets/samples/recover_purge_operations.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. diff --git a/sdk/keyvault/azure-keyvault-secrets/samples/recover_purge_operations_async.py b/sdk/keyvault/azure-keyvault-secrets/samples/recover_purge_operations_async.py index b69b0bcfb4ef..60e690ec9939 100644 --- a/sdk/keyvault/azure-keyvault-secrets/samples/recover_purge_operations_async.py +++ b/sdk/keyvault/azure-keyvault-secrets/samples/recover_purge_operations_async.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -8,6 +9,7 @@ from azure.keyvault.secrets.aio import SecretClient from azure.identity.aio import DefaultAzureCredential + # ---------------------------------------------------------------------------------------------------------- # Prerequisites: # 1. An Azure Key Vault (https://learn.microsoft.com/azure/key-vault/quick-create-cli) diff --git a/sdk/keyvault/azure-keyvault-secrets/setup.py b/sdk/keyvault/azure-keyvault-secrets/setup.py index c08df19d91e9..e39269c08bc6 100644 --- a/sdk/keyvault/azure-keyvault-secrets/setup.py +++ b/sdk/keyvault/azure-keyvault-secrets/setup.py @@ -1,55 +1,47 @@ -#!/usr/bin/env python +# 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. +# -------------------------------------------------------------------------- -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -# pylint:disable=missing-docstring +import os import re -import os.path -from io import open -from setuptools import find_packages, setup +from setuptools import setup, find_packages + -# Change the PACKAGE_NAME only to change folder and different name PACKAGE_NAME = "azure-keyvault-secrets" -PACKAGE_PPRINT_NAME = "Key Vault Secrets" +PACKAGE_PPRINT_NAME = "Azure Keyvault Secrets" # a-b-c => a/b/c -PACKAGE_FOLDER_PATH = PACKAGE_NAME.replace("-", "/") -# a-b-c => a.b.c -NAMESPACE_NAME = PACKAGE_NAME.replace("-", ".") +package_folder_path = PACKAGE_NAME.replace("-", "/") # Version extraction inspired from 'requests' -with open(os.path.join(PACKAGE_FOLDER_PATH, "_version.py"), "r") as fd: - VERSION = re.search(r'^VERSION\s*=\s*[\'"]([^\'"]*)[\'"]', fd.read(), re.MULTILINE).group(1) +with open(os.path.join(package_folder_path, "_version.py"), "r") as fd: + version = re.search(r'^VERSION\s*=\s*[\'"]([^\'"]*)[\'"]', fd.read(), re.MULTILINE).group(1) -if not VERSION: +if not version: raise RuntimeError("Cannot find version information") -with open("README.md", encoding="utf-8") as f: - README = f.read() -with open("CHANGELOG.md", encoding="utf-8") as f: - CHANGELOG = f.read() setup( name=PACKAGE_NAME, - version=VERSION, - include_package_data=True, - description=f"Microsoft Azure {PACKAGE_PPRINT_NAME} Client Library for Python", - long_description=README + "\n\n" + CHANGELOG, + version=version, + description="Microsoft Corporation {} Client Library for Python".format(PACKAGE_PPRINT_NAME), + long_description=open("README.md", "r").read(), long_description_content_type="text/markdown", license="MIT License", author="Microsoft Corporation", - author_email="azurekeyvault@microsoft.com", - url="https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-secrets", + author_email="azpysdkhelp@microsoft.com", + url="https://github.com/Azure/azure-sdk-for-python/tree/main/sdk", keywords="azure, azure sdk", classifiers=[ "Development Status :: 4 - Beta", "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -59,17 +51,20 @@ zip_safe=False, packages=find_packages( exclude=[ - "samples", "tests", # Exclude packages that will be covered by PEP420 or nspkg "azure", "azure.keyvault", ] ), - python_requires=">=3.8", + include_package_data=True, + package_data={ + "azure.keyvault.secrets": ["py.typed"], + }, install_requires=[ - "azure-core>=1.31.0", "isodate>=0.6.1", + "azure-core>=1.30.0", "typing-extensions>=4.6.0", ], + python_requires=">=3.9", ) diff --git a/sdk/keyvault/azure-keyvault-secrets/tests/conftest.py b/sdk/keyvault/azure-keyvault-secrets/tests/conftest.py index 96ff292c3f2c..e630f5c4ab81 100644 --- a/sdk/keyvault/azure-keyvault-secrets/tests/conftest.py +++ b/sdk/keyvault/azure-keyvault-secrets/tests/conftest.py @@ -31,7 +31,7 @@ test_proxy, add_oauth_response_sanitizer, add_general_regex_sanitizer, - remove_batch_sanitizers + remove_batch_sanitizers, ) diff --git a/sdk/keyvault/azure-keyvault-secrets/tests/test_polling_method.py b/sdk/keyvault/azure-keyvault-secrets/tests/test_polling_method.py index fded987db56c..22189629419d 100644 --- a/sdk/keyvault/azure-keyvault-secrets/tests/test_polling_method.py +++ b/sdk/keyvault/azure-keyvault-secrets/tests/test_polling_method.py @@ -74,7 +74,9 @@ def command(): _command.operation_complete = True resource = object() - polling_method = DeleteRecoverPollingMethod(mock_pipeline_response, command, final_resource=resource, finished=False) + polling_method = DeleteRecoverPollingMethod( + mock_pipeline_response, command, final_resource=resource, finished=False + ) assert not polling_method.finished() with mock.patch(SLEEP) as sleep: @@ -102,7 +104,9 @@ def test_final_resource(): assert final_resource is resource command = mock.Mock() - polling_method = DeleteRecoverPollingMethod(mock_pipeline_response, command, final_resource=resource, finished=False) + polling_method = DeleteRecoverPollingMethod( + mock_pipeline_response, command, final_resource=resource, finished=False + ) assert polling_method.resource() is resource polling_method.run() diff --git a/sdk/keyvault/azure-keyvault-secrets/tests/test_secrets_async.py b/sdk/keyvault/azure-keyvault-secrets/tests/test_secrets_async.py index 435d6c6d04b1..8408e6e35890 100644 --- a/sdk/keyvault/azure-keyvault-secrets/tests/test_secrets_async.py +++ b/sdk/keyvault/azure-keyvault-secrets/tests/test_secrets_async.py @@ -390,6 +390,7 @@ async def test_40x_handling(self, client, **kwargs): # Test that 409 is raised correctly (`set_secret` shouldn't actually trigger this, but for raising behavior) async def run(*_, **__): return Mock(http_response=Mock(status_code=409)) + with patch.object(client._client._client._pipeline, "run", run): with pytest.raises(ResourceExistsError): await client.set_secret("...", "...") diff --git a/sdk/keyvault/azure-keyvault-secrets/tests/test_secrets_client.py b/sdk/keyvault/azure-keyvault-secrets/tests/test_secrets_client.py index ed09c2759c48..d92537cc0f19 100644 --- a/sdk/keyvault/azure-keyvault-secrets/tests/test_secrets_client.py +++ b/sdk/keyvault/azure-keyvault-secrets/tests/test_secrets_client.py @@ -379,6 +379,7 @@ def test_40x_handling(self, client, **kwargs): # Test that 409 is raised correctly (`set_secret` shouldn't actually trigger this, but for raising behavior) def run(*_, **__): return Mock(http_response=Mock(status_code=409)) + with patch.object(client._client._client._pipeline, "run", run): with pytest.raises(ResourceExistsError): client.set_secret("...", "...") diff --git a/sdk/keyvault/azure-keyvault-secrets/tsp-location.yaml b/sdk/keyvault/azure-keyvault-secrets/tsp-location.yaml new file mode 100644 index 000000000000..4a69e2be8c2f --- /dev/null +++ b/sdk/keyvault/azure-keyvault-secrets/tsp-location.yaml @@ -0,0 +1,5 @@ +directory: specification/keyvault/Security.KeyVault.Secrets +commit: 4465f2aaefeb75e8a088c7e0950979e03430a234 +repo: Azure/azure-rest-api-specs +additionalDirectories: +- specification/keyvault/Security.KeyVault.Common