From 1844ef98a0f8c38ac45bed634ff9022d9a41711a Mon Sep 17 00:00:00 2001
From: vincenttran-msft <101599632+vincenttran-msft@users.noreply.github.com>
Date: Fri, 22 Jul 2022 13:43:34 -0700
Subject: [PATCH] [Storage] Handling AzureNamedKeyCredential in Python SDK
(#24967)
---
.../blob/changefeed/_change_feed_client.py | 16 +-
sdk/storage/azure-storage-blob/CHANGELOG.md | 1 +
.../azure/storage/blob/__init__.py | 14 +-
.../azure/storage/blob/_blob_client.py | 31 ++-
.../storage/blob/_blob_service_client.py | 16 +-
.../azure/storage/blob/_container_client.py | 30 ++-
.../azure/storage/blob/_shared/base_client.py | 13 +-
.../azure/storage/blob/aio/__init__.py | 16 +-
.../storage/blob/aio/_blob_client_async.py | 8 +-
.../blob/aio/_blob_service_client_async.py | 8 +-
.../blob/aio/_container_client_async.py | 8 +-
...est_azure_named_key_credential_access.yaml | 40 ++++
...est_azure_named_key_credential_access.yaml | 29 +++
.../tests/test_common_blob.py | 15 +-
.../tests/test_common_blob_async.py | 16 +-
.../azure-storage-file-datalake/CHANGELOG.md | 1 +
.../_data_lake_directory_client.py | 16 +-
.../filedatalake/_data_lake_file_client.py | 16 +-
.../filedatalake/_data_lake_service_client.py | 6 +-
.../filedatalake/_file_system_client.py | 16 +-
.../storage/filedatalake/_path_client.py | 8 +-
.../filedatalake/_shared/base_client.py | 9 +-
.../aio/_data_lake_directory_client_async.py | 8 +-
.../aio/_data_lake_file_client_async.py | 8 +-
.../aio/_data_lake_service_client_async.py | 8 +-
.../aio/_file_system_client_async.py | 8 +-
.../filedatalake/aio/_path_client_async.py | 8 +-
.../azure-storage-file-datalake/setup.py | 2 +-
...est_azure_named_key_credential_access.yaml | 37 +++
...est_azure_named_key_credential_access.yaml | 29 +++
.../tests/test_datalake_service_client.py | 12 +
.../test_datalake_service_client_async.py | 12 +
.../azure-storage-file-share/CHANGELOG.md | 1 +
.../storage/fileshare/_directory_client.py | 38 +--
.../azure/storage/fileshare/_file_client.py | 36 ++-
.../azure/storage/fileshare/_share_client.py | 36 ++-
.../fileshare/_share_service_client.py | 24 +-
.../storage/fileshare/_shared/base_client.py | 9 +-
.../fileshare/aio/_directory_client_async.py | 12 +-
.../fileshare/aio/_file_client_async.py | 12 +-
.../fileshare/aio/_share_client_async.py | 12 +-
.../aio/_share_service_client_async.py | 12 +-
...est_azure_named_key_credential_access.yaml | 217 ++++++++++++++++++
...est_azure_named_key_credential_access.yaml | 153 ++++++++++++
.../tests/test_file.py | 21 +-
.../tests/test_file_async.py | 24 ++
sdk/storage/azure-storage-queue/CHANGELOG.md | 1 +
.../azure/storage/queue/_queue_client.py | 29 ++-
.../storage/queue/_queue_service_client.py | 19 +-
.../storage/queue/_shared/base_client.py | 10 +-
.../storage/queue/aio/_queue_client_async.py | 10 +-
.../queue/aio/_queue_service_client_async.py | 10 +-
...est_azure_named_key_credential_access.yaml | 117 ++++++++++
...est_azure_named_key_credential_access.yaml | 91 ++++++++
.../azure-storage-queue/tests/test_queue.py | 18 +-
.../tests/test_queue_async.py | 18 +-
shared_requirements.txt | 2 +-
57 files changed, 1209 insertions(+), 188 deletions(-)
create mode 100644 sdk/storage/azure-storage-blob/tests/recordings/test_common_blob.test_azure_named_key_credential_access.yaml
create mode 100644 sdk/storage/azure-storage-blob/tests/recordings/test_common_blob_async.test_azure_named_key_credential_access.yaml
create mode 100644 sdk/storage/azure-storage-file-datalake/tests/recordings/test_datalake_service_client.test_azure_named_key_credential_access.yaml
create mode 100644 sdk/storage/azure-storage-file-datalake/tests/recordings/test_datalake_service_client_async.test_azure_named_key_credential_access.yaml
create mode 100644 sdk/storage/azure-storage-file-share/tests/recordings/test_file.test_azure_named_key_credential_access.yaml
create mode 100644 sdk/storage/azure-storage-file-share/tests/recordings/test_file_async.test_azure_named_key_credential_access.yaml
create mode 100644 sdk/storage/azure-storage-queue/tests/recordings/test_queue.test_azure_named_key_credential_access.yaml
create mode 100644 sdk/storage/azure-storage-queue/tests/recordings/test_queue_async.test_azure_named_key_credential_access.yaml
diff --git a/sdk/storage/azure-storage-blob-changefeed/azure/storage/blob/changefeed/_change_feed_client.py b/sdk/storage/azure-storage-blob-changefeed/azure/storage/blob/changefeed/_change_feed_client.py
index 9072aa760ad2..c91eccc5f53b 100644
--- a/sdk/storage/azure-storage-blob-changefeed/azure/storage/blob/changefeed/_change_feed_client.py
+++ b/sdk/storage/azure-storage-blob-changefeed/azure/storage/blob/changefeed/_change_feed_client.py
@@ -25,10 +25,12 @@ class ChangeFeedClient(object): # pylint: disable=too-many-public-methods
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str secondary_hostname:
The hostname of the secondary endpoint.
:keyword int max_single_get_size:
@@ -51,7 +53,7 @@ class ChangeFeedClient(object): # pylint: disable=too-many-public-methods
"""
def __init__(
self, account_url, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
@@ -60,7 +62,7 @@ def __init__(
@classmethod
def from_connection_string(
cls, conn_str, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
): # type: (...) -> ChangeFeedClient
"""Create ChangeFeedClient from a Connection String.
@@ -71,9 +73,11 @@ def from_connection_string(
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token, or the connection string already has shared
access key values. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account shared access
- key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
Credentials provided here will take precedence over those in the connection string.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:returns: A change feed client.
:rtype: ~azure.storage.blob.changefeed.ChangeFeedClient
diff --git a/sdk/storage/azure-storage-blob/CHANGELOG.md b/sdk/storage/azure-storage-blob/CHANGELOG.md
index 487f189a149d..5709caa3f2e8 100644
--- a/sdk/storage/azure-storage-blob/CHANGELOG.md
+++ b/sdk/storage/azure-storage-blob/CHANGELOG.md
@@ -5,6 +5,7 @@
This version and all future versions will require Python 3.7+. Python 3.6 is no longer supported.
### Features Added
+- Added support for `AzureNamedKeyCredential` as a valid `credential` type.
### Bugs Fixed
- Adjusted type hints for `upload_blob` and `StorageStreamDownloader.readall`.
diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/__init__.py b/sdk/storage/azure-storage-blob/azure/storage/blob/__init__.py
index 58442edc91ea..15f20338c80f 100644
--- a/sdk/storage/azure-storage-blob/azure/storage/blob/__init__.py
+++ b/sdk/storage/azure-storage-blob/azure/storage/blob/__init__.py
@@ -70,7 +70,7 @@
def upload_blob_to_url(
blob_url, # type: str
data, # type: Union[Iterable[AnyStr], IO[AnyStr]]
- credential=None, # type: Any
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs):
# type: (...) -> Dict[str, Any]
"""Upload data to a given URL
@@ -85,10 +85,12 @@ def upload_blob_to_url(
:param credential:
The credentials with which to authenticate. This is optional if the
blob URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword bool overwrite:
Whether the blob to be uploaded should overwrite the current data.
If True, upload_blob_to_url will overwrite any existing data. If set to False, the
@@ -127,7 +129,7 @@ def _download_to_stream(client, handle, **kwargs):
def download_blob_from_url(
blob_url, # type: str
output, # type: str
- credential=None, # type: Any
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs):
# type: (...) -> None
"""Download the contents of a blob to a local file or stream.
@@ -141,10 +143,12 @@ def download_blob_from_url(
:param credential:
The credentials with which to authenticate. This is optional if the
blob URL already has a SAS token or the blob is public. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials,
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword bool overwrite:
Whether the local file should be overwritten if it already exists. The default value is
`False` - in which case a ValueError will be raised if the file already exists. If set to
diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.py
index 62a08feb976e..30684bc1dcdd 100644
--- a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.py
+++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.py
@@ -104,10 +104,12 @@ class BlobClient(StorageAccountHostsMixin, StorageEncryptionMixin): # pylint: d
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -151,7 +153,7 @@ def __init__(
container_name, # type: str
blob_name, # type: str
snapshot=None, # type: Optional[Union[str, Dict[str, Any]]]
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
@@ -210,8 +212,13 @@ def _encode_source_url(self, source_url):
return '?'.join(result)
@classmethod
- def from_blob_url(cls, blob_url, credential=None, snapshot=None, **kwargs):
- # type: (Type[ClassType], str, Optional[Any], Optional[Union[str, Dict[str, Any]]], Any) -> ClassType
+ def from_blob_url(
+ cls, # type: Type[ClassType]
+ blob_url, # type: str
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
+ snapshot=None, # type: Optional[Union[str, Dict[str, Any]]]
+ **kwargs # type: Any
+ ): # type: (...) -> ClassType
"""Create BlobClient from a blob url. This doesn't support customized blob url with '/' in blob name.
:param str blob_url:
@@ -222,10 +229,12 @@ def from_blob_url(cls, blob_url, credential=None, snapshot=None, **kwargs):
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token, or the connection string already has shared
access key values. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account shared access
- key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:param str snapshot:
The optional blob snapshot on which to operate. This can be the snapshot ID string
or the response returned from :func:`create_snapshot`. If specified, this will override
@@ -291,7 +300,7 @@ def from_connection_string(
container_name, # type: str
blob_name, # type: str
snapshot=None, # type: Optional[str]
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
): # type: (...) -> ClassType
"""Create BlobClient from a Connection String.
@@ -309,9 +318,11 @@ def from_connection_string(
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token, or the connection string already has shared
access key values. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account shared access
- key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
Credentials provided here will take precedence over those in the connection string.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:returns: A Blob client.
:rtype: ~azure.storage.blob.BlobClient
diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.py
index 30907ef457ec..89abab31b4c7 100644
--- a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.py
+++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_service_client.py
@@ -73,10 +73,12 @@ class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin):
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -118,7 +120,7 @@ class BlobServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin):
def __init__(
self, account_url, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
@@ -148,7 +150,7 @@ def _format_url(self, hostname):
def from_connection_string(
cls, # type: Type[ClassType]
conn_str, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
): # type: (...) -> ClassType
"""Create BlobServiceClient from a Connection String.
@@ -159,9 +161,11 @@ def from_connection_string(
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token, or the connection string already has shared
access key values. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account shared access
- key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
Credentials provided here will take precedence over those in the connection string.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:returns: A Blob service client.
:rtype: ~azure.storage.blob.BlobServiceClient
diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.py
index a3fca708d043..39df3da26e2d 100644
--- a/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.py
+++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_container_client.py
@@ -88,10 +88,12 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -133,7 +135,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
def __init__(
self, account_url, # type: str
container_name, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
@@ -169,8 +171,12 @@ def _format_url(self, hostname):
self._query_str)
@classmethod
- def from_container_url(cls, container_url, credential=None, **kwargs):
- # type: (Type[ClassType], str, Optional[Any], Any) -> ClassType
+ def from_container_url(
+ cls, # type: Type[ClassType]
+ container_url, # type: str
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
+ **kwargs # type: Any
+ ): # type: (...) -> ClassType
"""Create ContainerClient from a container url.
:param str container_url:
@@ -181,10 +187,12 @@ def from_container_url(cls, container_url, credential=None, **kwargs):
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token, or the connection string already has shared
access key values. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account shared access
- key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:returns: A container client.
:rtype: ~azure.storage.blob.ContainerClient
"""
@@ -216,7 +224,7 @@ def from_connection_string(
cls, # type: Type[ClassType]
conn_str, # type: str
container_name, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
): # type: (...) -> ClassType
"""Create ContainerClient from a Connection String.
@@ -230,9 +238,11 @@ def from_connection_string(
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token, or the connection string already has shared
access key values. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account shared access
- key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
Credentials provided here will take precedence over those in the connection string.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:returns: A container client.
:rtype: ~azure.storage.blob.ContainerClient
diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/base_client.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/base_client.py
index 6365e1688e49..a9ea706d92f6 100644
--- a/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/base_client.py
+++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/base_client.py
@@ -6,9 +6,12 @@
import logging
import uuid
from typing import ( # pylint: disable=unused-import
- Optional,
Any,
+ Dict,
Tuple,
+ Union,
+ Optional,
+ TYPE_CHECKING
)
try:
@@ -20,7 +23,7 @@
import six
from azure.core.configuration import Configuration
-from azure.core.credentials import AzureSasCredential
+from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential
from azure.core.exceptions import HttpResponseError
from azure.core.pipeline import Pipeline
from azure.core.pipeline.transport import RequestsTransport, HttpTransport
@@ -53,6 +56,8 @@
from .._version import VERSION
from .response_handlers import process_storage_error, PartialBatchErrorException
+if TYPE_CHECKING:
+ from azure.core.credentials import TokenCredential
_LOGGER = logging.getLogger(__name__)
_SERVICE_PARAMS = {
@@ -68,7 +73,7 @@ def __init__(
self,
parsed_url, # type: Any
service, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
@@ -353,6 +358,8 @@ def _format_shared_key_credential(account_name, credential):
if "account_key" not in credential:
raise ValueError("Shared key credential missing 'account_key")
return SharedKeyCredentialPolicy(**credential)
+ if isinstance(credential, AzureNamedKeyCredential):
+ return SharedKeyCredentialPolicy(credential.named_key.name, credential.named_key.key)
return credential
diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/__init__.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/__init__.py
index cfd991e34507..e8286fe217b1 100644
--- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/__init__.py
+++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/__init__.py
@@ -19,7 +19,7 @@
async def upload_blob_to_url(
blob_url, # type: str
data, # type: Union[Iterable[AnyStr], IO[AnyStr]]
- credential=None, # type: Any
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs):
# type: (...) -> dict[str, Any]
"""Upload data to a given URL
@@ -31,13 +31,15 @@ async def upload_blob_to_url(
:param data:
The data to upload. This can be bytes, text, an iterable or a file-like object.
:type data: bytes or str or Iterable
- :param credential:
+ :param credential:
The credentials with which to authenticate. This is optional if the
blob URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword bool overwrite:
Whether the blob to be uploaded should overwrite the current data.
If True, upload_blob_to_url will overwrite any existing data. If set to False, the
@@ -76,7 +78,7 @@ async def _download_to_stream(client, handle, **kwargs):
async def download_blob_from_url(
blob_url, # type: str
output, # type: str
- credential=None, # type: Any
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs):
# type: (...) -> None
"""Download the contents of a blob to a local file or stream.
@@ -90,10 +92,12 @@ async def download_blob_from_url(
:param credential:
The credentials with which to authenticate. This is optional if the
blob URL already has a SAS token or the blob is public. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials,
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword bool overwrite:
Whether the local file should be overwritten if it already exists. The default value is
`False` - in which case a ValueError will be raised if the file already exists. If set to
diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_client_async.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_client_async.py
index 850ea689ae7f..3566ec7c7feb 100644
--- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_client_async.py
+++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_client_async.py
@@ -70,10 +70,12 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -117,7 +119,7 @@ def __init__(
container_name, # type: str
blob_name, # type: str
snapshot=None, # type: Optional[Union[str, Dict[str, Any]]]
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.py
index f10f8b1dd0a4..5fd5301e027e 100644
--- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.py
+++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_blob_service_client_async.py
@@ -69,10 +69,12 @@ class BlobServiceClient(AsyncStorageAccountHostsMixin, BlobServiceClientBase, St
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -114,7 +116,7 @@ class BlobServiceClient(AsyncStorageAccountHostsMixin, BlobServiceClientBase, St
def __init__(
self, account_url, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_container_client_async.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_container_client_async.py
index fc3c267037ff..a139e3f4bf3e 100644
--- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_container_client_async.py
+++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/_container_client_async.py
@@ -64,10 +64,12 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -109,7 +111,7 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
def __init__(
self, account_url, # type: str
container_name, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
diff --git a/sdk/storage/azure-storage-blob/tests/recordings/test_common_blob.test_azure_named_key_credential_access.yaml b/sdk/storage/azure-storage-blob/tests/recordings/test_common_blob.test_azure_named_key_credential_access.yaml
new file mode 100644
index 000000000000..00ddc7cfd9e6
--- /dev/null
+++ b/sdk/storage/azure-storage-blob/tests/recordings/test_common_blob.test_azure_named_key_credential_access.yaml
@@ -0,0 +1,40 @@
+interactions:
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ Content-Length:
+ - '0'
+ User-Agent:
+ - azsdk-python-storage-blob/12.13.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-date:
+ - Thu, 23 Jun 2022 23:44:15 GMT
+ x-ms-version:
+ - '2021-08-06'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/container76851672?restype=container
+ response:
+ body:
+ string: ''
+ headers:
+ content-length:
+ - '0'
+ date:
+ - Thu, 23 Jun 2022 23:44:16 GMT
+ etag:
+ - '"0x8DA557248FF6AA9"'
+ last-modified:
+ - Thu, 23 Jun 2022 23:44:16 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-version:
+ - '2021-08-06'
+ status:
+ code: 201
+ message: Created
+version: 1
diff --git a/sdk/storage/azure-storage-blob/tests/recordings/test_common_blob_async.test_azure_named_key_credential_access.yaml b/sdk/storage/azure-storage-blob/tests/recordings/test_common_blob_async.test_azure_named_key_credential_access.yaml
new file mode 100644
index 000000000000..c83ff83bf5fc
--- /dev/null
+++ b/sdk/storage/azure-storage-blob/tests/recordings/test_common_blob_async.test_azure_named_key_credential_access.yaml
@@ -0,0 +1,29 @@
+interactions:
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-blob/12.13.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-date:
+ - Thu, 23 Jun 2022 23:47:19 GMT
+ x-ms-version:
+ - '2021-08-06'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/container81e18ef?restype=container
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '0'
+ date: Thu, 23 Jun 2022 23:47:19 GMT
+ etag: '"0x8DA5572B65BCF75"'
+ last-modified: Thu, 23 Jun 2022 23:47:20 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-version: '2021-08-06'
+ status:
+ code: 201
+ message: Created
+ url: https://vincenttranstock.blob.core.windows.net/container81e18ef?restype=container
+version: 1
diff --git a/sdk/storage/azure-storage-blob/tests/test_common_blob.py b/sdk/storage/azure-storage-blob/tests/test_common_blob.py
index b497d382ac38..1a53f36e80d5 100644
--- a/sdk/storage/azure-storage-blob/tests/test_common_blob.py
+++ b/sdk/storage/azure-storage-blob/tests/test_common_blob.py
@@ -18,7 +18,7 @@
from azure.core import MatchConditions
-from azure.core.credentials import AzureSasCredential
+from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential
from azure.core.exceptions import (
HttpResponseError,
ResourceNotFoundError,
@@ -1995,6 +1995,19 @@ def test_account_sas_credential(self, storage_account_name, storage_account_key)
self.assertEqual(blob_name, blob_properties.name)
self.assertEqual(self.container_name, container_properties.name)
+ @BlobPreparer()
+ def test_azure_named_key_credential_access(self, storage_account_name, storage_account_key):
+ named_key = AzureNamedKeyCredential(storage_account_name, storage_account_key)
+ bsc = BlobServiceClient(self.account_url(storage_account_name, "blob"), named_key)
+ container_name = self._get_container_reference()
+
+ # Act
+ container = bsc.get_container_client(container_name)
+ created = container.create_container()
+
+ # Assert
+ self.assertTrue(created)
+
@BlobPreparer()
def test_get_user_delegation_key(self, storage_account_name, storage_account_key):
# Act
diff --git a/sdk/storage/azure-storage-blob/tests/test_common_blob_async.py b/sdk/storage/azure-storage-blob/tests/test_common_blob_async.py
index c945a18d49da..8dfb89a47c5a 100644
--- a/sdk/storage/azure-storage-blob/tests/test_common_blob_async.py
+++ b/sdk/storage/azure-storage-blob/tests/test_common_blob_async.py
@@ -19,7 +19,7 @@
from azure.mgmt.storage.aio import StorageManagementClient
from azure.core import MatchConditions
-from azure.core.credentials import AzureSasCredential
+from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential
from azure.core.exceptions import (
HttpResponseError,
ResourceNotFoundError,
@@ -2037,6 +2037,20 @@ async def test_account_sas_credential(self, storage_account_name, storage_accoun
self.assertEqual(blob_name, blob_properties.name)
self.assertEqual(self.container_name, container_properties.name)
+ @BlobPreparer()
+ @AsyncStorageTestCase.await_prepared_test
+ async def test_azure_named_key_credential_access(self, storage_account_name, storage_account_key):
+ named_key = AzureNamedKeyCredential(storage_account_name, storage_account_key)
+ bsc = BlobServiceClient(self.account_url(storage_account_name, "blob"), named_key)
+ container_name = self._get_container_reference()
+
+ # Act
+ container = bsc.get_container_client(container_name)
+ created = await container.create_container()
+
+ # Assert
+ self.assertTrue(created)
+
@pytest.mark.live_test_only
@BlobPreparer()
@AsyncStorageTestCase.await_prepared_test
diff --git a/sdk/storage/azure-storage-file-datalake/CHANGELOG.md b/sdk/storage/azure-storage-file-datalake/CHANGELOG.md
index c5546c2a0149..143e02067c94 100644
--- a/sdk/storage/azure-storage-file-datalake/CHANGELOG.md
+++ b/sdk/storage/azure-storage-file-datalake/CHANGELOG.md
@@ -5,6 +5,7 @@
This version and all future versions will require Python 3.7+. Python 3.6 is no longer supported.
### Features Added
+- Added support for `AzureNamedKeyCredential` as a valid `credential` type.
### Bugs Fixed
diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_directory_client.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_directory_client.py
index 19231fa3beca..2a93df0eae88 100644
--- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_directory_client.py
+++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_directory_client.py
@@ -47,10 +47,12 @@ class DataLakeDirectoryClient(PathClient):
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, and account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -68,7 +70,7 @@ def __init__(
self, account_url, # type: str
file_system_name, # type: str
directory_name, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
@@ -81,7 +83,7 @@ def from_connection_string(
conn_str, # type: str
file_system_name, # type: str
directory_name, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
): # type: (...) -> ClassType
"""
@@ -99,9 +101,11 @@ def from_connection_string(
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token, or the connection string already has shared
access key values. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, and account shared access
- key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
Credentials provided here will take precedence over those in the connection string.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:return: a DataLakeDirectoryClient
:rtype: ~azure.storage.filedatalake.DataLakeDirectoryClient
"""
diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_file_client.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_file_client.py
index 54552e2c0c46..f433965541d9 100644
--- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_file_client.py
+++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_file_client.py
@@ -57,10 +57,12 @@ class DataLakeFileClient(PathClient):
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -78,7 +80,7 @@ def __init__(
self, account_url, # type: str
file_system_name, # type: str
file_path, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
@@ -91,7 +93,7 @@ def from_connection_string(
conn_str, # type: str
file_system_name, # type: str
file_path, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
): # type: (...) -> ClassType
"""
@@ -109,9 +111,11 @@ def from_connection_string(
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token, or the connection string already has shared
access key values. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account shared access
- key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
Credentials provided here will take precedence over those in the connection string.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:return a DataLakeFileClient
:rtype ~azure.storage.filedatalake.DataLakeFileClient
"""
diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_service_client.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_service_client.py
index a5bfff3c531c..d55f13b89fe6 100644
--- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_service_client.py
+++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_service_client.py
@@ -47,10 +47,12 @@ class DataLakeServiceClient(StorageAccountHostsMixin):
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_file_system_client.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_file_system_client.py
index 79ac40de8c28..ab25f4c176f2 100644
--- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_file_system_client.py
+++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_file_system_client.py
@@ -58,10 +58,12 @@ class FileSystemClient(StorageAccountHostsMixin):
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -78,7 +80,7 @@ class FileSystemClient(StorageAccountHostsMixin):
def __init__(
self, account_url, # type: str
file_system_name, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
@@ -150,7 +152,7 @@ def from_connection_string(
cls, # type: Type[ClassType]
conn_str, # type: str
file_system_name, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
): # type: (...) -> ClassType
"""
@@ -164,9 +166,11 @@ def from_connection_string(
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token, or the connection string already has shared
access key values. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account shared access
- key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
Credentials provided here will take precedence over those in the connection string.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:return a FileSystemClient
:rtype ~azure.storage.filedatalake.FileSystemClient
diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_path_client.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_path_client.py
index 36dddb60cacc..2d8c14cbee12 100644
--- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_path_client.py
+++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_path_client.py
@@ -47,10 +47,12 @@ class PathClient(StorageAccountHostsMixin):
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -59,7 +61,7 @@ def __init__(
self, account_url, # type: str
file_system_name, # type: str
path_name, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/base_client.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/base_client.py
index 3af10b496f22..8ccc285ca329 100644
--- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/base_client.py
+++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/base_client.py
@@ -9,6 +9,7 @@
Optional,
Any,
Tuple,
+ TYPE_CHECKING
)
try:
@@ -20,7 +21,7 @@
import six
from azure.core.configuration import Configuration
-from azure.core.credentials import AzureSasCredential
+from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential
from azure.core.exceptions import HttpResponseError
from azure.core.pipeline import Pipeline
from azure.core.pipeline.transport import RequestsTransport, HttpTransport
@@ -53,6 +54,8 @@
from .._version import VERSION
from .response_handlers import process_storage_error, PartialBatchErrorException
+if TYPE_CHECKING:
+ from azure.core.credentials import TokenCredential
_LOGGER = logging.getLogger(__name__)
_SERVICE_PARAMS = {
@@ -67,7 +70,7 @@ def __init__(
self,
parsed_url, # type: Any
service, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
@@ -352,6 +355,8 @@ def _format_shared_key_credential(account_name, credential):
if "account_key" not in credential:
raise ValueError("Shared key credential missing 'account_key")
return SharedKeyCredentialPolicy(**credential)
+ if isinstance(credential, AzureNamedKeyCredential):
+ return SharedKeyCredentialPolicy(credential.named_key.name, credential.named_key.key)
return credential
diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_directory_client_async.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_directory_client_async.py
index 923fafec280f..5c0fa8a061be 100644
--- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_directory_client_async.py
+++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_directory_client_async.py
@@ -47,10 +47,12 @@ class DataLakeDirectoryClient(PathClient, DataLakeDirectoryClientBase):
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -69,7 +71,7 @@ def __init__(
self, account_url, # type: str
file_system_name, # type: str
directory_name, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_file_client_async.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_file_client_async.py
index 5ac4840e36b7..39ddcb1cc85f 100644
--- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_file_client_async.py
+++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_file_client_async.py
@@ -48,10 +48,12 @@ class DataLakeFileClient(PathClient, DataLakeFileClientBase):
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -70,7 +72,7 @@ def __init__(
self, account_url, # type: str
file_system_name, # type: str
file_path, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_service_client_async.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_service_client_async.py
index c4c48dddad9f..c71160695f37 100644
--- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_service_client_async.py
+++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_service_client_async.py
@@ -44,10 +44,12 @@ class DataLakeServiceClient(AsyncStorageAccountHostsMixin, DataLakeServiceClient
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -71,7 +73,7 @@ class DataLakeServiceClient(AsyncStorageAccountHostsMixin, DataLakeServiceClient
def __init__(
self, account_url, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_file_system_client_async.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_file_system_client_async.py
index a837085b48c1..46b847d7ae5b 100644
--- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_file_system_client_async.py
+++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_file_system_client_async.py
@@ -61,10 +61,12 @@ class FileSystemClient(AsyncStorageAccountHostsMixin, FileSystemClientBase):
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -82,7 +84,7 @@ class FileSystemClient(AsyncStorageAccountHostsMixin, FileSystemClientBase):
def __init__(
self, account_url, # type: str
file_system_name, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_path_client_async.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_path_client_async.py
index 604d19c83fec..bff06eb9523f 100644
--- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_path_client_async.py
+++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_path_client_async.py
@@ -39,10 +39,12 @@ class PathClient(AsyncStorageAccountHostsMixin, PathClientBase):
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -51,7 +53,7 @@ def __init__(
self, account_url, # type: str
file_system_name, # type: str
path_name, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
diff --git a/sdk/storage/azure-storage-file-datalake/setup.py b/sdk/storage/azure-storage-file-datalake/setup.py
index 5d3a1d9e576a..43ccc5d1452b 100644
--- a/sdk/storage/azure-storage-file-datalake/setup.py
+++ b/sdk/storage/azure-storage-file-datalake/setup.py
@@ -77,6 +77,6 @@
install_requires=[
"azure-core<2.0.0,>=1.23.1",
"msrest>=0.6.21",
- "azure-storage-blob<13.0.0,>=12.13.0"
+ "azure-storage-blob<13.0.0,>=12.14.0b1"
],
)
diff --git a/sdk/storage/azure-storage-file-datalake/tests/recordings/test_datalake_service_client.test_azure_named_key_credential_access.yaml b/sdk/storage/azure-storage-file-datalake/tests/recordings/test_datalake_service_client.test_azure_named_key_credential_access.yaml
new file mode 100644
index 000000000000..56be9ab4cc92
--- /dev/null
+++ b/sdk/storage/azure-storage-file-datalake/tests/recordings/test_datalake_service_client.test_azure_named_key_credential_access.yaml
@@ -0,0 +1,37 @@
+interactions:
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ User-Agent:
+ - azsdk-python-storage-blob/12.13.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-date:
+ - Tue, 12 Jul 2022 00:28:51 GMT
+ x-ms-version:
+ - '2021-08-06'
+ method: GET
+ uri: https://storagename.blob.core.windows.net/?restype=service&comp=properties
+ response:
+ body:
+ string: "\uFEFF1.0falsefalsefalsefalse1.0truetruetrue71.0falsefalsefalsefalsefalse"
+ headers:
+ content-type:
+ - application/xml
+ date:
+ - Tue, 12 Jul 2022 00:28:51 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ transfer-encoding:
+ - chunked
+ x-ms-version:
+ - '2021-08-06'
+ status:
+ code: 200
+ message: OK
+version: 1
diff --git a/sdk/storage/azure-storage-file-datalake/tests/recordings/test_datalake_service_client_async.test_azure_named_key_credential_access.yaml b/sdk/storage/azure-storage-file-datalake/tests/recordings/test_datalake_service_client_async.test_azure_named_key_credential_access.yaml
new file mode 100644
index 000000000000..17aa5e7ad1c3
--- /dev/null
+++ b/sdk/storage/azure-storage-file-datalake/tests/recordings/test_datalake_service_client_async.test_azure_named_key_credential_access.yaml
@@ -0,0 +1,29 @@
+interactions:
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-blob/12.13.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-date:
+ - Tue, 12 Jul 2022 00:29:02 GMT
+ x-ms-version:
+ - '2021-08-06'
+ method: GET
+ uri: https://storagename.blob.core.windows.net/?restype=service&comp=properties
+ response:
+ body:
+ string: "\uFEFF1.0falsefalsefalsefalse1.0truetruetrue71.0falsefalsefalsefalsefalse"
+ headers:
+ content-type: application/xml
+ date: Tue, 12 Jul 2022 00:29:01 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ transfer-encoding: chunked
+ x-ms-version: '2021-08-06'
+ status:
+ code: 200
+ message: OK
+ url: https://vincenttranhnscanary.blob.core.windows.net/?restype=service&comp=properties
+version: 1
diff --git a/sdk/storage/azure-storage-file-datalake/tests/test_datalake_service_client.py b/sdk/storage/azure-storage-file-datalake/tests/test_datalake_service_client.py
index 7fc281eb5dd9..e3b39925712e 100644
--- a/sdk/storage/azure-storage-file-datalake/tests/test_datalake_service_client.py
+++ b/sdk/storage/azure-storage-file-datalake/tests/test_datalake_service_client.py
@@ -19,6 +19,7 @@
from settings.testcase import DataLakePreparer
from devtools_testutils.storage import StorageTestCase
+from azure.core.credentials import AzureNamedKeyCredential
# ------------------------------------------------------------------------------
from azure.storage.filedatalake._models import AnalyticsLogging, Metrics, RetentionPolicy, \
@@ -348,3 +349,14 @@ def test_connectionstring_without_secondary(self):
assert client.url == 'https://foo.dfs.core.windows.net/fsname/dname'
assert client.primary_hostname == 'foo.dfs.core.windows.net'
assert not client.secondary_hostname
+
+ @DataLakePreparer()
+ def test_azure_named_key_credential_access(self, datalake_storage_account_name, datalake_storage_account_key):
+ named_key = AzureNamedKeyCredential(datalake_storage_account_name, datalake_storage_account_key)
+ dsc = DataLakeServiceClient(self.account_url(datalake_storage_account_name, "blob"), named_key)
+
+ # Act
+ props = dsc.get_service_properties()
+
+ # Assert
+ self.assertIsNotNone(props)
diff --git a/sdk/storage/azure-storage-file-datalake/tests/test_datalake_service_client_async.py b/sdk/storage/azure-storage-file-datalake/tests/test_datalake_service_client_async.py
index 84d05e467c73..2d8fec0910d4 100644
--- a/sdk/storage/azure-storage-file-datalake/tests/test_datalake_service_client_async.py
+++ b/sdk/storage/azure-storage-file-datalake/tests/test_datalake_service_client_async.py
@@ -19,6 +19,7 @@
)
from devtools_testutils.storage.aio import AsyncStorageTestCase as StorageTestCase
from settings.testcase import DataLakePreparer
+from azure.core.credentials import AzureNamedKeyCredential
# ------------------------------------------------------------------------------
from azure.storage.filedatalake._models import AnalyticsLogging, Metrics, RetentionPolicy, \
@@ -343,3 +344,14 @@ async def test_connectionstring_without_secondary(self):
assert client.url == 'https://foo.dfs.core.windows.net/fsname/dname'
assert client.primary_hostname == 'foo.dfs.core.windows.net'
assert not client.secondary_hostname
+
+ @DataLakePreparer()
+ async def test_azure_named_key_credential_access(self, datalake_storage_account_name, datalake_storage_account_key):
+ named_key = AzureNamedKeyCredential(datalake_storage_account_name, datalake_storage_account_key)
+ dsc = DataLakeServiceClient(self.account_url(datalake_storage_account_name, "blob"), named_key)
+
+ # Act
+ props = await dsc.get_service_properties()
+
+ # Assert
+ self.assertIsNotNone(props)
diff --git a/sdk/storage/azure-storage-file-share/CHANGELOG.md b/sdk/storage/azure-storage-file-share/CHANGELOG.md
index 0e862987009a..0daccb992e53 100644
--- a/sdk/storage/azure-storage-file-share/CHANGELOG.md
+++ b/sdk/storage/azure-storage-file-share/CHANGELOG.md
@@ -5,6 +5,7 @@
This version and all future versions will require Python 3.7+. Python 3.6 is no longer supported.
### Features Added
+- Added support for `AzureNamedKeyCredential` as a valid `credential` type.
### Bugs Fixed
diff --git a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_directory_client.py b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_directory_client.py
index 643af020894c..3c4132a59512 100644
--- a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_directory_client.py
+++ b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_directory_client.py
@@ -63,10 +63,14 @@ class ShareDirectoryClient(StorageAccountHostsMixin):
An optional share snapshot on which to operate. This can be the snapshot ID string
or the response returned from :func:`ShareClient.create_snapshot`.
:param credential:
- The credential with which to authenticate. This is optional if the
+ The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials or an account
- shared access key.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -82,7 +86,7 @@ def __init__( # type: ignore
share_name, # type: str
directory_path, # type: str
snapshot=None, # type: Optional[Union[str, Dict[str, Any]]]
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Optional[Any]
):
# type: (...) -> None
@@ -123,7 +127,7 @@ def __init__( # type: ignore
@classmethod
def from_directory_url(cls, directory_url, # type: str
snapshot=None, # type: Optional[Union[str, Dict[str, Any]]]
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Optional[Any]
):
# type: (...) -> ShareDirectoryClient
@@ -135,10 +139,14 @@ def from_directory_url(cls, directory_url, # type: str
An optional share snapshot on which to operate. This can be the snapshot ID string
or the response returned from :func:`ShareClient.create_snapshot`.
:param credential:
- The credential with which to authenticate. This is optional if the
- account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials or an account
- shared access key.
+ The credentials with which to authenticate. This is optional if the
+ account URL already has a SAS token. The value can be a SAS token string,
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:returns: A directory client.
:rtype: ~azure.storage.fileshare.ShareDirectoryClient
"""
@@ -185,7 +193,7 @@ def from_connection_string(
cls, conn_str, # type: str
share_name, # type: str
directory_path, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> ShareDirectoryClient
@@ -198,10 +206,14 @@ def from_connection_string(
:param str directory_path:
The directory path.
:param credential:
- The credential with which to authenticate. This is optional if the
+ The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials or an account
- shared access key.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:returns: A directory client.
:rtype: ~azure.storage.fileshare.ShareDirectoryClient
"""
diff --git a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_file_client.py b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_file_client.py
index a2b0fec1abca..c3d3afdd461f 100644
--- a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_file_client.py
+++ b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_file_client.py
@@ -123,10 +123,14 @@ class ShareFileClient(StorageAccountHostsMixin):
An optional file snapshot on which to operate. This can be the snapshot ID string
or the response returned from :func:`ShareClient.create_snapshot`.
:param credential:
- The credential with which to authenticate. This is optional if the
+ The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials or an account
- shared access key.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -142,7 +146,7 @@ def __init__( # type: ignore
share_name, # type: str
file_path, # type: str
snapshot=None, # type: Optional[Union[str, Dict[str, Any]]]
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
@@ -187,7 +191,7 @@ def __init__( # type: ignore
def from_file_url(
cls, file_url, # type: str
snapshot=None, # type: Optional[Union[str, Dict[str, Any]]]
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> ShareFileClient
@@ -198,10 +202,14 @@ def from_file_url(
An optional file snapshot on which to operate. This can be the snapshot ID string
or the response returned from :func:`ShareClient.create_snapshot`.
:param credential:
- The credential with which to authenticate. This is optional if the
+ The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials or an account
- shared access key.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:returns: A File client.
:rtype: ~azure.storage.fileshare.ShareFileClient
"""
@@ -243,7 +251,7 @@ def from_connection_string(
share_name, # type: str
file_path, # type: str
snapshot=None, # type: Optional[Union[str, Dict[str, Any]]]
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> ShareFileClient
@@ -259,10 +267,14 @@ def from_connection_string(
An optional file snapshot on which to operate. This can be the snapshot ID string
or the response returned from :func:`ShareClient.create_snapshot`.
:param credential:
- The credential with which to authenticate. This is optional if the
+ The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials or an account
- shared access key.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:returns: A File client.
:rtype: ~azure.storage.fileshare.ShareFileClient
diff --git a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_share_client.py b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_share_client.py
index c5ee3aaed14e..4a699e1c2f67 100644
--- a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_share_client.py
+++ b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_share_client.py
@@ -62,10 +62,14 @@ class ShareClient(StorageAccountHostsMixin): # pylint: disable=too-many-public-m
An optional share snapshot on which to operate. This can be the snapshot ID string
or the response returned from :func:`create_snapshot`.
:param credential:
- The credential with which to authenticate. This is optional if the
+ The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials or an account
- shared access key.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -80,7 +84,7 @@ def __init__( # type: ignore
self, account_url, # type: str
share_name, # type: str
snapshot=None, # type: Optional[Union[str, Dict[str, Any]]]
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
@@ -120,7 +124,7 @@ def __init__( # type: ignore
@classmethod
def from_share_url(cls, share_url, # type: str
snapshot=None, # type: Optional[Union[str, Dict[str, Any]]]
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> ShareClient
@@ -130,10 +134,14 @@ def from_share_url(cls, share_url, # type: str
An optional share snapshot on which to operate. This can be the snapshot ID string
or the response returned from :func:`create_snapshot`.
:param credential:
- The credential with which to authenticate. This is optional if the
+ The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials or an account
- shared access key.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:returns: A share client.
:rtype: ~azure.storage.fileshare.ShareClient
"""
@@ -189,7 +197,7 @@ def from_connection_string(
cls, conn_str, # type: str
share_name, # type: str
snapshot=None, # type: Optional[str]
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> ShareClient
@@ -203,10 +211,14 @@ def from_connection_string(
The optional share snapshot on which to operate. This can be the snapshot ID string
or the response returned from :func:`create_snapshot`.
:param credential:
- The credential with which to authenticate. This is optional if the
+ The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials or an account
- shared access key.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:returns: A share client.
:rtype: ~azure.storage.fileshare.ShareClient
diff --git a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_share_service_client.py b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_share_service_client.py
index 46721ee9ea86..da9c8a065957 100644
--- a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_share_service_client.py
+++ b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_share_service_client.py
@@ -58,10 +58,14 @@ class ShareServiceClient(StorageAccountHostsMixin):
in the URL path (e.g. share or file) will be discarded. This URL can be optionally
authenticated with a SAS token.
:param credential:
- The credential with which to authenticate. This is optional if the
+ The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials or an account
- shared access key.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -83,7 +87,7 @@ class ShareServiceClient(StorageAccountHostsMixin):
"""
def __init__(
self, account_url, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
@@ -116,7 +120,7 @@ def _format_url(self, hostname):
@classmethod
def from_connection_string(
cls, conn_str, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
): # type: (...) -> ShareServiceClient
"""Create ShareServiceClient from a Connection String.
@@ -124,10 +128,14 @@ def from_connection_string(
:param str conn_str:
A connection string to an Azure Storage account.
:param credential:
- The credential with which to authenticate. This is optional if the
+ The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials or an account
- shared access key.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:returns: A File Share service client.
:rtype: ~azure.storage.fileshare.ShareServiceClient
diff --git a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/base_client.py b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/base_client.py
index 3af10b496f22..8ccc285ca329 100644
--- a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/base_client.py
+++ b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/base_client.py
@@ -9,6 +9,7 @@
Optional,
Any,
Tuple,
+ TYPE_CHECKING
)
try:
@@ -20,7 +21,7 @@
import six
from azure.core.configuration import Configuration
-from azure.core.credentials import AzureSasCredential
+from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential
from azure.core.exceptions import HttpResponseError
from azure.core.pipeline import Pipeline
from azure.core.pipeline.transport import RequestsTransport, HttpTransport
@@ -53,6 +54,8 @@
from .._version import VERSION
from .response_handlers import process_storage_error, PartialBatchErrorException
+if TYPE_CHECKING:
+ from azure.core.credentials import TokenCredential
_LOGGER = logging.getLogger(__name__)
_SERVICE_PARAMS = {
@@ -67,7 +70,7 @@ def __init__(
self,
parsed_url, # type: Any
service, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
@@ -352,6 +355,8 @@ def _format_shared_key_credential(account_name, credential):
if "account_key" not in credential:
raise ValueError("Shared key credential missing 'account_key")
return SharedKeyCredentialPolicy(**credential)
+ if isinstance(credential, AzureNamedKeyCredential):
+ return SharedKeyCredentialPolicy(credential.named_key.name, credential.named_key.key)
return credential
diff --git a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_directory_client_async.py b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_directory_client_async.py
index 6b6ed4be57d2..70003f928a76 100644
--- a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_directory_client_async.py
+++ b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_directory_client_async.py
@@ -54,10 +54,14 @@ class ShareDirectoryClient(AsyncStorageAccountHostsMixin, ShareDirectoryClientBa
An optional share snapshot on which to operate. This can be the snapshot ID string
or the response returned from :func:`ShareClient.create_snapshot`.
:param credential:
- The credential with which to authenticate. This is optional if the
+ The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials or an account
- shared access key.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -75,7 +79,7 @@ def __init__( # type: ignore
share_name, # type: str
directory_path, # type: str
snapshot=None, # type: Optional[Union[str, Dict[str, Any]]]
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Optional[Any]
):
# type: (...) -> None
diff --git a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_file_client_async.py b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_file_client_async.py
index bdccbbdcc82f..a27def34d133 100644
--- a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_file_client_async.py
+++ b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_file_client_async.py
@@ -111,10 +111,14 @@ class ShareFileClient(AsyncStorageAccountHostsMixin, ShareFileClientBase):
An optional file snapshot on which to operate. This can be the snapshot ID string
or the response returned from :func:`ShareClient.create_snapshot`.
:param credential:
- The credential with which to authenticate. This is optional if the
+ The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials or an account
- shared access key.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -134,7 +138,7 @@ def __init__( # type: ignore
share_name, # type: str
file_path, # type: str
snapshot=None, # type: Optional[Union[str, Dict[str, Any]]]
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
diff --git a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_share_client_async.py b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_share_client_async.py
index 437fb6d3050e..2fe3850b3270 100644
--- a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_share_client_async.py
+++ b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_share_client_async.py
@@ -51,10 +51,14 @@ class ShareClient(AsyncStorageAccountHostsMixin, ShareClientBase):
An optional share snapshot on which to operate. This can be the snapshot ID string
or the response returned from :func:`create_snapshot`.
:param credential:
- The credential with which to authenticate. This is optional if the
+ The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials or an account
- shared access key.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -71,7 +75,7 @@ def __init__( # type: ignore
self, account_url, # type: str
share_name, # type: str
snapshot=None, # type: Optional[Union[str, Dict[str, Any]]]
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
diff --git a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_share_service_client_async.py b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_share_service_client_async.py
index 9cf53d32933b..482bebc73793 100644
--- a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_share_service_client_async.py
+++ b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_share_service_client_async.py
@@ -51,10 +51,14 @@ class ShareServiceClient(AsyncStorageAccountHostsMixin, ShareServiceClientBase):
in the URL path (e.g. share or file) will be discarded. This URL can be optionally
authenticated with a SAS token.
:param credential:
- The credential with which to authenticate. This is optional if the
+ The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials or an account
- shared access key.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -78,7 +82,7 @@ class ShareServiceClient(AsyncStorageAccountHostsMixin, ShareServiceClientBase):
"""
def __init__(
self, account_url, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
diff --git a/sdk/storage/azure-storage-file-share/tests/recordings/test_file.test_azure_named_key_credential_access.yaml b/sdk/storage/azure-storage-file-share/tests/recordings/test_file.test_azure_named_key_credential_access.yaml
new file mode 100644
index 000000000000..0477b4ee2baa
--- /dev/null
+++ b/sdk/storage/azure-storage-file-share/tests/recordings/test_file.test_azure_named_key_credential_access.yaml
@@ -0,0 +1,217 @@
+interactions:
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ Content-Length:
+ - '0'
+ User-Agent:
+ - azsdk-python-storage-file-share/12.9.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-date:
+ - Thu, 30 Jun 2022 01:15:33 GMT
+ x-ms-version:
+ - '2021-06-08'
+ method: PUT
+ uri: https://storagename.file.core.windows.net/utsharedf1d138b?restype=share
+ response:
+ body:
+ string: "\uFEFFShareAlreadyExists
The
+ specified share already exists.\nRequestId:f8bf0e99-201a-0033-411e-8c8569000000\nTime:2022-06-30T01:15:32.9622302Z"
+ headers:
+ content-length:
+ - '222'
+ content-type:
+ - application/xml
+ date:
+ - Thu, 30 Jun 2022 01:15:32 GMT
+ server:
+ - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-error-code:
+ - ShareAlreadyExists
+ x-ms-version:
+ - '2021-06-08'
+ status:
+ code: 409
+ message: The specified share already exists.
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ Content-Length:
+ - '0'
+ User-Agent:
+ - azsdk-python-storage-file-share/12.9.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-content-length:
+ - '1024'
+ x-ms-date:
+ - Thu, 30 Jun 2022 01:15:34 GMT
+ x-ms-file-attributes:
+ - none
+ x-ms-file-creation-time:
+ - now
+ x-ms-file-last-write-time:
+ - now
+ x-ms-file-permission:
+ - Inherit
+ x-ms-type:
+ - file
+ x-ms-version:
+ - '2021-06-08'
+ method: PUT
+ uri: https://storagename.file.core.windows.net/utsharedf1d138b/filedf1d138b
+ response:
+ body:
+ string: ''
+ headers:
+ content-length:
+ - '0'
+ date:
+ - Thu, 30 Jun 2022 01:15:32 GMT
+ etag:
+ - '"0x8DA5A3607D7398B"'
+ last-modified:
+ - Thu, 30 Jun 2022 01:15:33 GMT
+ server:
+ - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-file-attributes:
+ - Archive
+ x-ms-file-change-time:
+ - '2022-06-30T01:15:33.2625803Z'
+ x-ms-file-creation-time:
+ - '2022-06-30T01:15:33.2625803Z'
+ x-ms-file-id:
+ - '13835128424026341376'
+ x-ms-file-last-write-time:
+ - '2022-06-30T01:15:33.2625803Z'
+ x-ms-file-parent-id:
+ - '0'
+ x-ms-file-permission-key:
+ - 8723072292820393796*15109150453380773834
+ x-ms-request-server-encrypted:
+ - 'true'
+ x-ms-version:
+ - '2021-06-08'
+ status:
+ code: 201
+ message: Created
+- request:
+ body: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ Content-Length:
+ - '1024'
+ Content-Type:
+ - application/octet-stream
+ User-Agent:
+ - azsdk-python-storage-file-share/12.9.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-date:
+ - Thu, 30 Jun 2022 01:15:34 GMT
+ x-ms-range:
+ - bytes=0-1023
+ x-ms-version:
+ - '2021-06-08'
+ x-ms-write:
+ - update
+ method: PUT
+ uri: https://storagename.file.core.windows.net/utsharedf1d138b/filedf1d138b?comp=range
+ response:
+ body:
+ string: ''
+ headers:
+ content-length:
+ - '0'
+ content-md5:
+ - yaNM/IXZgmmMasifdgcavQ==
+ date:
+ - Thu, 30 Jun 2022 01:15:32 GMT
+ etag:
+ - '"0x8DA5A3607F85154"'
+ last-modified:
+ - Thu, 30 Jun 2022 01:15:33 GMT
+ server:
+ - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-file-last-write-time:
+ - '2022-06-30T01:15:33.4794580Z'
+ x-ms-request-server-encrypted:
+ - 'true'
+ x-ms-version:
+ - '2021-06-08'
+ status:
+ code: 201
+ message: Created
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ User-Agent:
+ - azsdk-python-storage-file-share/12.9.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-date:
+ - Thu, 30 Jun 2022 01:15:34 GMT
+ x-ms-version:
+ - '2021-06-08'
+ method: HEAD
+ uri: https://storagename.file.core.windows.net/utsharedf1d138b/filedf1d138b
+ response:
+ body:
+ string: ''
+ headers:
+ content-length:
+ - '1024'
+ content-type:
+ - application/octet-stream
+ date:
+ - Thu, 30 Jun 2022 01:15:33 GMT
+ etag:
+ - '"0x8DA5A3607F85154"'
+ last-modified:
+ - Thu, 30 Jun 2022 01:15:33 GMT
+ server:
+ - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-file-attributes:
+ - Archive
+ x-ms-file-change-time:
+ - '2022-06-30T01:15:33.4794580Z'
+ x-ms-file-creation-time:
+ - '2022-06-30T01:15:33.2625803Z'
+ x-ms-file-id:
+ - '13835128424026341376'
+ x-ms-file-last-write-time:
+ - '2022-06-30T01:15:33.4794580Z'
+ x-ms-file-parent-id:
+ - '0'
+ x-ms-file-permission-key:
+ - 8723072292820393796*15109150453380773834
+ x-ms-lease-state:
+ - available
+ x-ms-lease-status:
+ - unlocked
+ x-ms-server-encrypted:
+ - 'true'
+ x-ms-type:
+ - File
+ x-ms-version:
+ - '2021-06-08'
+ status:
+ code: 200
+ message: OK
+version: 1
diff --git a/sdk/storage/azure-storage-file-share/tests/recordings/test_file_async.test_azure_named_key_credential_access.yaml b/sdk/storage/azure-storage-file-share/tests/recordings/test_file_async.test_azure_named_key_credential_access.yaml
new file mode 100644
index 000000000000..f86ec867e7ca
--- /dev/null
+++ b/sdk/storage/azure-storage-file-share/tests/recordings/test_file_async.test_azure_named_key_credential_access.yaml
@@ -0,0 +1,153 @@
+interactions:
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-file-share/12.9.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-date:
+ - Thu, 30 Jun 2022 01:16:46 GMT
+ x-ms-version:
+ - '2021-06-08'
+ method: PUT
+ uri: https://storagename.file.core.windows.net/utshare5f4c1608?restype=share
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '0'
+ date: Thu, 30 Jun 2022 01:16:44 GMT
+ etag: '"0x8DA5A3632D1E948"'
+ last-modified: Thu, 30 Jun 2022 01:16:45 GMT
+ server: Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-version: '2021-06-08'
+ status:
+ code: 201
+ message: Created
+ url: https://vincenttrancanary.file.core.windows.net/utshare5f4c1608?restype=share
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-file-share/12.9.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-content-length:
+ - '1024'
+ x-ms-date:
+ - Thu, 30 Jun 2022 01:16:46 GMT
+ x-ms-file-attributes:
+ - none
+ x-ms-file-creation-time:
+ - now
+ x-ms-file-last-write-time:
+ - now
+ x-ms-file-permission:
+ - Inherit
+ x-ms-type:
+ - file
+ x-ms-version:
+ - '2021-06-08'
+ method: PUT
+ uri: https://storagename.file.core.windows.net/utshare5f4c1608/file5f4c1608
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '0'
+ date: Thu, 30 Jun 2022 01:16:45 GMT
+ etag: '"0x8DA5A36333D6D57"'
+ last-modified: Thu, 30 Jun 2022 01:16:46 GMT
+ server: Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-file-attributes: Archive
+ x-ms-file-change-time: '2022-06-30T01:16:46.0744023Z'
+ x-ms-file-creation-time: '2022-06-30T01:16:46.0744023Z'
+ x-ms-file-id: '13835128424026341376'
+ x-ms-file-last-write-time: '2022-06-30T01:16:46.0744023Z'
+ x-ms-file-parent-id: '0'
+ x-ms-file-permission-key: 8723072292820393796*15109150453380773834
+ x-ms-request-server-encrypted: 'true'
+ x-ms-version: '2021-06-08'
+ status:
+ code: 201
+ message: Created
+ url: https://vincenttrancanary.file.core.windows.net/utshare5f4c1608/file5f4c1608
+- request:
+ body: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ headers:
+ Accept:
+ - application/xml
+ Content-Length:
+ - '1024'
+ Content-Type:
+ - application/octet-stream
+ User-Agent:
+ - azsdk-python-storage-file-share/12.9.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-date:
+ - Thu, 30 Jun 2022 01:16:47 GMT
+ x-ms-range:
+ - bytes=0-1023
+ x-ms-version:
+ - '2021-06-08'
+ x-ms-write:
+ - update
+ method: PUT
+ uri: https://storagename.file.core.windows.net/utshare5f4c1608/file5f4c1608?comp=range
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '0'
+ content-md5: yaNM/IXZgmmMasifdgcavQ==
+ date: Thu, 30 Jun 2022 01:16:45 GMT
+ etag: '"0x8DA5A36334DE5B2"'
+ last-modified: Thu, 30 Jun 2022 01:16:46 GMT
+ server: Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-file-last-write-time: '2022-06-30T01:16:46.1823410Z'
+ x-ms-request-server-encrypted: 'true'
+ x-ms-version: '2021-06-08'
+ status:
+ code: 201
+ message: Created
+ url: https://vincenttrancanary.file.core.windows.net/utshare5f4c1608/file5f4c1608?comp=range
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-file-share/12.9.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-date:
+ - Thu, 30 Jun 2022 01:16:47 GMT
+ x-ms-version:
+ - '2021-06-08'
+ method: HEAD
+ uri: https://storagename.file.core.windows.net/utshare5f4c1608/file5f4c1608
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '1024'
+ content-type: application/octet-stream
+ date: Thu, 30 Jun 2022 01:16:45 GMT
+ etag: '"0x8DA5A36334DE5B2"'
+ last-modified: Thu, 30 Jun 2022 01:16:46 GMT
+ server: Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-file-attributes: Archive
+ x-ms-file-change-time: '2022-06-30T01:16:46.1823410Z'
+ x-ms-file-creation-time: '2022-06-30T01:16:46.0744023Z'
+ x-ms-file-id: '13835128424026341376'
+ x-ms-file-last-write-time: '2022-06-30T01:16:46.1823410Z'
+ x-ms-file-parent-id: '0'
+ x-ms-file-permission-key: 8723072292820393796*15109150453380773834
+ x-ms-lease-state: available
+ x-ms-lease-status: unlocked
+ x-ms-server-encrypted: 'true'
+ x-ms-type: File
+ x-ms-version: '2021-06-08'
+ status:
+ code: 200
+ message: OK
+ url: https://vincenttrancanary.file.core.windows.net/utshare5f4c1608/file5f4c1608
+version: 1
diff --git a/sdk/storage/azure-storage-file-share/tests/test_file.py b/sdk/storage/azure-storage-file-share/tests/test_file.py
index c1c96e30c924..ad71cad0a6f5 100644
--- a/sdk/storage/azure-storage-file-share/tests/test_file.py
+++ b/sdk/storage/azure-storage-file-share/tests/test_file.py
@@ -13,7 +13,7 @@
import requests
import uuid
from azure.core import MatchConditions
-from azure.core.credentials import AzureSasCredential
+from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential
from azure.core.exceptions import HttpResponseError, ResourceNotFoundError, ResourceExistsError
from azure.storage.blob import BlobServiceClient
from azure.storage.fileshare import (
@@ -2148,6 +2148,25 @@ def test_account_sas_credential(self, storage_account_name, storage_account_key)
# Assert
self.assertIsNotNone(properties)
+ @FileSharePreparer()
+ def test_azure_named_key_credential_access(self, storage_account_name, storage_account_key):
+
+ self._setup(storage_account_name, storage_account_key)
+ file_client = self._create_file()
+ named_key = AzureNamedKeyCredential(storage_account_name, storage_account_key)
+
+ # Act
+ file_client = ShareFileClient(
+ self.account_url(storage_account_name, "file"),
+ share_name=self.share_name,
+ file_path=file_client.file_name,
+ credential=named_key)
+
+ properties = file_client.get_file_properties()
+
+ # Assert
+ self.assertIsNotNone(properties)
+
@FileSharePreparer()
def test_account_sas_raises_if_sas_already_in_uri(self, storage_account_name, storage_account_key):
with self.assertRaises(ValueError):
diff --git a/sdk/storage/azure-storage-file-share/tests/test_file_async.py b/sdk/storage/azure-storage-file-share/tests/test_file_async.py
index 895ccf2785db..07edab47046c 100644
--- a/sdk/storage/azure-storage-file-share/tests/test_file_async.py
+++ b/sdk/storage/azure-storage-file-share/tests/test_file_async.py
@@ -9,6 +9,10 @@
import os
from datetime import datetime, timedelta
+from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential
+from azure.core.pipeline.transport import AioHttpTransport
+from multidict import CIMultiDict, CIMultiDictProxy
+
import requests
import pytest
import uuid
@@ -2323,6 +2327,26 @@ async def test_account_sas_credential_async(self, storage_account_name, storage_
# Assert
self.assertIsNotNone(properties)
+ @FileSharePreparer()
+ @AsyncStorageTestCase.await_prepared_test
+ async def test_azure_named_key_credential_access(self, storage_account_name, storage_account_key):
+
+ self._setup(storage_account_name, storage_account_key)
+ file_client = await self._create_file(storage_account_name, storage_account_key)
+ named_key = AzureNamedKeyCredential(storage_account_name, storage_account_key)
+
+ # Act
+ file_client = ShareFileClient(
+ self.account_url(storage_account_name, "file"),
+ share_name=self.share_name,
+ file_path=file_client.file_name,
+ credential=named_key)
+
+ properties = await file_client.get_file_properties()
+
+ # Assert
+ self.assertIsNotNone(properties)
+
@FileSharePreparer()
def test_account_sas_raises_if_sas_already_in_uri(self, storage_account_name, storage_account_key):
with self.assertRaises(ValueError):
diff --git a/sdk/storage/azure-storage-queue/CHANGELOG.md b/sdk/storage/azure-storage-queue/CHANGELOG.md
index 29b26de64538..775c6a4167fb 100644
--- a/sdk/storage/azure-storage-queue/CHANGELOG.md
+++ b/sdk/storage/azure-storage-queue/CHANGELOG.md
@@ -5,6 +5,7 @@
This version and all future versions will require Python 3.7+. Python 3.6 is no longer supported.
### Features Added
+- Added support for `AzureNamedKeyCredential` as a valid `credential` type.
### Bugs Fixed
diff --git a/sdk/storage/azure-storage-queue/azure/storage/queue/_queue_client.py b/sdk/storage/azure-storage-queue/azure/storage/queue/_queue_client.py
index f4bbe136d593..efe95541fa1e 100644
--- a/sdk/storage/azure-storage-queue/azure/storage/queue/_queue_client.py
+++ b/sdk/storage/azure-storage-queue/azure/storage/queue/_queue_client.py
@@ -49,8 +49,12 @@ class QueueClient(StorageAccountHostsMixin, StorageEncryptionMixin):
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -75,7 +79,7 @@ class QueueClient(StorageAccountHostsMixin, StorageEncryptionMixin):
def __init__(
self, account_url, # type: str
queue_name, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
@@ -120,7 +124,7 @@ def _format_url(self, hostname):
@classmethod
def from_queue_url(cls,
queue_url, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> QueueClient
@@ -130,8 +134,12 @@ def from_queue_url(cls,
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:returns: A queue client.
:rtype: ~azure.storage.queue.QueueClient
"""
@@ -163,7 +171,7 @@ def from_queue_url(cls,
def from_connection_string(
cls, conn_str, # type: str
queue_name, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> QueueClient
@@ -177,8 +185,11 @@ def from_connection_string(
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token, or the connection string already has shared
access key values. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account shared access
- key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ Credentials provided here will take precedence over those in the connection string.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:returns: A queue client.
:rtype: ~azure.storage.queue.QueueClient
diff --git a/sdk/storage/azure-storage-queue/azure/storage/queue/_queue_service_client.py b/sdk/storage/azure-storage-queue/azure/storage/queue/_queue_service_client.py
index f8fcfaee5eb5..a0f090d7eda6 100644
--- a/sdk/storage/azure-storage-queue/azure/storage/queue/_queue_service_client.py
+++ b/sdk/storage/azure-storage-queue/azure/storage/queue/_queue_service_client.py
@@ -57,8 +57,12 @@ class QueueServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin):
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -84,7 +88,7 @@ class QueueServiceClient(StorageAccountHostsMixin, StorageEncryptionMixin):
def __init__(
self, account_url, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
@@ -115,7 +119,7 @@ def _format_url(self, hostname):
@classmethod
def from_connection_string(
cls, conn_str, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
): # type: (...) -> QueueServiceClient
"""Create QueueServiceClient from a Connection String.
@@ -126,8 +130,11 @@ def from_connection_string(
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token, or the connection string already has shared
access key values. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account shared access
- key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ Credentials provided here will take precedence over those in the connection string.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:returns: A Queue service client.
:rtype: ~azure.storage.queue.QueueClient
diff --git a/sdk/storage/azure-storage-queue/azure/storage/queue/_shared/base_client.py b/sdk/storage/azure-storage-queue/azure/storage/queue/_shared/base_client.py
index 3af10b496f22..5ddaf3eb5c97 100644
--- a/sdk/storage/azure-storage-queue/azure/storage/queue/_shared/base_client.py
+++ b/sdk/storage/azure-storage-queue/azure/storage/queue/_shared/base_client.py
@@ -9,6 +9,7 @@
Optional,
Any,
Tuple,
+ TYPE_CHECKING
)
try:
@@ -20,7 +21,7 @@
import six
from azure.core.configuration import Configuration
-from azure.core.credentials import AzureSasCredential
+from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential
from azure.core.exceptions import HttpResponseError
from azure.core.pipeline import Pipeline
from azure.core.pipeline.transport import RequestsTransport, HttpTransport
@@ -53,6 +54,9 @@
from .._version import VERSION
from .response_handlers import process_storage_error, PartialBatchErrorException
+if TYPE_CHECKING:
+ from azure.core.credentials import TokenCredential
+
_LOGGER = logging.getLogger(__name__)
_SERVICE_PARAMS = {
@@ -67,7 +71,7 @@ def __init__(
self,
parsed_url, # type: Any
service, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
@@ -352,6 +356,8 @@ def _format_shared_key_credential(account_name, credential):
if "account_key" not in credential:
raise ValueError("Shared key credential missing 'account_key")
return SharedKeyCredentialPolicy(**credential)
+ if isinstance(credential, AzureNamedKeyCredential):
+ return SharedKeyCredentialPolicy(credential.named_key.name, credential.named_key.key)
return credential
diff --git a/sdk/storage/azure-storage-queue/azure/storage/queue/aio/_queue_client_async.py b/sdk/storage/azure-storage-queue/azure/storage/queue/aio/_queue_client_async.py
index cc69d597ac4f..eb0c01017f81 100644
--- a/sdk/storage/azure-storage-queue/azure/storage/queue/aio/_queue_client_async.py
+++ b/sdk/storage/azure-storage-queue/azure/storage/queue/aio/_queue_client_async.py
@@ -48,8 +48,12 @@ class QueueClient(AsyncStorageAccountHostsMixin, QueueClientBase, StorageEncrypt
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -83,7 +87,7 @@ def __init__(
self,
account_url, # type: str
queue_name, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
diff --git a/sdk/storage/azure-storage-queue/azure/storage/queue/aio/_queue_service_client_async.py b/sdk/storage/azure-storage-queue/azure/storage/queue/aio/_queue_service_client_async.py
index 873515006b43..368cee23f26d 100644
--- a/sdk/storage/azure-storage-queue/azure/storage/queue/aio/_queue_service_client_async.py
+++ b/sdk/storage/azure-storage-queue/azure/storage/queue/aio/_queue_service_client_async.py
@@ -56,8 +56,12 @@ class QueueServiceClient(AsyncStorageAccountHostsMixin, QueueServiceClientBase,
:param credential:
The credentials with which to authenticate. This is optional if the
account URL already has a SAS token. The value can be a SAS token string,
- an instance of a AzureSasCredential from azure.core.credentials, an account
- shared access key, or an instance of a TokenCredentials class from azure.identity.
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
+ should be the storage account key.
:keyword str api_version:
The Storage API version to use for requests. Default value is the most recent service version that is
compatible with the current SDK. Setting to an older version may result in reduced feature compatibility.
@@ -83,7 +87,7 @@ class QueueServiceClient(AsyncStorageAccountHostsMixin, QueueServiceClientBase,
def __init__(
self, account_url, # type: str
- credential=None, # type: Optional[Any]
+ credential=None, # type: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "TokenCredential"]] # pylint: disable=line-too-long
**kwargs # type: Any
):
# type: (...) -> None
diff --git a/sdk/storage/azure-storage-queue/tests/recordings/test_queue.test_azure_named_key_credential_access.yaml b/sdk/storage/azure-storage-queue/tests/recordings/test_queue.test_azure_named_key_credential_access.yaml
new file mode 100644
index 000000000000..880fc14b7fdc
--- /dev/null
+++ b/sdk/storage/azure-storage-queue/tests/recordings/test_queue.test_azure_named_key_credential_access.yaml
@@ -0,0 +1,117 @@
+interactions:
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ Content-Length:
+ - '0'
+ User-Agent:
+ - azsdk-python-storage-queue/12.4.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-date:
+ - Thu, 30 Jun 2022 01:31:30 GMT
+ x-ms-version:
+ - '2021-02-12'
+ method: PUT
+ uri: https://storagename.queue.core.windows.net/pyqueuesyncf7f71410
+ response:
+ body:
+ string: ''
+ headers:
+ content-length:
+ - '0'
+ date:
+ - Thu, 30 Jun 2022 01:31:29 GMT
+ server:
+ - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-version:
+ - '2021-02-12'
+ status:
+ code: 201
+ message: Created
+- request:
+ body: '
+
+ message1'
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ Content-Length:
+ - '103'
+ Content-Type:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-queue/12.4.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-date:
+ - Thu, 30 Jun 2022 01:31:31 GMT
+ x-ms-version:
+ - '2021-02-12'
+ method: POST
+ uri: https://storagename.queue.core.windows.net/pyqueuesyncf7f71410/messages
+ response:
+ body:
+ string: "\uFEFFdc87d0b7-05a4-471c-8a0d-5c2ade57397bThu,
+ 30 Jun 2022 01:31:30 GMTThu, 07 Jul 2022 01:31:30
+ GMTAgAAAAMAAAAAAAAAlHXjHyGM2AE=Thu,
+ 30 Jun 2022 01:31:30 GMT"
+ headers:
+ content-type:
+ - application/xml
+ date:
+ - Thu, 30 Jun 2022 01:31:30 GMT
+ server:
+ - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0
+ transfer-encoding:
+ - chunked
+ x-ms-version:
+ - '2021-02-12'
+ status:
+ code: 201
+ message: Created
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ User-Agent:
+ - azsdk-python-storage-queue/12.4.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-date:
+ - Thu, 30 Jun 2022 01:31:31 GMT
+ x-ms-version:
+ - '2021-02-12'
+ method: GET
+ uri: https://storagename.queue.core.windows.net/pyqueuesyncf7f71410/messages?peekonly=true
+ response:
+ body:
+ string: "\uFEFFdc87d0b7-05a4-471c-8a0d-5c2ade57397bThu,
+ 30 Jun 2022 01:31:30 GMTThu, 07 Jul 2022 01:31:30
+ GMT0message1"
+ headers:
+ cache-control:
+ - no-cache
+ content-type:
+ - application/xml
+ date:
+ - Thu, 30 Jun 2022 01:31:30 GMT
+ server:
+ - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0
+ transfer-encoding:
+ - chunked
+ x-ms-version:
+ - '2021-02-12'
+ status:
+ code: 200
+ message: OK
+version: 1
diff --git a/sdk/storage/azure-storage-queue/tests/recordings/test_queue_async.test_azure_named_key_credential_access.yaml b/sdk/storage/azure-storage-queue/tests/recordings/test_queue_async.test_azure_named_key_credential_access.yaml
new file mode 100644
index 000000000000..708dfd79c783
--- /dev/null
+++ b/sdk/storage/azure-storage-queue/tests/recordings/test_queue_async.test_azure_named_key_credential_access.yaml
@@ -0,0 +1,91 @@
+interactions:
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-queue/12.4.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-date:
+ - Thu, 30 Jun 2022 01:32:54 GMT
+ x-ms-version:
+ - '2021-02-12'
+ method: PUT
+ uri: https://storagename.queue.core.windows.net/pyqueueasync7b44168d
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '0'
+ date: Thu, 30 Jun 2022 01:32:53 GMT
+ server: Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-version: '2021-02-12'
+ status:
+ code: 201
+ message: Created
+ url: https://vincenttranstock.queue.core.windows.net/pyqueueasync7b44168d
+- request:
+ body: '
+
+ message1'
+ headers:
+ Accept:
+ - application/xml
+ Content-Length:
+ - '103'
+ Content-Type:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-queue/12.4.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-date:
+ - Thu, 30 Jun 2022 01:32:55 GMT
+ x-ms-version:
+ - '2021-02-12'
+ method: POST
+ uri: https://storagename.queue.core.windows.net/pyqueueasync7b44168d/messages
+ response:
+ body:
+ string: "\uFEFFdee316b0-a564-41da-a385-006dcf1c8e50Thu,
+ 30 Jun 2022 01:32:54 GMTThu, 07 Jul 2022 01:32:54
+ GMTAgAAAAMAAAAAAAAAav7cUSGM2AE=Thu,
+ 30 Jun 2022 01:32:54 GMT"
+ headers:
+ content-type: application/xml
+ date: Thu, 30 Jun 2022 01:32:53 GMT
+ server: Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0
+ transfer-encoding: chunked
+ x-ms-version: '2021-02-12'
+ status:
+ code: 201
+ message: Created
+ url: https://vincenttranstock.queue.core.windows.net/pyqueueasync7b44168d/messages
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-queue/12.4.0 Python/3.10.2 (Windows-10-10.0.19044-SP0)
+ x-ms-date:
+ - Thu, 30 Jun 2022 01:32:55 GMT
+ x-ms-version:
+ - '2021-02-12'
+ method: GET
+ uri: https://storagename.queue.core.windows.net/pyqueueasync7b44168d/messages?peekonly=true
+ response:
+ body:
+ string: "\uFEFFdee316b0-a564-41da-a385-006dcf1c8e50Thu,
+ 30 Jun 2022 01:32:54 GMTThu, 07 Jul 2022 01:32:54
+ GMT0message1"
+ headers:
+ cache-control: no-cache
+ content-type: application/xml
+ date: Thu, 30 Jun 2022 01:32:53 GMT
+ server: Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0
+ transfer-encoding: chunked
+ x-ms-version: '2021-02-12'
+ status:
+ code: 200
+ message: OK
+ url: https://vincenttranstock.queue.core.windows.net/pyqueueasync7b44168d/messages?peekonly=true
+version: 1
diff --git a/sdk/storage/azure-storage-queue/tests/test_queue.py b/sdk/storage/azure-storage-queue/tests/test_queue.py
index 4c8e623ae383..4c2d0f723d61 100644
--- a/sdk/storage/azure-storage-queue/tests/test_queue.py
+++ b/sdk/storage/azure-storage-queue/tests/test_queue.py
@@ -14,7 +14,7 @@
date,
)
-from azure.core.credentials import AzureSasCredential
+from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential
from azure.core.pipeline.transport import RequestsTransport
from azure.core.exceptions import (
HttpResponseError,
@@ -725,6 +725,22 @@ def test_account_sas(self, storage_account_name, storage_account_key):
self.assertNotEqual('', message.id)
self.assertEqual(u'message1', message.content)
+ @QueuePreparer()
+ def test_azure_named_key_credential_access(self, storage_account_name, storage_account_key):
+
+ # Arrange
+ named_key = AzureNamedKeyCredential(storage_account_name, storage_account_key)
+ qsc = QueueServiceClient(self.account_url(storage_account_name, "queue"), named_key)
+ queue_client = self._get_queue_reference(qsc)
+ queue_client.create_queue()
+ queue_client.send_message(u'message1')
+
+ # Act
+ result = queue_client.peek_messages()
+
+ # Assert
+ self.assertIsNotNone(result)
+
@QueuePreparer()
def test_account_sas_raises_if_sas_already_in_uri(self, storage_account_name, storage_account_key):
with self.assertRaises(ValueError):
diff --git a/sdk/storage/azure-storage-queue/tests/test_queue_async.py b/sdk/storage/azure-storage-queue/tests/test_queue_async.py
index 0a67b04fe15a..4070cdde8bb3 100644
--- a/sdk/storage/azure-storage-queue/tests/test_queue_async.py
+++ b/sdk/storage/azure-storage-queue/tests/test_queue_async.py
@@ -14,7 +14,7 @@
date,
)
-from azure.core.credentials import AzureSasCredential
+from azure.core.credentials import AzureSasCredential, AzureNamedKeyCredential
from azure.core.pipeline.transport import AioHttpTransport
from azure.core.exceptions import (
HttpResponseError,
@@ -779,6 +779,22 @@ async def test_account_sas(self, storage_account_name, storage_account_key):
self.assertNotEqual('', message.id)
self.assertEqual(u'message1', message.content)
+ @QueuePreparer()
+ async def test_azure_named_key_credential_access(self, storage_account_name, storage_account_key):
+
+ # Arrange
+ named_key = AzureNamedKeyCredential(storage_account_name, storage_account_key)
+ qsc = QueueServiceClient(self.account_url(storage_account_name, "queue"), named_key)
+ queue_client = self._get_queue_reference(qsc)
+ await queue_client.create_queue()
+ await queue_client.send_message(u'message1')
+
+ # Act
+ result = await queue_client.peek_messages()
+
+ # Assert
+ self.assertIsNotNone(result)
+
@QueuePreparer()
def test_account_sas_raises_if_sas_already_in_uri(self, storage_account_name, storage_account_key):
with self.assertRaises(ValueError):
diff --git a/shared_requirements.txt b/shared_requirements.txt
index 99968b875cc9..c3fe9ce2b535 100644
--- a/shared_requirements.txt
+++ b/shared_requirements.txt
@@ -158,7 +158,7 @@ chardet<5,>=3.0.2
#override azure-storage-queue azure-core<2.0.0,>=1.23.1
#override azure-storage-file-share azure-core<2.0.0,>=1.23.1
#override azure-storage-file-datalake azure-core<2.0.0,>=1.23.1
-#override azure-storage-file-datalake azure-storage-blob<13.0.0,>=12.13.0
+#override azure-storage-file-datalake azure-storage-blob<13.0.0,>=12.14.0b1
#override azure-security-attestation azure-core<2.0.0,>=1.8.2
#override azure-data-tables msrest>=0.6.19
#override azure-schemaregistry azure-core<2.0.0,>=1.23.0