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 d2caf7a5a8e5..b1a8a21946d4 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
@@ -743,7 +743,8 @@ def list_blobs(self, name_starts_with=None, include=None, **kwargs):
begin with the specified prefix.
:param list[str] or str include:
Specifies one or more additional datasets to include in the response.
- Options include: 'snapshots', 'metadata', 'uncommittedblobs', 'copy', 'deleted', 'tags'.
+ Options include: 'snapshots', 'metadata', 'uncommittedblobs', 'copy', 'deleted', 'deletedwithversions',
+ 'tags', 'versions'.
:keyword int timeout:
The timeout parameter is expressed in seconds.
:returns: An iterable (auto-paging) response of BlobProperties.
diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_deserialize.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_deserialize.py
index dff39536572d..e54cccc57bcc 100644
--- a/sdk/storage/azure-storage-blob/azure/storage/blob/_deserialize.py
+++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_deserialize.py
@@ -153,6 +153,7 @@ def get_blob_properties_from_generated_code(generated):
blob.tags = parse_tags(generated.blob_tags) # pylint: disable=protected-access
blob.object_replication_source_properties = deserialize_ors_policies(generated.object_replication_metadata)
blob.last_accessed_on = generated.properties.last_accessed_on
+ blob.has_versions_only = generated.has_versions_only
return blob
diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_generated/models/_models.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_generated/models/_models.py
index 8e2e604c746f..7c4362edf615 100644
--- a/sdk/storage/azure-storage-blob/azure/storage/blob/_generated/models/_models.py
+++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_generated/models/_models.py
@@ -280,6 +280,7 @@ class BlobItemInternal(msrest.serialization.Model):
'metadata': {'key': 'Metadata', 'type': 'BlobMetadata'},
'blob_tags': {'key': 'BlobTags', 'type': 'BlobTags'},
'object_replication_metadata': {'key': 'OrMetadata', 'type': '{str}'},
+ 'has_versions_only': {'key': 'HasVersionsOnly', 'type': 'bool'},
}
_xml_map = {
'name': 'Blob'
diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_generated/models/_models_py3.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_generated/models/_models_py3.py
index d10ef443f76c..50d17842a1f4 100644
--- a/sdk/storage/azure-storage-blob/azure/storage/blob/_generated/models/_models_py3.py
+++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_generated/models/_models_py3.py
@@ -311,6 +311,7 @@ class BlobItemInternal(msrest.serialization.Model):
'metadata': {'key': 'Metadata', 'type': 'BlobMetadata'},
'blob_tags': {'key': 'BlobTags', 'type': 'BlobTags'},
'object_replication_metadata': {'key': 'OrMetadata', 'type': '{str}'},
+ 'has_versions_only': {'key': 'HasVersionsOnly', 'type': 'bool'},
}
_xml_map = {
'name': 'Blob'
diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_models.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_models.py
index 1ddde2e46c5c..3529850cbd3d 100644
--- a/sdk/storage/azure-storage-blob/azure/storage/blob/_models.py
+++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_models.py
@@ -519,6 +519,10 @@ class BlobProperties(DictMixin):
Key value pair of tags on this blob.
.. versionadded:: 12.4.0
+ :ivar bool has_versions_only:
+ A true value indicates the root blob is deleted
+
+ .. versionadded:: 12.10.0
"""
@@ -559,6 +563,7 @@ def __init__(self, **kwargs):
self.last_accessed_on = kwargs.get('x-ms-last-access-time')
self.tag_count = kwargs.get('x-ms-tag-count')
self.tags = None
+ self.has_versions_only = None
class FilteredBlob(DictMixin):
diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_serialize.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_serialize.py
index 8f6f265dce52..4eb3fb4ecfa0 100644
--- a/sdk/storage/azure-storage-blob/azure/storage/blob/_serialize.py
+++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_serialize.py
@@ -38,7 +38,8 @@
'2020-02-10',
'2020-04-08',
'2020-06-12',
- '2020-08-04'
+ '2020-08-04',
+ '2020-10-02'
]
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 93cc87748e34..3efaa0dcb0d1 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
@@ -605,7 +605,8 @@ def list_blobs(self, name_starts_with=None, include=None, **kwargs):
begin with the specified prefix.
:param list[str] or str include:
Specifies one or more additional datasets to include in the response.
- Options include: 'snapshots', 'metadata', 'uncommittedblobs', 'copy', 'deleted', 'tags'.
+ Options include: 'snapshots', 'metadata', 'uncommittedblobs', 'copy', 'deleted', 'deletedwithversions',
+ 'tags', 'versions'.
:keyword int timeout:
The timeout parameter is expressed in seconds.
:returns: An iterable (auto-paging) response of BlobProperties.
diff --git a/sdk/storage/azure-storage-blob/tests/recordings/test_container.test_list_blobs_include_deletedwithversion.yaml b/sdk/storage/azure-storage-blob/tests/recordings/test_container.test_list_blobs_include_deletedwithversion.yaml
new file mode 100644
index 000000000000..e31a7fbfdd84
--- /dev/null
+++ b/sdk/storage/azure-storage-blob/tests/recordings/test_container.test_list_blobs_include_deletedwithversion.yaml
@@ -0,0 +1,524 @@
+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.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:33 GMT
+ x-ms-version:
+ - '2020-10-02'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/containera8e61798?restype=container
+ response:
+ body:
+ string: "\uFEFFContainerAlreadyExistsThe
+ specified container already exists.\nRequestId:8202fa90-c01e-0059-1ed7-585d41000000\nTime:2021-06-04T00:22:34.3511114Z"
+ headers:
+ content-length:
+ - '230'
+ content-type:
+ - application/xml
+ date:
+ - Fri, 04 Jun 2021 00:22:33 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-error-code:
+ - ContainerAlreadyExists
+ x-ms-version:
+ - '2020-10-02'
+ status:
+ code: 409
+ message: The specified container already exists.
+- request:
+ body: hello world
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ Content-Length:
+ - '11'
+ Content-Type:
+ - application/octet-stream
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-blob-content-disposition:
+ - inline
+ x-ms-blob-content-language:
+ - spanish
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:34 GMT
+ x-ms-meta-name:
+ - bob
+ x-ms-meta-number:
+ - '1'
+ x-ms-version:
+ - '2020-10-02'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/containera8e61798/blob1
+ response:
+ body:
+ string: ''
+ headers:
+ content-length:
+ - '0'
+ content-md5:
+ - XrY7u+Ae7tCTyyK7j1rNww==
+ date:
+ - Fri, 04 Jun 2021 00:22:34 GMT
+ etag:
+ - '"0x8D926EED9C8EF9A"'
+ last-modified:
+ - Fri, 04 Jun 2021 00:22:34 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-content-crc64:
+ - vo7q9sPVKY0=
+ x-ms-request-server-encrypted:
+ - 'true'
+ x-ms-version:
+ - '2020-10-02'
+ x-ms-version-id:
+ - '2021-06-04T00:22:34.7532186Z'
+ status:
+ code: 201
+ message: Created
+- request:
+ body: abc
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ Content-Length:
+ - '3'
+ Content-Type:
+ - application/octet-stream
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:34 GMT
+ x-ms-version:
+ - '2020-10-02'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/containera8e61798/blob1
+ response:
+ body:
+ string: ''
+ headers:
+ content-length:
+ - '0'
+ content-md5:
+ - kAFQmDzST7DWlj99KOF/cg==
+ date:
+ - Fri, 04 Jun 2021 00:22:34 GMT
+ etag:
+ - '"0x8D926EED9DC2CFA"'
+ last-modified:
+ - Fri, 04 Jun 2021 00:22:34 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-content-crc64:
+ - 6/rBP7vK5QU=
+ x-ms-request-server-encrypted:
+ - 'true'
+ x-ms-version:
+ - '2020-10-02'
+ x-ms-version-id:
+ - '2021-06-04T00:22:34.8803082Z'
+ status:
+ code: 201
+ message: Created
+- request:
+ body: cde
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ Content-Length:
+ - '3'
+ Content-Type:
+ - application/octet-stream
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:34 GMT
+ x-ms-version:
+ - '2020-10-02'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/containera8e61798/blob1
+ response:
+ body:
+ string: ''
+ headers:
+ content-length:
+ - '0'
+ content-md5:
+ - olbmszav3DjFZHicOZtRbA==
+ date:
+ - Fri, 04 Jun 2021 00:22:34 GMT
+ etag:
+ - '"0x8D926EED9EF6A5B"'
+ last-modified:
+ - Fri, 04 Jun 2021 00:22:35 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-content-crc64:
+ - SsrIw8/pA7Y=
+ x-ms-request-server-encrypted:
+ - 'true'
+ x-ms-version:
+ - '2020-10-02'
+ x-ms-version-id:
+ - '2021-06-04T00:22:35.0063979Z'
+ status:
+ code: 201
+ message: Created
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ Content-Length:
+ - '0'
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:35 GMT
+ x-ms-version:
+ - '2020-10-02'
+ method: DELETE
+ uri: https://storagename.blob.core.windows.net/containera8e61798/blob1
+ response:
+ body:
+ string: ''
+ headers:
+ content-length:
+ - '0'
+ date:
+ - Fri, 04 Jun 2021 00:22:34 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-delete-type-permanent:
+ - 'false'
+ x-ms-version:
+ - '2020-10-02'
+ status:
+ code: 202
+ message: Accepted
+- request:
+ body: hello world
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ Content-Length:
+ - '11'
+ Content-Type:
+ - application/octet-stream
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-blob-content-disposition:
+ - inline
+ x-ms-blob-content-language:
+ - spanish
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:35 GMT
+ x-ms-meta-name:
+ - car
+ x-ms-meta-number:
+ - '2'
+ x-ms-version:
+ - '2020-10-02'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/containera8e61798/blob2
+ response:
+ body:
+ string: ''
+ headers:
+ content-length:
+ - '0'
+ content-md5:
+ - XrY7u+Ae7tCTyyK7j1rNww==
+ date:
+ - Fri, 04 Jun 2021 00:22:34 GMT
+ etag:
+ - '"0x8D926EEDA1BD9AA"'
+ last-modified:
+ - Fri, 04 Jun 2021 00:22:35 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-content-crc64:
+ - vo7q9sPVKY0=
+ x-ms-request-server-encrypted:
+ - 'true'
+ x-ms-version:
+ - '2020-10-02'
+ x-ms-version-id:
+ - '2021-06-04T00:22:35.2976058Z'
+ status:
+ code: 201
+ message: Created
+- request:
+ body: hello world
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ Content-Length:
+ - '11'
+ Content-Type:
+ - application/octet-stream
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-blob-content-disposition:
+ - inline
+ x-ms-blob-content-language:
+ - spanish
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:35 GMT
+ x-ms-meta-name:
+ - car
+ x-ms-meta-number:
+ - '2'
+ x-ms-version:
+ - '2020-10-02'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/containera8e61798/blob3
+ response:
+ body:
+ string: ''
+ headers:
+ content-length:
+ - '0'
+ content-md5:
+ - XrY7u+Ae7tCTyyK7j1rNww==
+ date:
+ - Fri, 04 Jun 2021 00:22:34 GMT
+ etag:
+ - '"0x8D926EEDA34BD55"'
+ last-modified:
+ - Fri, 04 Jun 2021 00:22:35 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-content-crc64:
+ - vo7q9sPVKY0=
+ x-ms-request-server-encrypted:
+ - 'true'
+ x-ms-version:
+ - '2020-10-02'
+ x-ms-version-id:
+ - '2021-06-04T00:22:35.4607205Z'
+ status:
+ code: 201
+ message: Created
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:35 GMT
+ x-ms-version:
+ - '2020-10-02'
+ method: GET
+ uri: https://storagename.blob.core.windows.net/containera8e61798?restype=container&comp=list&include=deletedwithversions
+ response:
+ body:
+ string: "\uFEFFblob1trueFri,
+ 04 Jun 2021 00:22:35 GMTFri, 04 Jun 2021 00:22:35
+ GMT0x8D926EED9EF6A5B0application/octet-streamolbmszav3DjFZHicOZtRbA==Fri, 04 Jun 2021 00:22:35 GMTBlockBlobHottrueunlockedavailabletrueblob22021-06-04T00:22:35.2976058ZtrueFri,
+ 04 Jun 2021 00:22:35 GMTFri, 04 Jun 2021 00:22:35
+ GMT0x8D926EEDA1BD9AA11application/octet-streamspanishXrY7u+Ae7tCTyyK7j1rNww==inlineFri, 04
+ Jun 2021 00:22:35 GMTBlockBlobHottrueunlockedavailabletrueblob32021-06-04T00:22:35.4607205ZtrueFri,
+ 04 Jun 2021 00:22:35 GMTFri, 04 Jun 2021 00:22:35
+ GMT0x8D926EEDA34BD5511application/octet-streamspanishXrY7u+Ae7tCTyyK7j1rNww==inlineFri, 04
+ Jun 2021 00:22:35 GMTBlockBlobHottrueunlockedavailabletrueblob6trueFri,
+ 04 Jun 2021 00:03:14 GMTFri, 04 Jun 2021 00:03:14
+ GMT0x8D926EC2628399C0application/octet-streamolbmszav3DjFZHicOZtRbA==Fri, 04 Jun 2021 00:03:14 GMTBlockBlobHottrueunlockedavailabletrue"
+ headers:
+ content-type:
+ - application/xml
+ date:
+ - Fri, 04 Jun 2021 00:22:34 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ transfer-encoding:
+ - chunked
+ x-ms-version:
+ - '2020-10-02'
+ 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.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:35 GMT
+ x-ms-range:
+ - bytes=0-33554431
+ x-ms-version:
+ - '2020-10-02'
+ method: GET
+ uri: https://storagename.blob.core.windows.net/containera8e61798/blob1?versionid=2021-06-04T00%3A22%3A35.0063979Z
+ response:
+ body:
+ string: cde
+ headers:
+ accept-ranges:
+ - bytes
+ content-length:
+ - '3'
+ content-range:
+ - bytes 0-2/3
+ content-type:
+ - application/octet-stream
+ date:
+ - Fri, 04 Jun 2021 00:22:35 GMT
+ etag:
+ - '"0x8D926EED9EF6A5B"'
+ last-modified:
+ - Fri, 04 Jun 2021 00:22:35 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-blob-content-md5:
+ - olbmszav3DjFZHicOZtRbA==
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-creation-time:
+ - Fri, 04 Jun 2021 00:22:35 GMT
+ x-ms-server-encrypted:
+ - 'true'
+ x-ms-version:
+ - '2020-10-02'
+ x-ms-version-id:
+ - '2021-06-04T00:22:35.0063979Z'
+ status:
+ code: 206
+ message: Partial Content
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:35 GMT
+ x-ms-range:
+ - bytes=0-33554431
+ x-ms-version:
+ - '2020-10-02'
+ method: GET
+ uri: https://storagename.blob.core.windows.net/containera8e61798/blob1?versionid=2021-06-04T00%3A22%3A34.7532186Z
+ response:
+ body:
+ string: hello world
+ headers:
+ accept-ranges:
+ - bytes
+ content-disposition:
+ - inline
+ content-language:
+ - spanish
+ content-length:
+ - '11'
+ content-range:
+ - bytes 0-10/11
+ content-type:
+ - application/octet-stream
+ date:
+ - Fri, 04 Jun 2021 00:22:35 GMT
+ etag:
+ - '"0x8D926EED9C8EF9A"'
+ last-modified:
+ - Fri, 04 Jun 2021 00:22:34 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-blob-content-md5:
+ - XrY7u+Ae7tCTyyK7j1rNww==
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-creation-time:
+ - Fri, 04 Jun 2021 00:22:34 GMT
+ x-ms-meta-name:
+ - bob
+ x-ms-meta-number:
+ - '1'
+ x-ms-server-encrypted:
+ - 'true'
+ x-ms-version:
+ - '2020-10-02'
+ x-ms-version-id:
+ - '2021-06-04T00:22:34.7532186Z'
+ status:
+ code: 206
+ message: Partial Content
+version: 1
diff --git a/sdk/storage/azure-storage-blob/tests/recordings/test_container_async.test_list_blobs_include_deletedwithversion_async.yaml b/sdk/storage/azure-storage-blob/tests/recordings/test_container_async.test_list_blobs_include_deletedwithversion_async.yaml
new file mode 100644
index 000000000000..d70b34396475
--- /dev/null
+++ b/sdk/storage/azure-storage-blob/tests/recordings/test_container_async.test_list_blobs_include_deletedwithversion_async.yaml
@@ -0,0 +1,387 @@
+interactions:
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:45 GMT
+ x-ms-version:
+ - '2020-10-02'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/acontainere4ee1c92?restype=container
+ response:
+ body:
+ string: "\uFEFFContainerAlreadyExistsThe
+ specified container already exists.\nRequestId:7bc8288b-b01e-0031-13d7-583bd1000000\nTime:2021-06-04T00:22:45.4807498Z"
+ headers:
+ content-length: '230'
+ content-type: application/xml
+ date: Fri, 04 Jun 2021 00:22:44 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-error-code: ContainerAlreadyExists
+ x-ms-version: '2020-10-02'
+ status:
+ code: 409
+ message: The specified container already exists.
+ url: https://seanmcccanary3.blob.core.windows.net/acontainere4ee1c92?restype=container
+- request:
+ body: hello world
+ headers:
+ Accept:
+ - application/xml
+ Content-Length:
+ - '11'
+ Content-Type:
+ - application/octet-stream
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-blob-content-disposition:
+ - inline
+ x-ms-blob-content-language:
+ - spanish
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:45 GMT
+ x-ms-meta-name:
+ - bob
+ x-ms-meta-number:
+ - '1'
+ x-ms-version:
+ - '2020-10-02'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/acontainere4ee1c92/blob1
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '0'
+ content-md5: XrY7u+Ae7tCTyyK7j1rNww==
+ date: Fri, 04 Jun 2021 00:22:44 GMT
+ etag: '"0x8D926EEE0381268"'
+ last-modified: Fri, 04 Jun 2021 00:22:45 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-content-crc64: vo7q9sPVKY0=
+ x-ms-request-server-encrypted: 'true'
+ x-ms-version: '2020-10-02'
+ x-ms-version-id: '2021-06-04T00:22:45.5478888Z'
+ status:
+ code: 201
+ message: Created
+ url: https://seanmcccanary3.blob.core.windows.net/acontainere4ee1c92/blob1
+- request:
+ body: abc
+ headers:
+ Accept:
+ - application/xml
+ Content-Length:
+ - '3'
+ Content-Type:
+ - application/octet-stream
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:45 GMT
+ x-ms-version:
+ - '2020-10-02'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/acontainere4ee1c92/blob1
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '0'
+ content-md5: kAFQmDzST7DWlj99KOF/cg==
+ date: Fri, 04 Jun 2021 00:22:44 GMT
+ etag: '"0x8D926EEE04162EA"'
+ last-modified: Fri, 04 Jun 2021 00:22:45 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-content-crc64: 6/rBP7vK5QU=
+ x-ms-request-server-encrypted: 'true'
+ x-ms-version: '2020-10-02'
+ x-ms-version-id: '2021-06-04T00:22:45.6099322Z'
+ status:
+ code: 201
+ message: Created
+ url: https://seanmcccanary3.blob.core.windows.net/acontainere4ee1c92/blob1
+- request:
+ body: cde
+ headers:
+ Accept:
+ - application/xml
+ Content-Length:
+ - '3'
+ Content-Type:
+ - application/octet-stream
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:45 GMT
+ x-ms-version:
+ - '2020-10-02'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/acontainere4ee1c92/blob1
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '0'
+ content-md5: olbmszav3DjFZHicOZtRbA==
+ date: Fri, 04 Jun 2021 00:22:44 GMT
+ etag: '"0x8D926EEE04B019A"'
+ last-modified: Fri, 04 Jun 2021 00:22:45 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-content-crc64: SsrIw8/pA7Y=
+ x-ms-request-server-encrypted: 'true'
+ x-ms-version: '2020-10-02'
+ x-ms-version-id: '2021-06-04T00:22:45.6729770Z'
+ status:
+ code: 201
+ message: Created
+ url: https://seanmcccanary3.blob.core.windows.net/acontainere4ee1c92/blob1
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:45 GMT
+ x-ms-version:
+ - '2020-10-02'
+ method: DELETE
+ uri: https://storagename.blob.core.windows.net/acontainere4ee1c92/blob1
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '0'
+ date: Fri, 04 Jun 2021 00:22:44 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-delete-type-permanent: 'false'
+ x-ms-version: '2020-10-02'
+ status:
+ code: 202
+ message: Accepted
+ url: https://seanmcccanary3.blob.core.windows.net/acontainere4ee1c92/blob1
+- request:
+ body: hello world
+ headers:
+ Accept:
+ - application/xml
+ Content-Length:
+ - '11'
+ Content-Type:
+ - application/octet-stream
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-blob-content-disposition:
+ - inline
+ x-ms-blob-content-language:
+ - spanish
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:45 GMT
+ x-ms-meta-name:
+ - car
+ x-ms-meta-number:
+ - '2'
+ x-ms-version:
+ - '2020-10-02'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/acontainere4ee1c92/blob2
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '0'
+ content-md5: XrY7u+Ae7tCTyyK7j1rNww==
+ date: Fri, 04 Jun 2021 00:22:45 GMT
+ etag: '"0x8D926EEE0625E6F"'
+ last-modified: Fri, 04 Jun 2021 00:22:45 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-content-crc64: vo7q9sPVKY0=
+ x-ms-request-server-encrypted: 'true'
+ x-ms-version: '2020-10-02'
+ x-ms-version-id: '2021-06-04T00:22:45.8260863Z'
+ status:
+ code: 201
+ message: Created
+ url: https://seanmcccanary3.blob.core.windows.net/acontainere4ee1c92/blob2
+- request:
+ body: hello world
+ headers:
+ Accept:
+ - application/xml
+ Content-Length:
+ - '11'
+ Content-Type:
+ - application/octet-stream
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-blob-content-disposition:
+ - inline
+ x-ms-blob-content-language:
+ - spanish
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:45 GMT
+ x-ms-meta-name:
+ - car
+ x-ms-meta-number:
+ - '2'
+ x-ms-version:
+ - '2020-10-02'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/acontainere4ee1c92/blob3
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '0'
+ content-md5: XrY7u+Ae7tCTyyK7j1rNww==
+ date: Fri, 04 Jun 2021 00:22:45 GMT
+ etag: '"0x8D926EEE06B128C"'
+ last-modified: Fri, 04 Jun 2021 00:22:45 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-content-crc64: vo7q9sPVKY0=
+ x-ms-request-server-encrypted: 'true'
+ x-ms-version: '2020-10-02'
+ x-ms-version-id: '2021-06-04T00:22:45.8841272Z'
+ status:
+ code: 201
+ message: Created
+ url: https://seanmcccanary3.blob.core.windows.net/acontainere4ee1c92/blob3
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:45 GMT
+ x-ms-version:
+ - '2020-10-02'
+ method: GET
+ uri: https://storagename.blob.core.windows.net/acontainere4ee1c92?restype=container&comp=list&include=deletedwithversions
+ response:
+ body:
+ string: "\uFEFFblob1trueFri,
+ 04 Jun 2021 00:22:45 GMTFri, 04 Jun 2021 00:22:45
+ GMT0x8D926EEE04B019A0application/octet-streamolbmszav3DjFZHicOZtRbA==Fri, 04 Jun 2021 00:22:45 GMTBlockBlobHottrueunlockedavailabletrueblob22021-06-04T00:22:45.8260863ZtrueFri,
+ 04 Jun 2021 00:22:45 GMTFri, 04 Jun 2021 00:22:45
+ GMT0x8D926EEE0625E6F11application/octet-streamspanishXrY7u+Ae7tCTyyK7j1rNww==inlineFri, 04
+ Jun 2021 00:22:45 GMTBlockBlobHottrueunlockedavailabletrueblob32021-06-04T00:22:45.8841272ZtrueFri,
+ 04 Jun 2021 00:22:45 GMTFri, 04 Jun 2021 00:22:45
+ GMT0x8D926EEE06B128C11application/octet-streamspanishXrY7u+Ae7tCTyyK7j1rNww==inlineFri, 04
+ Jun 2021 00:22:45 GMTBlockBlobHottrueunlockedavailabletrue"
+ headers:
+ content-type: application/xml
+ date: Fri, 04 Jun 2021 00:22:45 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ transfer-encoding: chunked
+ x-ms-version: '2020-10-02'
+ status:
+ code: 200
+ message: OK
+ url: https://seanmcccanary3.blob.core.windows.net/acontainere4ee1c92?restype=container&comp=list&include=deletedwithversions
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:46 GMT
+ x-ms-range:
+ - bytes=0-33554431
+ x-ms-version:
+ - '2020-10-02'
+ method: GET
+ uri: https://storagename.blob.core.windows.net/acontainere4ee1c92/blob1?versionid=2021-06-04T00:22:45.6729770Z
+ response:
+ body:
+ string: cde
+ headers:
+ accept-ranges: bytes
+ content-length: '3'
+ content-range: bytes 0-2/3
+ content-type: application/octet-stream
+ date: Fri, 04 Jun 2021 00:22:45 GMT
+ etag: '"0x8D926EEE04B019A"'
+ last-modified: Fri, 04 Jun 2021 00:22:45 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-blob-content-md5: olbmszav3DjFZHicOZtRbA==
+ x-ms-blob-type: BlockBlob
+ x-ms-creation-time: Fri, 04 Jun 2021 00:22:45 GMT
+ x-ms-server-encrypted: 'true'
+ x-ms-version: '2020-10-02'
+ x-ms-version-id: '2021-06-04T00:22:45.6729770Z'
+ status:
+ code: 206
+ message: Partial Content
+ url: https://seanmcccanary3.blob.core.windows.net/acontainere4ee1c92/blob1?versionid=2021-06-04T00:22:45.6729770Z
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-blob/12.9.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Fri, 04 Jun 2021 00:22:46 GMT
+ x-ms-range:
+ - bytes=0-33554431
+ x-ms-version:
+ - '2020-10-02'
+ method: GET
+ uri: https://storagename.blob.core.windows.net/acontainere4ee1c92/blob1?versionid=2021-06-04T00:22:45.5478888Z
+ response:
+ body:
+ string: hello world
+ headers:
+ accept-ranges: bytes
+ content-disposition: inline
+ content-language: spanish
+ content-length: '11'
+ content-range: bytes 0-10/11
+ content-type: application/octet-stream
+ date: Fri, 04 Jun 2021 00:22:45 GMT
+ etag: '"0x8D926EEE0381268"'
+ last-modified: Fri, 04 Jun 2021 00:22:45 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-blob-content-md5: XrY7u+Ae7tCTyyK7j1rNww==
+ x-ms-blob-type: BlockBlob
+ x-ms-creation-time: Fri, 04 Jun 2021 00:22:45 GMT
+ x-ms-meta-name: bob
+ x-ms-meta-number: '1'
+ x-ms-server-encrypted: 'true'
+ x-ms-version: '2020-10-02'
+ x-ms-version-id: '2021-06-04T00:22:45.5478888Z'
+ status:
+ code: 206
+ message: Partial Content
+ url: https://seanmcccanary3.blob.core.windows.net/acontainere4ee1c92/blob1?versionid=2021-06-04T00:22:45.5478888Z
+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 4608f7a7bc17..3aa4f6d99384 100644
--- a/sdk/storage/azure-storage-blob/tests/test_container.py
+++ b/sdk/storage/azure-storage-blob/tests/test_container.py
@@ -1083,6 +1083,41 @@ def test_list_blobs_with_include_metadata(self, resource_group, location, storag
self.assertEqual(blobs[1].content_settings.content_language, 'spanish')
self.assertEqual(blobs[1].content_settings.content_disposition, 'inline')
+ @GlobalStorageAccountPreparer()
+ def test_list_blobs_include_deletedwithversion(self, resource_group, location, storage_account, storage_account_key):
+ bsc = BlobServiceClient(self.account_url(storage_account, "blob"), storage_account_key)
+ # pytest.skip("Waiting on metadata XML fix in msrest")
+ container = self._create_container(bsc)
+ data = b'hello world'
+ content_settings = ContentSettings(
+ content_language='spanish',
+ content_disposition='inline')
+ blob1 = container.get_blob_client('blob1')
+ resp = blob1.upload_blob(data, overwrite=True, content_settings=content_settings, metadata={'number': '1', 'name': 'bob'})
+ version_id_1 = resp['version_id']
+ blob1.upload_blob(b"abc", overwrite=True)
+ root_content = b"cde"
+ root_version_id = blob1.upload_blob(root_content, overwrite=True)['version_id']
+ blob1.delete_blob()
+
+ container.get_blob_client('blob2').upload_blob(data, overwrite=True, content_settings=content_settings, metadata={'number': '2', 'name': 'car'})
+ container.get_blob_client('blob3').upload_blob(data, overwrite=True, content_settings=content_settings, metadata={'number': '2', 'name': 'car'})
+
+ # Act
+ blobs =list(container.list_blobs(include=["deletedwithversions"]))
+ downloaded_root_content = blob1.download_blob(version_id=root_version_id).readall()
+ downloaded_original_content = blob1.download_blob(version_id=version_id_1).readall()
+
+ # Assert
+ self.assertEqual(blobs[0].name, 'blob1')
+ self.assertTrue(blobs[0].has_versions_only)
+ self.assertEqual(root_content, downloaded_root_content)
+ self.assertEqual(data, downloaded_original_content)
+ self.assertEqual(blobs[1].name, 'blob2')
+ self.assertFalse(blobs[1].has_versions_only)
+ self.assertEqual(blobs[2].name, 'blob3')
+ self.assertFalse(blobs[2].has_versions_only)
+
@GlobalStorageAccountPreparer()
def test_list_blobs_with_include_uncommittedblobs(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 c6d60e99ddd9..5e71216390c3 100644
--- a/sdk/storage/azure-storage-blob/tests/test_container_async.py
+++ b/sdk/storage/azure-storage-blob/tests/test_container_async.py
@@ -1140,6 +1140,46 @@ async def test_list_blobs_with_include_metadata(self, resource_group, location,
self.assertEqual(blobs[1].metadata['number'], '2')
self.assertEqual(blobs[1].metadata['name'], 'car')
+ @GlobalStorageAccountPreparer()
+ async def test_list_blobs_include_deletedwithversion_async(self, resource_group, location, storage_account, storage_account_key):
+ bsc = BlobServiceClient(self.account_url(storage_account, "blob"), storage_account_key)
+ # pytest.skip("Waiting on metadata XML fix in msrest")
+ container = await self._create_container(bsc)
+ data = b'hello world'
+ content_settings = ContentSettings(
+ content_language='spanish',
+ content_disposition='inline')
+ blob1 = container.get_blob_client('blob1')
+ resp = await blob1.upload_blob(data, overwrite=True, content_settings=content_settings, metadata={'number': '1', 'name': 'bob'})
+ version_id_1 = resp['version_id']
+ await blob1.upload_blob(b"abc", overwrite=True)
+ root_content = b"cde"
+ root_version_id = (await blob1.upload_blob(root_content, overwrite=True))['version_id']
+ # this will delete the root blob, while you can still access it through versioning
+ await blob1.delete_blob()
+
+ await container.get_blob_client('blob2').upload_blob(data, overwrite=True, content_settings=content_settings, metadata={'number': '2', 'name': 'car'})
+ await container.get_blob_client('blob3').upload_blob(data, overwrite=True, content_settings=content_settings, metadata={'number': '2', 'name': 'car'})
+
+ # Act
+ blobs = list()
+
+ # include deletedwithversions will give you all alive root blobs and the the deleted root blobs when versioning is on.
+ async for blob in container.list_blobs(include=["deletedwithversions"]):
+ blobs.append(blob)
+ downloaded_root_content = await (await blob1.download_blob(version_id=root_version_id)).readall()
+ downloaded_original_content = await (await blob1.download_blob(version_id=version_id_1)).readall()
+
+ # Assert
+ self.assertEqual(blobs[0].name, 'blob1')
+ self.assertTrue(blobs[0].has_versions_only)
+ self.assertEqual(root_content, downloaded_root_content)
+ self.assertEqual(data, downloaded_original_content)
+ self.assertEqual(blobs[1].name, 'blob2')
+ self.assertFalse(blobs[1].has_versions_only)
+ self.assertEqual(blobs[2].name, 'blob3')
+ self.assertFalse(blobs[2].has_versions_only)
+
@GlobalStorageAccountPreparer()
@AsyncStorageTestCase.await_prepared_test
async def test_list_blobs_with_include_uncommittedblobs(self, resource_group, location, storage_account, storage_account_key):