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 f3d2d16564a3..153b9b0751e7 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
@@ -1091,10 +1091,10 @@ def exists(self, **kwargs):
Returns True if a blob exists with the defined parameters, and returns
False otherwise.
- :param str version_id:
+ :kwarg str version_id:
The version id parameter is an opaque DateTime
value that, when present, specifies the version of the blob to check if it exists.
- :param int timeout:
+ :kwarg int timeout:
The timeout parameter is expressed in seconds.
:returns: boolean
"""
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 8788d14b704a..f84d5153dc03 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
@@ -21,7 +21,7 @@
import six
from azure.core import MatchConditions
-from azure.core.exceptions import HttpResponseError
+from azure.core.exceptions import HttpResponseError, ResourceNotFoundError
from azure.core.paging import ItemPaged
from azure.core.tracing.decorator import distributed_trace
from azure.core.pipeline import Pipeline
@@ -459,6 +459,25 @@ def get_container_properties(self, **kwargs):
response.name = self.container_name
return response # type: ignore
+ @distributed_trace
+ def exists(self, **kwargs):
+ # type: (**Any) -> bool
+ """
+ Returns True if a container exists and returns False otherwise.
+
+ :kwarg int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: boolean
+ """
+ try:
+ self._client.container.get_properties(**kwargs)
+ return True
+ except HttpResponseError as error:
+ try:
+ process_storage_error(error)
+ except ResourceNotFoundError:
+ return False
+
@distributed_trace
def set_container_metadata( # type: ignore
self, metadata=None, # type: Optional[Dict[str, str]]
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 1e1ae551339f..54a4e488b162 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
@@ -569,10 +569,10 @@ async def exists(self, **kwargs):
Returns True if a blob exists with the defined parameters, and returns
False otherwise.
- :param str version_id:
+ :kwarg str version_id:
The version id parameter is an opaque DateTime
value that, when present, specifies the version of the blob to check if it exists.
- :param int timeout:
+ :kwarg int timeout:
The timeout parameter is expressed in seconds.
:returns: boolean
"""
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 e26fe2388539..aa22b976a394 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
@@ -11,7 +11,7 @@
TYPE_CHECKING
)
-from azure.core.exceptions import HttpResponseError
+from azure.core.exceptions import HttpResponseError, ResourceNotFoundError
from azure.core.tracing.decorator import distributed_trace
from azure.core.tracing.decorator_async import distributed_trace_async
from azure.core.async_paging import AsyncItemPaged
@@ -335,6 +335,25 @@ async def get_container_properties(self, **kwargs):
response.name = self.container_name
return response # type: ignore
+ @distributed_trace_async
+ async def exists(self, **kwargs):
+ # type: (**Any) -> bool
+ """
+ Returns True if a container exists and returns False otherwise.
+
+ :kwarg int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: boolean
+ """
+ try:
+ await self._client.container.get_properties(**kwargs)
+ return True
+ except HttpResponseError as error:
+ try:
+ process_storage_error(error)
+ except ResourceNotFoundError:
+ return False
+
@distributed_trace_async
async def set_container_metadata( # type: ignore
self, metadata=None, # type: Optional[Dict[str, str]]
diff --git a/sdk/storage/azure-storage-blob/tests/recordings/test_container.test_container_exists.yaml b/sdk/storage/azure-storage-blob/tests/recordings/test_container.test_container_exists.yaml
new file mode 100644
index 000000000000..29f7ea651b2d
--- /dev/null
+++ b/sdk/storage/azure-storage-blob/tests/recordings/test_container.test_container_exists.yaml
@@ -0,0 +1,130 @@
+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.7.2 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Sun, 24 Jan 2021 23:07:30 GMT
+ x-ms-version:
+ - '2020-04-08'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/container112fe0ef2?restype=container
+ response:
+ body:
+ string: "\uFEFFContainerAlreadyExistsThe
+ specified container already exists.\nRequestId:34e48888-401e-009f-08a5-f21ff6000000\nTime:2021-01-24T23:07:30.9942715Z"
+ headers:
+ content-length:
+ - '230'
+ content-type:
+ - application/xml
+ date:
+ - Sun, 24 Jan 2021 23:07:30 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-error-code:
+ - ContainerAlreadyExists
+ x-ms-version:
+ - '2020-04-08'
+ status:
+ code: 409
+ message: The specified container already exists.
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ User-Agent:
+ - azsdk-python-storage-blob/12.7.2 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Sun, 24 Jan 2021 23:07:31 GMT
+ x-ms-version:
+ - '2020-04-08'
+ method: GET
+ uri: https://storagename.blob.core.windows.net/container112fe0ef2?restype=container
+ response:
+ body:
+ string: ''
+ headers:
+ content-length:
+ - '0'
+ date:
+ - Sun, 24 Jan 2021 23:07:31 GMT
+ etag:
+ - '"0x8D8C0BA190EF0A2"'
+ last-modified:
+ - Sun, 24 Jan 2021 22:47:58 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ vary:
+ - Origin
+ x-ms-default-encryption-scope:
+ - $account-encryption-key
+ x-ms-deny-encryption-scope-override:
+ - 'false'
+ x-ms-has-immutability-policy:
+ - 'false'
+ x-ms-has-legal-hold:
+ - 'false'
+ x-ms-lease-state:
+ - available
+ x-ms-lease-status:
+ - unlocked
+ x-ms-version:
+ - '2020-04-08'
+ status:
+ code: 200
+ message: OK
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ User-Agent:
+ - azsdk-python-storage-blob/12.7.2 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Sun, 24 Jan 2021 23:07:31 GMT
+ x-ms-version:
+ - '2020-04-08'
+ method: GET
+ uri: https://storagename.blob.core.windows.net/container212fe0ef2?restype=container
+ response:
+ body:
+ string: "\uFEFFContainerNotFoundThe
+ specified container does not exist.\nRequestId:34e488e9-401e-009f-63a5-f21ff6000000\nTime:2021-01-24T23:07:31.1273672Z"
+ headers:
+ content-length:
+ - '225'
+ content-type:
+ - application/xml
+ date:
+ - Sun, 24 Jan 2021 23:07:31 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ vary:
+ - Origin
+ x-ms-error-code:
+ - ContainerNotFound
+ x-ms-version:
+ - '2020-04-08'
+ status:
+ code: 404
+ message: The specified container does not exist.
+version: 1
diff --git a/sdk/storage/azure-storage-blob/tests/recordings/test_container_async.test_container_exists.yaml b/sdk/storage/azure-storage-blob/tests/recordings/test_container_async.test_container_exists.yaml
new file mode 100644
index 000000000000..a4d34236af68
--- /dev/null
+++ b/sdk/storage/azure-storage-blob/tests/recordings/test_container_async.test_container_exists.yaml
@@ -0,0 +1,92 @@
+interactions:
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-blob/12.7.2 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Sun, 24 Jan 2021 23:08:38 GMT
+ x-ms-version:
+ - '2020-04-08'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/container175a3116f?restype=container
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '0'
+ date: Sun, 24 Jan 2021 23:08:37 GMT
+ etag: '"0x8D8C0BCFBA744BA"'
+ last-modified: Sun, 24 Jan 2021 23:08:38 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-version: '2020-04-08'
+ status:
+ code: 201
+ message: Created
+ url: https://emilydevtest.blob.core.windows.net/container175a3116f?restype=container
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-blob/12.7.2 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Sun, 24 Jan 2021 23:08:38 GMT
+ x-ms-version:
+ - '2020-04-08'
+ method: GET
+ uri: https://storagename.blob.core.windows.net/container175a3116f?restype=container
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '0'
+ date: Sun, 24 Jan 2021 23:08:37 GMT
+ etag: '"0x8D8C0BCFBA744BA"'
+ last-modified: Sun, 24 Jan 2021 23:08:38 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ vary: Origin
+ x-ms-default-encryption-scope: $account-encryption-key
+ x-ms-deny-encryption-scope-override: 'false'
+ x-ms-has-immutability-policy: 'false'
+ x-ms-has-legal-hold: 'false'
+ x-ms-lease-state: available
+ x-ms-lease-status: unlocked
+ x-ms-version: '2020-04-08'
+ status:
+ code: 200
+ message: OK
+ url: https://emilydevtest.blob.core.windows.net/container175a3116f?restype=container
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-blob/12.7.2 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Sun, 24 Jan 2021 23:08:38 GMT
+ x-ms-version:
+ - '2020-04-08'
+ method: GET
+ uri: https://storagename.blob.core.windows.net/container275a3116f?restype=container
+ response:
+ body:
+ string: "\uFEFFContainerNotFoundThe
+ specified container does not exist.\nRequestId:f0e7bd23-001e-00b1-54a5-f24de1000000\nTime:2021-01-24T23:08:38.1833494Z"
+ headers:
+ content-length: '225'
+ content-type: application/xml
+ date: Sun, 24 Jan 2021 23:08:37 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ vary: Origin
+ x-ms-error-code: ContainerNotFound
+ x-ms-version: '2020-04-08'
+ status:
+ code: 404
+ message: The specified container does not exist.
+ url: https://emilydevtest.blob.core.windows.net/container275a3116f?restype=container
+version: 1
diff --git a/sdk/storage/azure-storage-blob/tests/test_container.py b/sdk/storage/azure-storage-blob/tests/test_container.py
index ff2c33347c96..9649c8dab266 100644
--- a/sdk/storage/azure-storage-blob/tests/test_container.py
+++ b/sdk/storage/azure-storage-blob/tests/test_container.py
@@ -311,6 +311,17 @@ def test_get_container_metadata_with_lease_id(self, resource_group, location, st
# Assert
self.assertDictEqual(md, metadata)
+ @GlobalStorageAccountPreparer()
+ def test_container_exists(self, resource_group, location, storage_account, storage_account_key):
+ bsc = BlobServiceClient(self.account_url(storage_account, "blob"), storage_account_key)
+
+ container1 = self._create_container(bsc, prefix="container1")
+ container2_name = self._get_container_reference(prefix="container2")
+ container2 = bsc.get_container_client(container2_name)
+
+ self.assertTrue(container1.exists())
+ self.assertFalse(container2.exists())
+
@GlobalStorageAccountPreparer()
def test_get_container_properties(self, resource_group, location, storage_account, storage_account_key):
bsc = BlobServiceClient(self.account_url(storage_account, "blob"), storage_account_key)
diff --git a/sdk/storage/azure-storage-blob/tests/test_container_async.py b/sdk/storage/azure-storage-blob/tests/test_container_async.py
index 9c280615e91f..2bcfb32da4b5 100644
--- a/sdk/storage/azure-storage-blob/tests/test_container_async.py
+++ b/sdk/storage/azure-storage-blob/tests/test_container_async.py
@@ -379,10 +379,24 @@ async def test_get_container_metadata_with_lease_id(self, resource_group, locati
# Assert
self.assertDictEqual(md, metadata)
+ @GlobalStorageAccountPreparer()
+ @AsyncStorageTestCase.await_prepared_test
+ async def test_container_exists(self, resource_group, location, storage_account, storage_account_key):
+ bsc = BlobServiceClient(self.account_url(
+ storage_account, "blob"), storage_account_key, transport=AiohttpTestTransport())
+
+ container1 = await self._create_container(bsc, prefix="container1")
+ container2_name = self._get_container_reference(prefix="container2")
+ container2 = bsc.get_container_client(container2_name)
+
+ self.assertTrue(await container1.exists())
+ self.assertFalse(await container2.exists())
+
@GlobalStorageAccountPreparer()
@AsyncStorageTestCase.await_prepared_test
async def test_get_container_properties(self, resource_group, location, storage_account, storage_account_key):
- bsc = BlobServiceClient(self.account_url(storage_account, "blob"), storage_account_key, transport=AiohttpTestTransport())
+ bsc = BlobServiceClient(
+ self.account_url(storage_account, "blob"), storage_account_key, transport=AiohttpTestTransport())
metadata = {'hello': 'world', 'number': '42'}
container = await self._create_container(bsc)
await container.set_container_metadata(metadata)